我是靠谱客的博主 老迟到超短裙,最近开发中收集的这篇文章主要介绍Win flex-bison 的简单使用,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Win flex-bison 的简单使用

学习编译原理的朋友,都会看到书中提到的 lex & yaccflex & bison 工具组合。这两组工具在 Unix, Linux, BSD 上使用不会有太大的问题,但在 Windows 上使用通常需要安装 MinGW+ (Msys GnuWin 或Msys2 ) 或者CygwinWin 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

Description

Win 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.

UPDATE1: Bison version 3.0 available in Files section in win_flex_bison-2.5.zippackage.

UPDATE2: Now "winflexbison" available as package in Chocolatey (http://chocolatey.org/packages/winflexbison)

Win flex-bison WebSite

Categories

Libraries

License

GNUGeneral 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", 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.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 编译了。

--wincompatwin_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 例程可以采用以下方式:

你可以在 fb1-5.l 文件中增加 %option noyywrap 选项 

%{
# 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", 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 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", *yytext, yylineno); }
%%

fb1-5.y

/* Companion source 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 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, "error: %sn", 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


最后

以上就是老迟到超短裙为你收集整理的Win flex-bison 的简单使用的全部内容,希望文章能够帮你解决Win flex-bison 的简单使用所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部