Lex&Yacc(4) flex与Yacc结合的例子

最近这一周的临时任务实在是重,好几个晚上都很晚才回去。
自己的Javacc开发任务也有所耽搁,下个周也不轻松。所以只好抽晚上程序跑数的时间来更新一下。
Lex是词法解析程序,擅长用正则表达式去匹配词组;而Yacc擅长于对复杂语法的分析,两者结合起来能使代码高效且维护更简单。
下面我们用lex与Yacc写一个计算器的例子,这个例子很经典,到处都可以找到,我的例子来自于《lex与yacc 第二版》第三章的第一个例子ch03-01.l和ch03-01.y。
yc03.y

%token NUMBER //终结符标记。
%type exp term //非终结符标记,多个标记之间使用空格分开

%%

command : exp { printf("=%d\n",$1); }
;

exp : exp '+' term {$$ = $1 + $3;} //$N表示第N个表达式的值;$$表示冒号:左边的表达式
| exp '-' term {$$ = $1 - $3;} //$N所代表的引用值,为yylval的值,该值默认为int类型。
| term {$$ = $1;}
;

term : term '*' factor {$$ = $1 * $3;}
| term '/' factor
{
if($3==0)
yyerror("divide by zero");
else
$$ = $1/$3;
}
| factor {$$ = $1;}
;

factor : NUMBER {$$ = $1; printf("NUMBER \n");}
| '(' exp ')' {$$ = $2;}
;

使用下面的命令来编译yacc程序:
yacc -oyc03.c -d yc03.y 【这里使用:-d参数,是为了方便生成.h文件,以便flex程序引用】
gcc -c ./yc03.c 【编译.c文件】

%{
#include "yc03.h" //这里引用yacc生成的.h文件
extern int yylval; //使用yacc中的yylval变量,将lex中得到的值传递给yacc
%}

%%
[0-9]+ { yylval = atoi(yytext); return NUMBER; } //yytext为满足当前表达式的字符串,return NUMBER表示向Yacc返回NUMBER终结符标记
[ \t] ;
\n return 0; /* logical EOF */
. { return yytext[0]; }
%%
int main(){
yylex();
return(0);
}

使用下面的命令来编译flex程序:
flex -ofl03.c fl03.l
gcc -c ./fl03.c
使用下面的命令来连接flex和yacc生成的.o文件
gcc -o fl03 fl03.o yc03.o -ly -lfl
上面的例子只是讲述了lex与Yacc的结合,能简单解决部分算术运算,且只支持整数。要想支持整数,则需要将yylval的类型重新定义为double类型。而且,上面的例子还没有考虑到带符号的表达式和乘方等,后者可以引入C的math.c进行计算。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值