浏览 2243 次
锁定老帖子 主题:yacc 和 lex的上手(3)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-12-17
sample 4 一个简单的恒温控制器 (突然记起来大三时候做过的fuzzy logic的东东了) 目标:我们有一个恒温器,想用简单的语言来控制它,就像下面这样 heat on Heater on! heat off Heater off! target temperature 22 New temperature set! 我们需要识别token:heat, on/off (STATE), target, temperature, NUMBER 首先建立example4.l %{ #include <stdio.h> #include "y.tab.h" %} %% [0-9]+ return NUMBER; heat return TOKHEAT; on|off return STATE; target return TOKTARGET; temperature return TOKTEMPERATURE; \n /* ignore end of line */; [ \t]+ /* ignore whitespace */; %% 和前面相比这里有2个大的变化,一是inlucde y.tab.h ,另一个是不再直接print了, 而是返回token。原来是输出了screen,而现在则输出到yacc去了。 y.tab.h 是下面我们将要创建的文件, 通过yacc的语法文件来生成。 我们看看语法,BNF形式。 commands: /* empty */ | commands command ; command: heat_switch | target_set ; heat_switch: /* 加热开关 */ TOKHEAT STATE /* STATE 就是上面lex里面定义的on off */ { printf("\tHeat turned on or off\n"); } ; target_set: /*目标温度设定 */ TOKTARGET TOKTEMPERATURE NUMBER { printf("\tTemperature set\n"); } ; 编译 lex example4.l yacc -d example4.y cc -o example4 lex.yy.c y.tab.c 运行 $ ./example4 heat on Heat turned on or off heat off Heat turned on or off target temperature 12 Temperature set target xxx 34 error: syntax error xxx 我们再来扩展一下这个恒温器,让它能处理参数。 lex匹配到目标的时候,会同时将值赋到yytext中。yacc反过来又从yyval中取得值。 下面是新的lex文件 %{ #include <stdio.h> #include "y.tab.h" %} %% [0-9]+ yylval=atoi(yytext); return NUMBER; heat return TOKHEAT; on|off yylval=!strcmp(yytext,"on"); return STATE; target return TOKTARGET; temperature return TOKTEMPERATURE; \n /* ignore end of line */; [ \t]+ /* ignore whitespace */; %% 相应的yacc文件也要修改: %{ #include <stdio.h> #include <string.h> void yyerror(const char *str) { fprintf(stderr,"error: %s\n",str); } int yywrap() { return 1; } main() { yyparse(); } %} %token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE %% commands: /* empty */ | commands command ; command: heat_switch | target_set ; heat_switch: /* 这里使用了lex里面设置参数 */ TOKHEAT STATE { if($2) printf("\tHeat turned on\n"); else printf("\tHeat turned off\n"); } ; target_set: /* 这里使用了lex里面设置参数 */ TOKTARGET TOKTEMPERATURE NUMBER { printf("\tTemperature set to %d\n",$3); } ; %% 再次编译 然后运行 $ ./example4 heat on Heat turned on heat off Heat turned off target temperature 34 Temperature set to 34 得到预期的结果。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |