lex和yacc环境配置
lex和yacc的使用很簡(jiǎn)單,但環(huán)境配置卻是各種問題,本章說明lex和yacc在windows下的環(huán)境配置。
軟件需求:
系統(tǒng) win7-64位(win7-32, win8, win10全部通過)
c++編譯器: vs2010(2008,2013,2015也全部通過)
lex和yacc編譯器: ParGen.exe
基本流程:
安裝Pargen.exe,采用的默認(rèn)目錄安裝在C:\Program Files (x86)\Parser Generator 2\
安裝vs2010,這個(gè)各種教程,不再贅述
啟動(dòng)Pargen程序,并選擇Project->ParserWizard…
選中ParserWizard,開始工程的創(chuàng)建,此處我創(chuàng)建功能,命名為Test,目錄位置可自己選擇,目標(biāo)語言為C++,編譯器為vc++(32-bit)
下一步,選擇是創(chuàng)建lex,還是yacc,還是兩者兼有。此處我選擇是lex和yacc都有,準(zhǔn)備實(shí)現(xiàn)一個(gè)不支持變量的計(jì)算器,使用lex識(shí)別token,使用yacc識(shí)別語法。
下一步,設(shè)置yacc的文件名字以及使用的解析器,此處我使用的默認(rèn)選項(xiàng),不進(jìn)行修改,文件名默認(rèn)為myparser.y
下一步,設(shè)置lex的文件名以及使用的分析器的名字,此處我使用的默認(rèn)選項(xiàng),文件名默認(rèn)為mylexer.l
點(diǎn)擊完成按鈕,創(chuàng)建工程完畢,同時(shí)有兩個(gè)文件mylexer.l 和myparser.y
工程的管理,可使用window->project菜單,查看工程下的所有文件
當(dāng)你點(diǎn)擊文件編輯窗口的放大按鈕,會(huì)將其他的文件編輯覆蓋,此時(shí)可以使用window->project菜單查看,也可以使用window->Tile vertically查看全部文件的平鋪
編輯mylexer.l文件,粘貼入以下內(nèi)容:
%{ //this code will be added into the header of generated .cpp file #include <iostream> #include "myparser.h" using namespace std;//already defined in yacc.y, use %token... //enum{LT, EQ, GT, IF, ELSE, ID, NUMBER, PLUS, MINUS, TIMES, OVER, INT, DOUBLE,CHAR, LP,RP};const char* tokenStr[] = {"LT", "EQ", "GT", "IF", "ELSE", "ID", "NUMBER", "PLUS", "MINUS", "TIMES", "OVER", "INT", "DOUBLE","CHAR"}; static void print_token(int token, char* lex);%}%name mylexerdelim [ \t] ws {delim}+ letter [a-zA-Z] digit [0-9] id {letter}({letter}|{digit})* /* can support 12.34 */ number {digit}+(\.{digit}+)?%% %{ //this code will be added into yyaction functionYYSTYPE YYFAR& yylval = *(YYSTYPE YYFAR*)yyparserptr->yylvalptr;//double yylval; %}{ws} {/* do nothing */} "int" {print_token(INT, yytext); return INT;} "double" {print_token(DOUBLE, yytext);} "char" {print_token(CHAR, yytext);}"+" {print_token(PLUS, yytext); return PLUS;} "-" {print_token(MINUS, yytext); return MINUS;} "*" {print_token(TIMES, yytext); return TIMES;} "/" {print_token(OVER, yytext); return OVER;} "(" {return LP;} ")" {return RP;} "\n" {return EOL;} {id} { return ID;} {number} { yylval = atof(yytext);return NUMBER;} "//".* {return COMMENT;} "." {printf("Mystery character %s\n", yytext); } %%static void print_token(int token, char* lex) { #ifdef LEX_DEUBcout<<"token:" << token<<" "<<"lex:"<<lex<<endl; #endif }編譯myparser.y文件,粘貼入以下內(nèi)容
%{ #include "mylexer.h" %}%name myparser // class definition {// place any extra class members here } // constructor {// place any extra initialisation code here }// destructor {// place any extra cleanup code here }// place any declarations here %include { #ifndef YYSTYPE #define YYSTYPE double #endif }%token NUMBER ID %token PLUS MINUS TIMES OVER %token LP RP EOL COMMENT %TOKEN INT DOUBLE CHAR%left PLUS MINUS %left TIMES OVER %right UMINUS%%lines : lines expr EOL { printf("%g\n", $2); }| lines EOL| lines COMMENT|;expr : expr PLUS expr { $$ = $1 + $3; }| expr MINUS expr { $$ = $1 - $3; }| expr TIMES expr { $$ = $1 * $3; }| expr OVER expr { $$ = $1 / $3; }| LP expr RP { $$ = $2; }| '-' expr %prec UMINUS { $$ = -$2; }| NUMBER {$$=$1;} //$$=$1 can be ignored| ID //should be complemented; %%int main(int argc, char *argv[]) {printf("a cacluator which support +,-,*,/ and (): \n");printf(" e.g. 12.2+3*(2+5)\n");int n = 1;mylexer lexer;myparser parser;if (parser.yycreate(&lexer)) {if (lexer.yycreate(&parser)) {//lexer.yyin = new ifstream(argv[1]);//lexer.yyout = new ofstream(argv[2]);n = parser.yyparse();//parse_tree.get_label();//parse_tree.gen_code(*lexer.yyout);}}getchar();return n; }點(diǎn)擊Pargen右上角的編譯build按鈕,會(huì)生成相應(yīng)的.h和.cpp代碼
新建vs2010工程,并將生成的.h和.cpp代碼加入到工程中。簡(jiǎn)單起見,在comple\Test目錄下創(chuàng)建vs工程vsTest
選擇控制臺(tái)工程, 工程的目錄,以及工程名稱vsTest,點(diǎn)擊確定按鈕后
繼續(xù)下一步配置
此處附件選項(xiàng)選擇空項(xiàng)目,然后點(diǎn)擊完成按鈕,即完成vsTest工程創(chuàng)建
工程右鍵添加現(xiàn)有項(xiàng),即添加已經(jīng)生成.h和.cpp文件
在vs界面,點(diǎn)擊編譯按鈕,查看當(dāng)前的編譯情況,會(huì)顯示編譯錯(cuò)誤,找不到y(tǒng)y的頭文件,這是因?yàn)椴]有將Pargen安裝后的頭文件加入到工程的包含目錄中
下面將Pargen安裝后的頭文件加入到工程include配置
在vs界面,點(diǎn)擊編譯按鈕,查看編譯情況。 當(dāng)前頭文件可以正常找到,會(huì)出現(xiàn)大量的鏈接錯(cuò)誤-link error。這是因?yàn)閷?duì)應(yīng)的lib文件還沒有加載進(jìn)來。
下面加入庫(kù)文件,加入庫(kù)所在目錄
加入要使用的庫(kù)的名字:ylmtri.lib, 注意使用分號(hào)隔開
再次點(diǎn)擊編譯按鈕,會(huì)發(fā)現(xiàn)可以編譯,但是運(yùn)行的時(shí)候,會(huì)出現(xiàn)ylmtri.dll的錯(cuò)誤。這是因?yàn)槲覀兪褂脛?dòng)態(tài)dll庫(kù),需要將對(duì)應(yīng)的dll文件從Pargen目錄復(fù)制到工程目錄的exe文件同級(jí)目錄下
下面開始將ylmtri.dll從Pargen目錄復(fù)制到vsTest.exe同級(jí)目錄
再次點(diǎn)擊編譯運(yùn)行按鈕,可以正常運(yùn)行,效果如下
出處:http://blog.csdn.net/lpstudy/article/details/51330063
在最后一步的過程中,遇到了添加完ylmtri.dll仍然報(bào)錯(cuò)的情況,也是比較尷尬,在解決之后再修改。
總結(jié)
以上是生活随笔為你收集整理的lex和yacc环境配置的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设置log缓存_node多级缓存之red
- 下一篇: 利用spi发送接收信息c语言,SPI接收