Win flex-bison 的简单使用
Win flex-bison 的简单使用 学习编译原理的朋友,都会看到书中提到的 lex & yacc 或 flex & bison 工具组合。这两组工具在 Unix, Linux, BSD 上使用不会有太大的问题,但在 Windows 上使用通常需要安装 MinGW+ (Msys GnuWin 或Msys2 ) 或者Cygwin。Win flex-bison 提供了 flex bison for Windows 的另外一种移植,将GNU m4宏处理器源代码集成进 win flex-bison ,不依赖Msys,Msys2,Cygwin 提供的模拟类 Unix 运行环境,不依赖GNU m4宏处理器便可生成 C 目标文件。 flex 见 http://sourceforge.net/projects/flex/ bison 见 http://www.gnu.org/software/bison/ 目前,Msys GnuWin 上的 flex 2.5.35 和 bison (GNU Bison) 2.4.2 版本太陈旧了,N年没更新了。Msys2 ( http://sourceforge.net/projects/msys2/ ) 上的版本新, flex2.5.38 和 bison 3.0.2 Win flex-bison 见 http://sourceforge.net/projects/winflexbison/ Win flex-bison is a port Flex & Bison tools to the Windows platform 下面以 Win flex-bison 2.5.1和《flex & bison》第一章的简单计算器fb1-5为例,简单介绍如何使用。 首先从 http://sourceforge.net/projects/winflexbison/ 下载已经编译好的压缩文件 win_flex_bison-2.5.1.zip(不到700kb), Update:?2014-01-04 DescriptionWin flex-bison is a windows port the Flex(the fast lexical analyser) and Bison (GNU parser generator). win_flex based onFlex version 2.5.37 source code and win_bisonbased on Bison version 2.7 and they depend on system libraries only. Win flex-bison WebSite CategoriesLibraries LicenseGNUGeneral Public License version 3.0 (GPLv3) ? 解压到某一文件夹(如 winFlexBison),将这个文件夹增加到 path 环境变量中,就可以命令行使用了。 ? Bison规则描述文件 fb1-5.y /* Companionsource code for "flex & bison",published by O'Reilly * Media,ISBN 978-0-596-15597-1 * Copyright (c) 2009,Taughannock Networks.All rights reserved. * See the README file for license conditionsand contact info. * $Header: /home/johnl/flnb/code/RCS/fb1-5.y,v2.1 2009/11/08 02:53:18 johnl Exp $ */ /* simplestversion of calculator */ %{ # include <stdio.h> %} /* declare tokens*/ %token NUMBER %token ADD SUB MULDIV ABS %token OP CP %token EOL %% calclist: /*nothing */ | calclist exp EOL { printf("= %dn>",$2); } | calclist EOL { printf("> "); }/* blank line or a comment */ ; exp: factor | exp ADD exp { $$ = $1 + $3; } | exp SUB factor { $$ = $1 - $3; } | exp ABS factor { $$ = $1 | $3; } ; factor: term | factor MUL term { $$ = $1 * $3; } | factor DIV term { $$ = $1 / $3; } ; term: NUMBER | ABS term { $$ = $2 >= 0? $2 : - $2; } | OP exp CP { $$ = $2; } ; %% main() { printf("> "); yyparse(); } yyerror(char *s) { fprintf(stderr,"error: %sn",s); }? Flex词法分析文件 fb1-5.l /* Companionsource code for "flex & bison",Taughannock Networks.All rights reserved. * See the README file for license conditionsand contact info. * $Header: /home/johnl/flnb/code/RCS/fb1-5.l,v2.1 2009/11/08 02:53:18 johnl Exp $ */ /* recognizetokens for the calculator and print them out */ %{ # include"fb1-5.tab.h" %} %% "+" { return ADD; } "-" { return SUB; } "*" { return MUL; } "/" { return DIV; } "|" { return ABS; } "(" { return OP; } ")" { return CP; } [0-9]+ { yylval = atoi(yytext); return NUMBER; } n { return EOL; } "//".* [ t] { /* ignore white space */ } . { yyerror("Mystery character%cn",*yytext); } %% 手工运行以下命令 win_bison -d fb1-5.y 生成 fb1-5.tab.h 和fb1-5.tab.c 文件 win_flex --nounistdfb1-5.l 或win_flex --wincompat fb1-5.l 生成 lex.yy.c 文件。--nounistd 和 --wincompat 选项使生成的 lex.yy.c 不依赖<unistd.h> 可以用 VC 编译,否则就只能用 gcc 编译了。 --wincompat 为 win_flex 所增加的设置选项,在 flex --nounistd (do not include <unistd.h> ) 的基础上,减少 VC 的 compile warning (uses <io.h> instead of <unistd.h> and _isatty,_fileno functions ), 另外在生成的lex.yy.c 文件中添加: /*windows compatibility case*/ #include <io.h> #define isatty _isatty #define fileno _fileno其实,也可这样解决 : warning C4013: “isatty” undefined; assuming extern returning int 在 .l 文件中包含 # include <io.h> warning C4013: “strdup” undefined; assuming extern returning int 在 .l 或 .y 文件中包含 # include <string.h> warning C4996: 'isatty': The POSIX name for this item is deprecated. Instead,use the ISO C++ conformant name: _isatty. See online help for details. warning C4996: 'fileno': The POSIX name for this item is deprecated. Instead,use the ISO C++ conformant name: _fileno. See online help for details. warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead,use the ISO C++ conformant name: _strdup. See online help for details. 在 VC 添加 _CRT_NONSTDC_NO_DEPRECATE 编译宏定义,见 http://msdn.microsoft.com/en-us/library/ms235384.aspx 说明。 为了项目管理方便可将 lex.yy.c 重命名为 fb1-5.c ,用 cl 手工编译 cl fb1-5.cfb1-5.tab.c libfl.a 或 cl fb1-5.c fb1-5.tab.c libfl.lib 生成 fb1-5.exe ,由于用到 yywrap() 需要链接 flex 的 libfl.a 库。用VC编译的话,可以将 libfl.a 重名为libfl.lib 更直观。 运行一下fb1-5.exe ? 你也可以建立一个MakeFile文件 makefile.mak # Build a Simple Calc with fb1-5.y and fb1-5.l !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CC=cl CFLAGS=/nologo /DNDEBUG /D_CRT_SECURE_NO_WARNINGS /D_CRT_NONSTDC_NO_DEPRECATE /O2 /W3 LD=link LDFLAGS=/nologo LIBS=libfl.lib MOVE=move /Y ALL : fb1-5.exe CLEAN : -@erase "*.obj" -@erase "fb1-5.c" -@erase "fb1-5.tab.c" -@erase "fb1-5.tab.h" -@erase "fb1-5.exe" OBJS= fb1-5.obj fb1-5.tab.obj "fb1-5.tab.c" : fb1-5.y if not exist "$@/$(NULL)" win_bison -d $** "fb1-5.tab.h" : fb1-5.y if not exist "$@/$(NULL)" win_bison -d $** "fb1-5.c" : fb1-5.l if not exist "$@/$(NULL)" win_flex --nounistd $** && $(MOVE) lex.yy.c $@ "fb1-5.exe" : $(OBJS) $(LD) $(LDFLAGS) /out:$@ $** $(LIBS) "fb1-5.obj" : fb1-5.c fb1-5.tab.h $(CC) $(CFLAGS) /c fb1-5.c "fb1-5.tab.obj" : fb1-5.tab.c fb1-5.tab.h $(CC) $(CFLAGS) /c fb1-5.tab.c ?用 nmake /f makefile.mak来构建。 另外一个国外图文并茂的教程为 Using flex and bison in MSVC++ http://www.di-mgt.com.au/flex_and_bison_in_msvc.html 本文就是从那演化来的。 ? libfl.a ( v2.5.37 );从 GnuWin ,Msys,Msys2 中提取 Msys2?http://sourceforge.net/projects/msys2/ 也可以从 http://pan.baidu.com/s/1eQcKMgM 下载。 不链接 libfl.a 例程可以采用以下方式: %{ # include "fb1-5.tab.h" %} %option noyywrap %% 或 提供 yywrap() 实例 int yywrap() { return 1; } 或在 flex 执行选项增加 --noyywrap 选项。 都可以不用链接 flex 提供的 libfl.a 或 libfl.lib 例程( It contains versions of main() and yywrap(). )。 细心的话,你会发现 fb1-5.l 中的 yyerror() 调用2个参数,不同于 fb1-5.y 中的 yyerror(char *s),但的确调用的是yyerror(char *s),并编译通过,并生成执行文件。 运行中输入出错时,出错信息只是输出: > error: Mystery character %c 与原设想的有出入,没有多大实用性。 这时,你可在 fb1-5.l 文件中增加 %option yylineno 选项 ,重新处理输出出错信息。 . { printf("error: Mystery character %c(line:%d)n",*yytext,yylineno); } 接下来,在 fb1-5.y 中增加正负号处理,即增加一元操作符 +,- term: NUMBER | SUB term { $$ = - $2; /* unary minus */ } | ADD term { $$ = $2; /* unary plus */ } | ABS term { $$ = $2 >= 0? $2 : - $2; } | OP exp CP { $$ = $2; } ;?同理,可以根据需要,添加想要的操作符和函数。 修改后完整的源文件如下: fb1-5.l /* Companion source code for "flex & bison",Taughannock Networks. All rights reserved. * See the README file for license conditions and contact info. * $Header: /home/johnl/flnb/code/RCS/fb1-5.l,v 2.1 2009/11/08 02:53:18 johnl Exp $ */ /* recognize tokens for the calculator and print them out */ %{ #include <io.h> # include "fb1-5.tab.h" %} %option noyywrap %option yylineno %% "+" { return ADD; } "-" { return SUB; } "*" { return MUL; } "/" { return DIV; } "|" { return ABS; } "(" { return OP; } ")" { return CP; } [0-9]+ { yylval = atoi(yytext); return NUMBER; } n { return EOL; } "//".* [ t] { /* ignore white space */ } . { printf("error: Mystery character %c(line:%d)n",yylineno); } %% fb1-5.y /* Companion source code for "flex & bison",Taughannock Networks. All rights reserved. * See the README file for license conditions and contact info. * $Header: /home/johnl/flnb/code/RCS/fb1-5.y,v 2.1 2009/11/08 02:53:18 johnl Exp $ */ /* simplest version of calculator */ %{ #include <stdio.h> void yyerror(char *s); %} /* declare tokens */ %token NUMBER %token ADD SUB MUL DIV ABS %token OP CP %token EOL %% calclist: /* nothing */ | calclist exp EOL { printf("= %dn> ",$2); } | calclist EOL { printf("> "); } /* blank line or a comment */ ; exp: factor | exp ADD exp { $$ = $1 + $3; } | exp SUB factor { $$ = $1 - $3; } | exp ABS factor { $$ = $1 | $3; } ; factor: term | factor MUL term { $$ = $1 * $3; } | factor DIV term { $$ = $1 / $3; } ; term: NUMBER | SUB term { $$ = - $2; /* unary minus */ } | ADD term { $$ = $2; /* unary plus */ } | ABS term { $$ = $2 >= 0? $2 : - $2; } | OP exp CP { $$ = $2; } ; %% int main( void ) { printf("> "); yyparse(); return 0; } void yyerror(char *s) { fprintf(stderr,s); }makefile.mak (适用于 Msys2中的 flex& bison 在 Windows + VC,修改相应 LEX,YACC? 变量,可用于 win flex-bison ) # Build a Simple Calc with fb1-5.y and fb1-5.l !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF CC=cl CFLAGS=/nologo /DNDEBUG /D_CRT_SECURE_NO_WARNINGS /O2 /W3 LD=cl LDFLAGS=/nologo /link MOVE=move /Y LEX=flex YACC=bison ALL : fb1-5.exe CLEAN : -@erase "*.obj" -@erase "fb1-5.c" -@erase "fb1-5.tab.c" -@erase "fb1-5.tab.h" -@erase "fb1-5.exe" OBJS= fb1-5.obj fb1-5.tab.obj "fb1-5.tab.c" : fb1-5.y if not exist "$@/$(NULL)" $(YACC) -d $** "fb1-5.tab.h" : fb1-5.y if not exist "$@/$(NULL)" $(YACC) -d $** "fb1-5.c" : fb1-5.l if not exist "$@/$(NULL)" $(LEX) --nounistd $** && $(MOVE) lex.yy.c $@ "fb1-5.exe" : $(OBJS) $(LD) $** $(LDFLAGS) /out:$@ "fb1-5.obj" : fb1-5.c fb1-5.tab.h $(CC) $(CFLAGS) /c fb1-5.c "fb1-5.tab.obj" : fb1-5.tab.c fb1-5.tab.h $(CC) $(CFLAGS) /c fb1-5.tab.c在 MSYS2 shell 中运行结果 ?Win flex_bison 2.5.1 在 2014.3.27 增加了?custom_build_rules 文件夹 其中 how_to_use.txt 中为 https://sourceforge.net/p/winflexbison/wiki/Visual%20Studio%20custom%20build%20rules/ "Visual Studio custom build rules" Wiki Pages These steps help you setup custom build rules for Visual Studio 2010 and up. 内容与 http://www.di-mgt.com.au/flex_and_bison_in_msvc.html 差不多,但是没有 如何增加命令参数 的步骤,令人不解! 转载本文请注明来自 http://blog.csdn.net/gocad/article/details/21866627 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |