%{ #include "base.h" #define S(tok) #tok #include int yyerror(char *s); int yylex(void); Node * parse_tree; %} %token NUMBER IDENTIFIER %% /* Grammar rules and actions follow */ expr: expr '+' term | term ; term: term '*' factor | factor ; factor: '(' expr ')' | NUMBER | IDENTIFIER ; %% static void dump(Node * n, int level); int main (void) { /* yydebug = 1; */ yyparse(); dump(parse_tree, 0); return 0; } #include int yyerror(char *msg) /* Called by yyparse on error */ { extern char *yytext; extern int yylineno; fprintf(stderr, "%d: %s at '%s'\n", yylineno, msg, yytext); return 0; } static Node * newnode(char const * s) { Node * p = (Node *) malloc(sizeof(Node)); p->child = p->sibling = NULL; strcpy(p->name, s); return p; } #include Node * nn_nt(char const * name, ...) { Node * p = newnode(name); Node * t; va_list ap; va_start(ap, name); p->child = va_arg(ap, Node *); t = p->child; while ((t->sibling=va_arg(ap, Node *)) != NULL) t = t->sibling; va_end(ap); return p; } Node * nn_ch(char const c) { char s[2] = "a"; s[0] = c; return newnode(s); } Node * nn_num(char const * val) { return newnode(val); } Node * nn_id(char const * val) { return newnode(val); } static void dump(Node * n, int level) { printf("%*s%s\n", level*4, "", n->name); if (n->child) dump(n->child, level+1); if (n->sibling) dump(n->sibling, level); }