近期在做一个语法文件的扫描,校验的程序, 当然不能不用YACC/LEX这组工具. 但是每次修改语法和词法定文件后都要先在命令行上重新生成对应的源文件, 然后在QtCreator中将这些源文件编译成可执行程序来调试. 这样来回切换工作觉得非常麻烦, 且效率低下。于是希望找到一个集成的办法可一次完成所有的编译连接工作, 几经周折查询, 终于达到目标, 以下将整个过程记录在此, 希望对其他人有些帮助。
因为是Windows下应用,YACC/LEX工具是用的GNU的Bison/Flex, 下载的是Windows下的二进制安装程序, 下载地址分别是Bison for Windows和Flex for Windows .
1. 在QT项目文件的帮助就是QMake的文档中看到, 在QMake的变量中, 有LEXSOURCES, YACCSOURCES这两个变量, 那就是说可以在qt的项目文件中直接加入lex和yacc的源文件, 而qt应会编译自动生成所需要的源文件. 在pro文件中加入以下两行:
LEXSOURCES = grammar.l
YACCSOURCES = grammar.y
2.点击Build后, 显示 "'byacc'不是内部或外部命令......"这样的错误信息, 看来QMake默认是将byacc作为YACC编译器, 那需要如何修改成自己的文件呢? QMake的文档中没有相关的说明(关于YACC/LEX的信息本来就很少),只能去网上查询了。 结果查到了Undocumented QMake这份文档, 其中的说明解决了一下的大部分问题。原来qmake中有一些未列在文档中的变量(QMAKE_LEX和QMAKE_YACC)可以来完成这些事情。在pro文件中再加入以下两行:
QMAKE_LEX = flex
QMAKE_YACC = bison
然后将bison/flex的目录加到环境变量PATH中,或者加到qmake的搜索路径中, Qmake就会正确执行了.
3.下面的问题是,因为yacc默认生成的文件名是y.tab.h和y.tab.c, qmake中定义了一个步骤将这两个文件改名为<myfile>_yacc.h和<myfile>_yacc.c. 而bison默认生成的文件却不是这两个文件名, 因此重命名的操作会出错, 而后面的编译过程就变成"未找到指定的源文件", 因此需要用到另一个qmake变量QMAKE_YACCFLAGS来给bison程序加上执行的参数指定生成的文件名为"y.tab.c", 使后面的过程可以继续。在pro文件中再加上一行:
QMAKE_YACCFLAGS = -d -o y.tab.c -l解释一下, 上面的-d参数是指定生成头文件, 默认是不生成y.tab.h这个文件的, -l是在y.tab.c文件中不创建#line XXX这些标记, -o就是指定输出文件名了。
到这里就可以自动创建和编译bison/flex所需的文件了, 后面的工作就是改错, 调试等等。
最后的Qt项目文件是这样的:
QMAKE_LEX = flex QMAKE_YACC = bison QMAKE_YACCFLAGS = -d -o y.tab.c -l #Debug:QMAKE_YACCFLAGS += -t QT -= core QT -= gui TARGET = xxxxxx CONFIG += console CONFIG -= app_bundle TEMPLATE = app DEFINES += WNT Debug:DEFINES += YYDEBUG LEXSOURCES = xxxxxx.l YACCSOURCES = xxxxxx.y #这里是bison和flex安装目录的包含文件目录 INCLUDEPATH += D:/bin/GnuWin32/include SOURCES += \ main.cp