logo资料库

计算器语法分析器.docx

第1页 / 共2页
第2页 / 共2页
资料共2页,全文预览结束
词法处理文件 calc.lex 内容如下: %{ /* * 一个简单计算器的 Lex 词法文件 */ #include void yyerror(char*); #include "calc.tab.h" %} %% /* a-z 为变量 */ [a-z] { yylval = *yytext - 'a'; return VARIABLE; } /* 整数 */ [0-9]+ { yylval = atoi(yytext); return INTEGER; } /* 运算符 */ [-+()=/*\n] {return *yytext;} /* 空白被忽略 */ [ \t] ; /* 其他字符都是非法的 */ . yyerror("无效的输入字符"); %% int yywrap(void) { return 1; } 词法处理的目标就是区分出来每个成员到底是什么,这里有两种 INTEGER 和 VARIABLE。只要区分出来 各个成分词法分析的任务就完成了。 语法处理文件 calc.y 内容如下: %token INTEGER VARIABLE %left '+' %left '*' %{ #include '-' '/'
void yyerror(char*); int yylex(void); int sym[26]; %} %% program: program statement '\n' | ; statement: expr {printf("%d\n", $1);} |VARIABLE '=' expr {sym[$1] = $3;} ; expr: INTEGER |VARIABLE{$$ = sym[$1];} |expr '+' expr {$$ = $1 + $3;} |expr '-' expr {$$ = $1 - $3;} |expr '*' expr {$$ = $1 * $3;} |expr '/' expr {$$ = $1 / $3;} |'('expr')' {$$ = $2;} ; %% void yyerror(char* s) { fprintf(stderr, "%s\n", s); } int main(void) { printf("A simple calculator.\n"); yyparse(); return 0; } 语法分析文件的写法就是将 BNF 表达式描述一下即可,规则随着条目逐渐细化,变成了可以理解的内容。 这里不用管如何实现这些语法的分析,只是需要告知如何构建这些语法。 编译命令如下: >bison -d calc.y >flex calc.lex >gcc calc.tab.c lex.yy.c -o calc
分享到:
收藏