lex和yacc实现计算器
时间: 2023-08-02 21:26:14 浏览: 32
Lex和Yacc是UNIX系统中常用的编译器构建工具。它们可以帮助我们快速地构建一个计算器。下面是一个简单的例子:
首先,我们需要创建一个名为calc.l的Lex文件,并在其中定义我们的词法规则(即如何识别输入):
```
%{
#include "y.tab.h"
%}
%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[-+*/\n] { return yytext[0]; }
[ \t] { /* ignore whitespace */ }
. { printf("Invalid character: %s\n", yytext); }
%%
int yywrap() {
return 1;
}
```
在上面的代码中,我们定义了三个规则,分别是:
* 匹配数字(由1个或多个数字组成)
* 匹配运算符(加、减、乘、除以及换行符)
* 忽略空格和制表符
接下来,我们需要创建一个名为calc.y的Yacc文件,并在其中定义我们的语法规则(即如何解析输入):
```
%{
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
%}
%token NUMBER
%%
input: /* empty */
| input line
line : '\n'
| exp '\n' { printf("= %d\n", $1); }
exp : NUMBER
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '(' exp ')' { $$ = $2; }
%%
int main() {
yyparse();
return 0;
}
int yyerror(char *s) {
printf("Error: %s\n", s);
return 0;
}
```
在上面的代码中,我们定义了四个规则,分别是:
* 匹配输入(由0个或多个行组成)
* 匹配行(由换行符组成)
* 匹配表达式(由数字、运算符和括号组成)
* 定义规则的动作(例如,对于运算符,我们执行相应的计算)
最后,我们可以使用以下命令编译和运行我们的计算器:
```
$ lex calc.l
$ yacc -d calc.y
$ cc lex.yy.c y.tab.c -o calc
$ ./calc
```
现在,我们的计算器已经准备就绪了!