本文为原创,部分bat代码来自熊春雷前辈的博文:http://blog.csdn.net/pandaxcl/archive/2006/07/04/873898.aspx

 

为什么要使用lex和yacc

      最近的项目需要写一个Language Service,于是不可避免的涉足到了lex和yacc。lex和yacc原本是UNIX系统下的两个工具,用于编写涉及文本分析的程序。在Linux下面有两个GNU的工具:flex和bison,用来代替原始的lex和yacc。熊春雷前辈在上面的博文中介绍了如何获取flex和bison的Win32版,和如何在Win32环境下配置这两个工具,其中还要用到Windows版本的GCC,还是挺麻烦的。

 

为什么要在Visual Studio2008中调试lex和yacc程序

     正如上面所说的配置环境和使用GCC对于大多数Windows程序员来说是挺麻烦的,事实上我们完全可以使用Visual Studio带的C/C++编译器。使用Visual Studio2008的强大编辑环境,能够轻松的调试你的lex和yacc程序。

 

配置思路

      事实上,上面提到的flex和bison分别将*.l和*.y编译成C语言代码,然后我们用Visual Studio带的C/C++编译器就可以编译这个C代码,生成可执行文件。(顺便提一下,在开发Language Service时,需要用微软的两个特殊编译器来编译*.lex和*.y,分别是MPLex和MPPG,你可以在VS2008SDK路径下找到这两个工具)

      有了上面的认识,配置思路就很清晰了:建立一个C++的Console工程,把*.l和*.y放在工程中,在预编译选项中输入相应的命令行,使得在编译C代码之前用flex和bison编译*.l和*.y,这样就OK啦!

 

步骤

第一步:下载flex和bison。这里要下载的是win32的版本,熊春雷前辈的地址我找不到了,贴个我的地址吧:http://download.csdn.net/source/2161087

下载后你将看到这些文件,这些都是熊春雷前辈大包整理好的。

bison.exe         GNU的yacc程序
bison.hairy       GNU的yacc程序运行需要的文件
bison.simple      GNU的yacc程序运行需要的文件
flex.exe          GNU的lex程序
ini.bat           这个lex和yacc环境的环境变量配置
lexyacc.bat       这个lex和yacc环境的启动程序
Readme.txt        本说明文件

第二步:新建一个Console工程。在Visual Studio2008中建立一个C++的Console工程,选择空工程。将上面解压出来的文件复制到工程目录下。在工程路径下建一个frame.l和frame.y,这两个文件就是你*.l和*.y的源代码文件,将来可以在Visual Studio中编辑,你也可以取其他的名字,但相应的需要修改下面的介绍的命令行。

下面给出最简单的测试代码:

frame.l的代码:

%{

int yywrap(void);

%}

%%

%%

int yywrap(void)

{       

return 1;

}

frame.y的代码:

%{

void yyerror(const char *s);

%}

%%

program:      

;

%%

void yyerror(const char *s)

{}

int main()

{       

yyparse();       

return 0;

}

第三步:配置工程的预编译。右击工程->属性,在弹出的对话框中选择Buid Events->Pre-Build Event,在右侧的Command Line中输入如下命令行:

@set INSTALLDIR=%CD%
@PATH=%INSTALLDIR%
@set BISON_SIMPLE=%INSTALLDIR%\bison.simple
@set BISON_HAIRY=%INSTALLDIR%\bison.hairy
$(ProjectDir)bison -d frame.y
$(ProjectDir)flex frame.l

(上面的命令行一部分来源于lexyacc.bat文件)

如图所示:

image 第四步:添加C源程序文件。第三步完成之后,可以ReBuild一下,这样flex和bison便会在工程路径下编译出三个文件:

frame.tab.h

frame.tab.c

lex.yy.c

将这三个文件添加到工程中的对应位置,同时将frame.l和frame.y也加到工程中,以方便编辑。这样环境便基本搭建好了,每次编译时会自动调用命令行编译frame.l和frame.y,然后将再编译生成的C文件,并debug可执行文件,这样就省去了使用gcc,十分方便。

第五步:为文本输入配置命令行参数。上面的调试仅仅支持一行行输入,如果想要给程序一次性输入一个文本怎么办呢?我们可以通过配置命令行参数来实现,在debug文件夹下新建一个source.txt用于编写需要被解析的文本。右击工程->属性,在弹出的对话框中选择Debugging,在Command Arguments中输入命令行参数<$(TargetDir)source.txt,表示将目标路径下的source.txt作为文件交给程序解析。如图:

image 至此,你便可以将想要解析的文本,提前在source.txt中写好了。

 

后续:

flex和bison貌似只支持ANSI编码的文本。所以,如果你的flex或bison代码是从某个pdf中copy进VS2008的,那么有可能,VS2008会检测到文本含有Unicode编码的文本,会提示是否要转化,这个时候千万不要转化!否则flex和bison将无法识别Unicode编码开头的FF FE!!会有N多编译错误。第一次的时候,我为那些莫名其妙的错误弄的焦头烂额。

如果不慎转化了,那么只能用记事本转回ANSI。

所以代码还是多打字的好!呵呵。