/* ** Constant capture */ static int lp_constcapture (lua_State *L) { int i; int n = lua_gettop(L); /* number of values */ if (n == 0) /* no values? */ newleaf(L, TTrue); /* no capture */ else if (n == 1) newemptycapkey(L, Cconst, 1); /* single constant capture */ else { /* create a group capture with all values */ TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); newktable(L, n); /* create a 'ktable' for new tree */ tree->tag = TCapture; tree->cap = Cgroup; tree->key = 0; tree = sib1(tree); for (i = 1; i <= n - 1; i++) { tree->tag = TSeq; tree->u.ps = 3; /* skip TCapture and its sibling */ auxemptycap(sib1(tree), Cconst); sib1(tree)->key = addtoktable(L, i); tree = sib2(tree); } auxemptycap(tree, Cconst); tree->key = addtoktable(L, i); } return 1; }
/* ** Convert value at index 'idx' to a pattern */ static TTree *getpatt (lua_State *L, int idx, int *len) { TTree *tree; switch (lua_type(L, idx)) { case LUA_TSTRING: { size_t slen; const char *s = lua_tolstring(L, idx, &slen); /* get string */ if (slen == 0) /* empty? */ tree = newleaf(L, TTrue); /* always match */ else { tree = newtree(L, 2 * (slen - 1) + 1); fillseq(tree, TChar, slen, s); /* sequence of 'slen' chars */ } break; } case LUA_TNUMBER: { int n = lua_tointeger(L, idx); tree = numtree(L, n); break; } case LUA_TBOOLEAN: { tree = (lua_toboolean(L, idx) ? newleaf(L, TTrue) : newleaf(L, TFalse)); break; } case LUA_TTABLE: { tree = newgrammar(L, idx); break; } case LUA_TFUNCTION: { tree = newtree(L, 2); tree->tag = TRunTime; tree->key = addtonewktable(L, 0, idx); sib1(tree)->tag = TTrue; break; } default: { return gettree(L, idx, len); } } lua_replace(L, idx); /* put new tree into 'idx' slot */ if (len) *len = getsize(L, idx); return tree; }
/* ** Numbers as patterns: ** 0 == true (always match); n == TAny repeated 'n' times; ** -n == not (TAny repeated 'n' times) */ static TTree *numtree (lua_State *L, int n) { if (n == 0) return newleaf(L, TTrue); else { TTree *tree, *nd; if (n > 0) tree = nd = newtree(L, 2 * n - 1); else { /* negative: code it as !(-n) */ n = -n; tree = newtree(L, 2 * n); tree->tag = TNot; nd = sib1(tree); } fillseq(nd, TAny, n, NULL); /* sequence of 'n' any's */ return tree; } }
/* ** Create a non-terminal */ static int lp_V (lua_State *L) { TTree *tree = newleaf(L, TOpenCall); luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); tree->key = addtonewktable(L, 0, 1); return 1; }
static EORB_CPP_node *read_expr_11 (void) { char c; #ifdef DEBUG_EXPR if (debugging) { outputs("~E11:"); } #endif while (1) { c = getnhsexpand(); if (c == '(') { EORB_CPP_node *n; #ifdef DEBUG_EXPR if (debugging) { outputs("()"); } #endif n = read_expr_(); c = getnhsexpand(); if (c != ')') { err_head(); fprintf(stderr, "expression syntax error -- missing ) supplied\n"); Push(c); } #ifdef DEBUG_EXPR if (debugging) { outputs("~"); } #endif return (n); } else if (isdigit((int) c)) { int base; static char digits[] = "0123456789abcdefABCDEF"; static char values[] = "\0\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\12\13\14\15\16\17"; char *d; int v; #ifdef DEBUG_EXPR if (debugging) { outputs("N"); } #endif base = 10; if (c == '0') { base = 8; c = Get(); if ((c == 'x') || (c == 'X')) { base = 16; c = Get(); } } v = 0; while (1) { d = strchr(digits, c); if (d == 0) { Push(c); #ifdef DEBUG_EXPR if (debugging) { outputd(v); outputs("~"); } #endif return (newleaf(v)); } else if (values[d -digits] >= base) { err_head(); fprintf(stderr, "warning: illegal %sdigit `%c'\n", (base == 16) ? "hex " : (base == 8) ? "octal " : "", c); } v = (v * base) + values[d - digits]; c = Get(); } } else if (c == '\'') { int i; int j; int n; i = 0; n = 0; while (1) { j = get_quote_char(); if (j < 0) { break; } i = (i << 8) | j; n ++; } if (n > 4) { err_head(); fprintf(stderr, "warning: too many characters in character constant\n"); } return (newleaf(i)); } else if ((c == '\n') && !sharp) {} else { char *id; if (complain) { err_head(); fprintf(stderr, "expression syntax error -- number expected\n"); } if (isbsymchar(c)) { Push(c); id = read_ident(); } else { id = 0; } #ifdef DEBUG_EXPR if (debugging) { outputs("0("); outputc(c); outputs(":"); outputs(id ? id : "(none)"); outputs(")~"); } #endif if (id) { os_free(id); } return (newleaf(0)); } } }