添加乘除以及括号支持
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.cclean: rm -f *.yy.c *.tab.c *.tab.h calc2 |
运行:
1 2 3 4 5 | $ ./calc21+2*37(1+2) * 39 |