练习了下yacc与lex的使用,写了一个计算器的练习,如下
首先编辑cal.l
%{ #include "y.tab.h" #include <math.h> extern double vbltable[26]; extern YYSTYPE yylval; %}
%% ([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval.dval = atof(yytext); return NUMBER; }
[ \t] ; /* ignore white space */
[a-z] { yylval.vblno = yytext[0] - 'a'; return NAME; }
"$" { return 0; /* end of input */ }
\n | . return yytext[0]; %%
|
再编辑cal.y
%{ #include <stdio.h> double vbltable[26]; %}
%union { double dval; int vblno; }
%token <vblno> NAME %token <dval> NUMBER %left '-' '+' %left '*' '/' %nonassoc UMINUS
%type <dval> expression %% statement_list: statement '\n' | statement_list statement '\n' ;
statement: NAME '=' expression { vbltable[$1] = $3; } | expression { printf("= %g\n", $1); } ;
expression: expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { if($3 == 0.0) yyerror("divide by zero"); else $$ = $1 / $3; } | '-' expression %prec UMINUS { $$ = -$2; } | '(' expression ')' { $$ = $2; } | NUMBER | NAME { $$ = vbltable[$1]; } ; %%
int yyerror(char *str) { fprintf(stderr,"Error: %s\n",str); return 1; }
int yywrap() { return 1; } int main() { printf("calculate:\n"); yyparse(); }
|
最后编译下,
lex cal.l yacc -d cal.y cc -o tt lex.yy.c y.tab.c
|
执行后,可以进行下面的计算
阅读(918) | 评论(0) | 转发(0) |