课程学习 · 2022年11月24日

编译原理设计编译器lex/yacc(flex/bison)Windows配置过程

本文记录一下编译原理设计编译器lex/yacc(flex/bison)在Windows上的配置过程。

首先介绍一下,lex是词法分析器的自动产生工具,yacc是语法分析器的自动产生工具。flex是lex的“加强版”;

Bison是yacc的GNU实现,我的理解bison算就是yacc的一种吧,Bison is a general purpose parser generator that converts a grammar description for an LALR(1) context-free grammar into a C program to parse that grammar。

首先,下载MinGW,Flex,Bison
我使用的下载地址:(2022.11.24有效)
mingw https://osdn.net/frs/redir.php?m=rwthaachen&f=mingw%2F68260%2Fmingw-get-setup.exe

bison http://downloads.sourceforge.net/gnuwin32/bison-2.4.1-setup.exe

flex https://gnuwin32.sourceforge.net/downlinks/flex.php

得到这些文件:

安装MinGW
打开刚刚下载的mingw-get-setup.exe一路next。
安装完成后continue弹出这个玩意:

把gcc-g++标记一下安装:

注意,如果想用makefile,需要把上图第二行的base什么那个也装上。

Apply一下:

等一会,快慢取决于网络情况,原因你懂的。

完成之后可以看到gcc g++等等已经有了:(我的默认路径C:\MinGW

安装Flex和Bison
Flex一路next,没啥好说的。我的默认路径是C:\Program Files (x86)\GnuWin32

但是Bison注意了,我一开始用的默认路径,但是这个路径中间有空格,会出大问题:

注意!!问题来了!由于这个版本的Bison有bug,但后来没有更新的Windows上的Bison版本,所以这个古老的问题一直留着,会导致"Program Files (x86)"路径中间的空格被分开!!!

我看了一个叫做Julien Blitte的人写的文章,我十分感谢他,十分尊敬和崇拜他,他解答了我的疑惑,文章为:http://marin.jb.free.fr/bison/
这篇文章里他说:This version suffer of a bug due to a limitation of a lazy Microsoft implementation of the function _spawnvp() which does not support spaces argument.

就是说,这个路径中间有文件名,在传参的时候被当成了空格分开的多个字符串,于是安装是没问题,但使用的时候会报错:

m4: cannot open Files': No such file or directory
m4: cannot open(x86)GnuWin32/share/bison': No such file or directory
m4: cannot open C:\Program': No such file or directory
m4: cannot openFiles': No such file or directory
m4: cannot open `(x86)GnuWin32/share/bison/m4sugar/m4sugar.m4': No such file or directory

解决方法要么不要用默认的路径安装(例如用C:\bison,路径中不要有空格),要么直接用这个大佬修改Bison源码后重新编译的版本,大佬的链接网页拉到最下面有下载,直接替换安装后的那个C:\Program Files (x86)\GnuWin32\.....省略号里面的那个bison.exe
这个问题只要是我这个版本的Bison原版安装的必有这个问题,现在没问题一会用的时候也有问题。

加一下环境变量
什么是环境变量,怎么添加环境变量不在本文讨论范围之内。当然,添加环境变量这只是为了方便,如果你不想也行,每次都找到所在的目录就是了。

添加MinGW和GnuWin32的bin,如图。如果您刚才的Bison不是默认目录,也请加上。


(我是全新的虚拟机,所以环境变量很干净。

测试一下:

gcc -v
flex -V
bison -V

显示版本号不报错就行了。