最近在单位的几个小模块中,大胆加入了antlr,使原本呆板的功能增色不少,于是便蠢蠢欲动,想着用用yacc,后续为公司现在搞的胖客户端瘦瘦身。这是后话了。
且说在琢磨Yacc的时候,还是遇到不少问题,首先,我一般不写c++,c程序,所以不像好多人直接在linux下,用vi写代码,也不似很多人在win下,就用个ultraedit,当然这两个工具都挺好用,比如ultraedit有个列模式,那个功能真不错,和在linux下使用awk有些类似,跑题了,我是说我还是钟爱IDE,喜欢vs2008+红苹果的那种感觉,不喜欢记那么多的函数,只需要大概记得一些即可,所以我一开始的目标是在vs2008下使用生成的代码。所以在google上搜vs2008 yacc,的确出来不少,其中一个是parse generator2的软件,我也下了下,也按照文章中说的方法,在vs2008下重新编译了一下,确实也不错,可以用yacc生成出c++,c,java代码来。这个后续再慢慢研究了。现在我说的一种比较简单的方法,在vi上面编辑*.l,*.y,然后调用命令生成.c文件,在2008下编译。
首先我转载一下,博客园的一片文章:
http://www.cnblogs.com/P_Chou/archive/2010/03/24/1693763.html
这篇文章已经说的较为详细了,如何配置,但我这里增加一点,在vs2008里编辑*.l,*.y没有语法着色功能,这个对我而言不太好,于是,我决定用vim来进行编辑,当然也可以直接在vim中调用bison 等命令来生成代码。 还是用原博文中推荐的方法吧,不过我略改了下,将预生成事件的命令做了一点改动,就免得每次拷贝那连个simple和hairy文件了。一切都准备好,我就摩拳擦掌于那个《编译原理与实践》里一开始就讲的计算器程序了。
实际上书上第5章已经有相应的yacc的例子了,但它那个是一个只写了.y文件的,我这边来一个 .l+.y的。贴代码:
这个是frame.l ,其中 \n {return 0;} 较为重要,可以去掉直接写为 \n 试试。
%{
#include "frame.tab.h"
int yywrap(void);
%}
%%
[0-9]+ { yylval=atoi(yytext); return NUMBER;}
[\t ]
\+ { return PLUS;}
- {return MINUS;}
\* {return MUL;}
\/ {return DIV;}
\( {return LP;}
\) {return RP;}
\n {return 0;}
%%
int yywrap(void)
{
return 1;
}
frame.y文件
%{
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
void yyerror(const char *s);
extern FILE *yyin;
%}
%token NUMBER PLUS MINUS LP RP MUL DIV
%%
program: expr { printf("expr:%d\n",$1);};
expr:expr PLUS term {$$=$1+$3; }
|expr MINUS term {$$=$1-$3;}
|term {$$=$1;}
;
term:term MUL factor {$$=$1*$3; }
|term DIV factor {$$=$1/$3;}
|factor {$$=$1;}
;
factor: NUMBER {$$=$1;}
| LP expr RP {$$=$2;}
%%
void yyerror(const char *s)
{
printf("err:%s\n",s);
}
int main()
{
do{
yyparse();
}while(!feof(yyin));
return 0;
}
然后在vs2008中建个工程,按照上面链接中博客园文章中说的,建立工程,将frame.l,frame.y分别加入,加入预处理事件,点击重新生成,然后将.h,.c文件都加入工程,F5编译即可。
下面是运行图片: