ref: fd262ec2520b41e58a86866076e2509d26ba61bf
dir: /as/expr.c/
static char sccsid[] = "@(#) ./as/node.c"; #include <string.h> #include "../inc/scc.h" #include "as.h" #define NNODES 10 enum tokens { IDEN = 1, CHAR, STRING, SHL, SHR, GE, LT, }; static Alloc *arena; static int yytoken; static char *yytext; #define accept(t) (yytoken == (t) ? next() : 0) static Node * node(int op, Node *l, Node *r) { struct arena *ap; Node *np; if (!arena) arena = alloc(sizeof(Node), NNODES); np = memset(new(arena), 0, sizeof(*np)); np->op = op; return np; } static Node * binary(int op, Node *l, Node *r) { return node(op, l, r); } static Node * unary(int op, Node *np) { return node(op, np, NULL); } static int next(void) { return 0; } static void unexpected(void) { error("unexpected '%s'", yytext); } static void expect(int token) { if (yytoken != token) unexpected(); next(); } /*************************************************************************/ /* grammar functions */ /*************************************************************************/ static Node * primary(void) { Node *np; switch (yytoken) { case IDEN: case CHAR: case STRING: np = node(yytoken, NULL, NULL); next(); break; case '(': next(); np = expr(); expect(')'); break; default: unexpected(); return NULL; } return np; } static Node * mul(void) { int op; Node *np; np = primary(); for (;;) { switch (op = yytoken) { case '*': case '/': case '%': case SHL: case SHR: next(); binary(op, np, primary()); break; default: return np; } } } static Node * add(void) { int op; Node *np; np = mul(); for (;;) { switch (op = yytoken) { case '+': case '-': next(); np = binary(op, np, mul()); break; default: return np; } } } static Node * relational(void) { int op; Node *np; np = add(); for (;;) { switch (op = yytoken) { case '<': case '>': case '=': case GE: case LT: next(); np = binary(op, np, add()); break; default: return np; } } } static Node * not(void) { Node *np; np = relational(); while (accept('!')) np = unary('!', relational()); return np; } static Node * and(void) { int op; Node *np; np = not(); while (accept('&')) np = binary('&', np, not()); return np; } Node * expr(void) { int op; Node *np; np = and(); for (;;) { switch (op = yytoken) { case '|': case '^': next(); np = binary(op, np, and()); break; default: return np; } } }