CMake处理lex和yacc文件。即自动将lex&yacc文件转换成为c/c++文件,然后生成库文件或可执行文件。
这里只有一个lex文件(test.ll),然后生成可执行文件ttest。——test是cmake保留字,所以这里用ttest。
两个子目录:
test/src: test.ll, CMakeLists.txttest/bin: 工作目录,一开始为空,生成的文件都放在这里。或者
cmake_minimum_required(VERSION 2.8)project(ttest)# bisonfind_package(FLEX)FLEX_TARGET(ttest_lexer test.ll ${CMAKE_CURRENT_BINARY_DIR}/test.cpp)# mainadd_executable(ttest ${CMAKE_CURRENT_BINARY_DIR}/test.cpp)# librariesfind_library(LEX_LIB l)target_link_libraries(ttest ${LEX_LIB})两个文件:test.ll, test.yy. 最后生成可执行文件ttest。
执行如下命令:
yacc -d test.yylex test.llgcc -o test lex.yy.c y.tab.c -ll运行示例:
$ ./test Usage: ./test filename$ echo phone 1000 > ok.txt$ echo tom jerry > fail.txt$ ./test ok.txt pass...$ ./test fail.txt syntax error$首先修改test.ll中的头文件名称:
#include "y.tab.h" --> #include "parser.h"同样创建src/bin/CMakeLists.txt。其中cmake文件内容:
cmake_minimum_required(VERSION 3.5)project(ttest)# bison and flexfind_package(BISON)find_package(FLEX)BISON_TARGET(ttest_parser test.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h )FLEX_TARGET(ttest_lexer test.ll ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)# default header file is parser.hppADD_FLEX_BISON_DEPENDENCY(ttest_lexer ttest_parser)# maininclude_directories(${CMAKE_CURRENT_BINARY_DIR})set (MAIN_SRC ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp# or ${BISON_ttest_parser_OUTPUTS}${FLEX_ttest_lexer_OUTPUTS} )add_executable(ttest ${MAIN_SRC})find_library(LEX_LIB l)target_link_libraries(ttest ${LEX_LIB})注意到对于生成的cpp文件的两种引用方式。
另,根据https://cmake.org/cmake/help/v3.6/release/3.4.html的说法,可能cmake版本要求至少是3.4:
The FindBISON module BISON_TARGET macro learned a new DEFINES_FILE option to specify a custom output header to be generated.假定要把lexer&parser的代码打包成lib,然后供其他的cpp调用。为此,把test.yy中的main()搬到一个新的main.cpp文件中:
#include <stdio.h>extern FILE *yyin;extern int yyparse();int main(int argc, const char* argv[]){ if (argc != 2) { printf("Usage: %s filename/n", argv[0]); return 0; } yyin = fopen(argv[1], "rb"); if (NULL == yyin) { printf("Open file failed: %s/n", argv[1]); return 0; } while(!feof(yyin)) { yyparse(); } fclose(yyin); yyin = NULL; return 0;}然后cmake文件改为:
cmake_minimum_required(VERSION 3.5)project(ttest)# bison and flexfind_package(BISON)find_package(FLEX)BISON_TARGET(ttest_parser test.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h )FLEX_TARGET(ttest_lexer test.ll ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)# default header file is parser.hppADD_FLEX_BISON_DEPENDENCY(ttest_lexer ttest_parser)include_directories(${CMAKE_CURRENT_BINARY_DIR})add_library(myparser ${BISON_ttest_parser_OUTPUTS} ${FLEX_ttest_lexer_OUTPUTS} )# mainadd_executable(ttest main.cpp)target_link_libraries(ttest myparser)find_library(LEX_LIB l)target_link_libraries(ttest ${LEX_LIB})新闻热点
疑难解答