添加乘除以及括号支持
calc2.l
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /* calculator #1 */ %{ #include "y.tab.h" #include <stdlib.h> void yyerror(char *); %} %% [a-z] { yylval = *yytext - 'a'; return VARIABLE; } [0-9]+ { yylval = atoi(yytext); return INTEGER; } [-+()=/*\n] { return *yytext; } [ \t] ; /* skip whitespace */ . yyerror("Unknown character"); %% int yywrap(void) { return 1; } |
calc2.y
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | %{ #include <stdio.h> void yyerror(char *); int yylex(void); int sym[26]; %} %token INTEGER VARIABLE %left '+' '-' %left '*' '/' %% program: program statement '\n' | /* NULL */ ; statement: expression { printf("%d\n", $1); } | VARIABLE '=' expression { sym[$1] = $3; } ; expression: INTEGER | VARIABLE { $$ = sym[$1]; } | expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { $$ = $1 / $3; } | '(' expression ')' { $$ = $2; } ; %% void yyerror(char *s) { fprintf(stderr, "%s\n", s); } int main(void) { yyparse(); } |
%left指定operator是left-associative。%right指定为right associative。列表中最后定义的有最高的优先级。
Makefile
1 2 3 4 5 6 7 | all: bison -y -d calc2.y flex calc2.l gcc -o calc2 y.tab.c lex.yy.c clean: rm -f *.yy.c *.tab.c *.tab.h calc2 |
运行:
1 2 3 4 5 | $ ./calc2 1+2*3 7 (1+2) * 3 9 |