CMake&yacc&lex
发布时间:2020-12-15 03:30:41 所属栏目:百科 来源:网络整理
导读:Reference cmake bison command: https://cmake.org/cmake/help/v3.6/module/FindBISON.html cmake flex command: https://cmake.org/cmake/help/v3.6/module/FindFLEX.html 内容 CMake处理lex和yacc文件。即自动将lexyacc文件转换成为c/c++文件,然后生成库
Reference
内容CMake处理lex和yacc文件。即自动将lex&yacc文件转换成为c/c++文件,然后生成库文件或可执行文件。 lex这里只有一个lex文件(test.ll),然后生成可执行文件ttest。——test是cmake保留字,所以这里用ttest。 目录结构两个子目录:
文件test.ll%{ #include <string> #include <iostream> %} %% [t ]+ /* white space */ [a-zA-Z]+ { std::string word(yytext); std::cout<<"word: "<<word<<std::endl; } [0-9]+ { std::string number(yytext); std::cout<<"number: "<<number<<std::endl; } .|n {ECHO; /* normal default anyway */ } %% int main() { std::cout<<"Lex and C++"<<std::endl; yylex(); return 0; } CMakeLists.txtcmake_minimum_required(VERSION 2.8) project(ttest) # bison and flex find_package(BISON) find_package(FLEX) FLEX_TARGET(ttest_lexer test.ll ${PROJECT_BINARY_DIR}/test.cpp) # main set (MAIN_SRC ${PROJECT_BINARY_DIR}/test.cpp) add_executable(ttest ${MAIN_SRC}) # libraries find_library(LEX_LIB l) target_link_libraries(ttest ${LEX_LIB}) 或者 cmake_minimum_required(VERSION 2.8) project(ttest) # bison find_package(FLEX) FLEX_TARGET(ttest_lexer test.ll ${CMAKE_CURRENT_BINARY_DIR}/test.cpp) # main add_executable(ttest ${CMAKE_CURRENT_BINARY_DIR}/test.cpp) # libraries find_library(LEX_LIB l) target_link_libraries(ttest ${LEX_LIB}) Run$ ./ttest Lex and C++ abd 123 word: abd number: 123 ^C lexer&parserFiles两个文件:test.ll,test.yy. 最后生成可执行文件ttest。 test.ll%{ //#include <string> #include "y.tab.h" %} %% [t ]+ ; [a-zA-Z]+ {return OBJECT;} [0-9]+ {return PRICE;} .|n {ECHO;} test.yy%{ #include <stdio.h> extern int yylex (void); void yyerror(const char *s,...); %} %token OBJECT PRICE %% description: object PRICE { printf("pass...n"); } ; object: OBJECT ; %% extern FILE *yyin; int main(int argc,const char* argv[]) { if (argc != 2) { printf("Usage: %s filenamen",argv[0]); return 0; } yyin = fopen(argv[1],"rb"); if (NULL == yyin) { printf("Open file failed: %sn",argv[1]); return 0; } while(!feof(yyin)) { yyparse(); } fclose(yyin); yyin = NULL; return 0; } void yyerror(const char *s,...) { fprintf(stderr,"%sn",s); } 不用cmake执行如下命令: yacc -d test.yy lex test.ll gcc -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 $ 用cmake首先修改test.ll中的头文件名称: #include "y.tab.h" --> #include "parser.h" 同样创建src/bin/CMakeLists.txt。其中cmake文件内容: cmake_minimum_required(VERSION 3.5) project(ttest) # bison and flex find_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.hpp ADD_FLEX_BISON_DEPENDENCY(ttest_lexer ttest_parser) # main include_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. lex&parser打包成库文件假定要把lexer&parser的代码打包成lib,然后供其他的cpp调用。为此,把test.yy中的main()搬到一个新的main.cpp文件中: #include <stdio.h> extern FILE *yyin; extern int yyparse(); int main(int argc,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 flex find_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.hpp ADD_FLEX_BISON_DEPENDENCY(ttest_lexer ttest_parser) include_directories(${CMAKE_CURRENT_BINARY_DIR}) add_library(myparser ${BISON_ttest_parser_OUTPUTS} ${FLEX_ttest_lexer_OUTPUTS} ) # main add_executable(ttest main.cpp) target_link_libraries(ttest myparser) find_library(LEX_LIB l) target_link_libraries(ttest ${LEX_LIB}) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |