编译原理:用flex和bison实现一个简单的计算器

运用flex和bison工具实现一个简单的计算器,可以进行+、-、*、/等运算。
flex源代码格式:
declarations
%%
translation rules
%%
auxiliary functions
语法分析器的自动构造:
编译原理:用flex和bison实现一个简单的计算器_第1张图片
bison源代码格式:
declarations
%%
translation rules
%%
supporting C routines

Translation Rule:
这里写图片描述
编译原理:用flex和bison实现一个简单的计算器_第2张图片
calc.l

%{
# include "calc.tab.h"
int lexerror(char *s);
%}

%%
"+" { return ADD; }
"-" { return SUB; }
"*" { return MUL; }
"/" { return DIV; }
"("     { return LP; }
")"     { return RP; }
[0-9]+  { yylval = atoi(yytext); return NUM; }

\n      { return EOL; }
[ \t]   { /* ignore white space */ }
.   { lexerror(yytext); }
%%

int lexerror(char *s)
{
  fprintf(stderr, "lexical error: %s\n", s);
}

calc.y:

%{
#  include 

int yyerror(char *s);
int yylex();

%}

//set attribute type
%define api.value.type {int}

/* declare tokens (terminal symbols) */
%token NUM  256
%token ADD 257
%token SUB 258
%token MUL 259
%token DIV 260
%token LP 261
%token RP 262
%token EOL 263

%%

start: 
 | start expr EOL { printf("= %d\n> ", $2); };

expr: term
 | expr ADD term { $$ = $1 + $3; }
 | expr SUB term { $$ = $1 - $3; } 
 ;

term: factor { $$ = $1; }
 | term MUL factor { $$ = $1 * $3; }
 | term DIV factor { $$ = $1 / $3; } 
 ;

factor: NUM { $$ = $1; }
 | LP expr RP { $$ = $2; }
 ;

%%
int main()
{
  printf("> "); 
  yyparse();
}

int yyerror(char *s)
{
  fprintf(stderr, "error: %s\n", s);
}

在Unix终端输入命令:
先用bison编译calc.y
这里写图片描述
再使用flex编译calc.l
这里写图片描述
使用gcc命令将上述的文件编译在一起
这里写图片描述
这里写图片描述
运行截图:
编译原理:用flex和bison实现一个简单的计算器_第3张图片

你可能感兴趣的:(编译原理,flex,bison,计算器)