flex 和 Bison 的计算机
flex源代码
%{
#include <stdio.h>
#include <stdlib.h>
#include "simple.tab.h"
%}
%%
"+" {return ADD;}
"-" {return SUB;}
"*" {return MUL;}
"/" {return DIV;}
"\n" {return CR; }
([1-9][0-9]*)|0|([0-9]+\.[0-9]+) {
double temp;
sscanf(yytext,"%lf",&temp);
yylval.double_value = temp;
return DOUBLE_LITERAL;
}
[\t];
. {
fprintf(stderr,"lexical error.\n");
}
%%
int main(void)
{
yyparse();
return 0;
}
int yywrap(void)
{
return 0;
}
bison源代码
%{
#include <stdio.h>
#include <stdlib.h>
int yyerror(char* msg);
int yylex(void);
#define YYDEBUG 1
%}
%union{
int int_value;
double double_value;
}
%token <double_value> DOUBLE_LITERAL
%token ADD SUB MUL DIV CR
%type <double_value> expression term primary_expression
%%
line_list
: line
| line_list line
;
line
: expression CR
{
printf(">>%lf\n", $1);
}
expression
: term
| expression ADD term
{
$$ = $1 + $3;
}
| expression SUB term
{
$$ = $1 - $3;
}
;
term
: primary_expression
| term MUL primary_expression
{
$$ = $1 * $3 ;
}
| term DIV primary_expression
{
$$ = $1 / $3;
}
;
primary_expression
:DOUBLE_LITERAL
;
%%
int yyerror(char* msg)
{
printf("error\n");
return 0;
}
运行结果
举个例子来说明
3*2+5/2 \n
在lex 中会被转成
DOUBLE_LITERAL MUL DOUBLE_LITERAL ADD DOUBLE_LITERAL DIV DOUBLE_LITERAL CR
在bison中会被认为line :(expression CR)
expression发现有MUL和DIV执行,转为term,
term MUL primary_expression
用double_value来计算结果。
bison相关符号请查阅http://blog.csdn.net/sirouni2003/article/details/400672#SEC54