static enum token t_lex(char *s) { int num; if (s == NULL) { return EOI; } num = find_op(s); if (((TOKEN_TYPE(num) == UNOP || TOKEN_TYPE(num) == BUNOP) && isunopoperand()) || (num == LPAREN && islparenoperand()) || (num == RPAREN && isrparenoperand())) return OPERAND; return num; }
static int primary(enum token n) { enum token nn; int res; if (n == EOI) return 0; /* missing expression */ if (n == LPAREN) { parenlevel++; if ((nn = t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL)) == RPAREN) { parenlevel--; return 0; /* missing expression */ } res = oexpr(nn); if (t_lex(nargc > 0 ? (--nargc, *++t_wp) : NULL) != RPAREN) syntax(NULL, "closing paren expected"); parenlevel--; return res; } if (TOKEN_TYPE(n) == UNOP) { /* unary expression */ if (--nargc == 0) syntax(NULL, "argument expected"); /* impossible */ switch (n) { case STREZ: return strlen(*++t_wp) == 0; case STRNZ: return strlen(*++t_wp) != 0; case FILTT: return isatty(getn(*++t_wp)); default: return filstat(*++t_wp, n); } } nn = t_lex(nargc > 0 ? t_wp[1] : NULL); if (TOKEN_TYPE(nn) == BINOP) return binop(nn); return strlen(*t_wp) > 0; }
static int islparenoperand(void) { char *s; int num; if (nargc == 1) return 1; s = *(t_wp + 1); if (nargc == 2) return parenlevel == 1 && strcmp(s, ")") == 0; if (nargc != 3) return 0; num = find_op(s); return TOKEN_TYPE(num) == BINOP; }
static int isunopoperand(void) { char *s; char *t; int num; if (nargc == 1) return 1; s = *(t_wp + 1); if (nargc == 2) return parenlevel == 1 && strcmp(s, ")") == 0; t = *(t_wp + 2); num = find_op(s); return TOKEN_TYPE(num) == BINOP && (parenlevel == 0 || t[0] != ')' || t[1] != '\0'); }
void CSGScanner :: ReadNext () { char ch; // scan whitespaces do { scanin->get(ch); //if (ch == '\n') // linenum++; // end of file reached if (scanin->eof()) { token = TOK_END; return; } if (ch == '\n') linenum++; // skip comment line if (ch == '#') { while (ch != '\n') { scanin->get(ch); if (scanin->eof()) { token = TOK_END; return; } } linenum++; } } while (isspace(ch)); switch (ch) { case '(': case ')': case '[': case ']': case '-': case '=': case ',': case ';': { token = TOKEN_TYPE (ch); break; } default: { if (isdigit (ch) || ch == '.') { scanin->putback (ch); (*scanin) >> num_value; token = TOK_NUM; return; } if (isalpha (ch)) { string_value = string (1, ch); scanin->get(ch); while (isalnum(ch) || ch == '_') { string_value += ch; scanin->get(ch); } scanin->putback (ch); } int nr = 0; while (defkw[nr].kw) { if (string_value == defkw[nr].name) { token = defkw[nr].kw; return; } nr++; } nr = 0; while (defprim[nr].kw) { if (string_value == defprim[nr].name) { token = TOK_PRIMITIVE; prim_token = defprim[nr].kw; return; } nr++; } token = TOK_STRING; } }