flex&bison安装与简单使用
1.wls安装
这里使用的是wls,wls安装教程可以参考这一篇,亲测可用,安装后是自带gcc的,但是相关依赖没有,需要运行以下两个命令
1 | sudo apt-get update |
可能会遇到一些问题,可以广泛参考网上的错误解决方案~
2.安装flex bison并尝试第一个flex程序
在Ubuntu系统系统下安装flex bison,输入以下命令
1 | sudo apt-get install flex bison |
一会就装好了,然后我们尝试我们的第一个flex程序(feb1-1.l
),该程序参考flex与bison中文版第二版(可以买来看看!)
1 | %{ |
这个程序就是C代码,flex程序包含三个部分,各个部分通过%%行进行分割
- 第一部分是声明部分,%{和}%之间的代码会原样照抄到生成的C文件的开头部分,在上面的栗子中,我们使用其设定了行数、单词书与字符数的变量
- 第二部分是模式匹配部分,学习过正则表达式的同学对着肯定不会陌生(这里就不对正则表达式做详细介绍了~),每一行的开始处对应一个模式(用一个正则表达式表示),后面是当模式匹配时会执行的C语言代码(变量yytext总是被设定为指向本次匹配输入的文本)
- 第三部分是我们的主程序,它负责调用flex体用的词法分析例程yylex(),并输出结果。在没有其他改变的情况下,词法分析器将读取标准输入。
我们首先编译flex生成C程序(lex.yy.c
)
1 | flex fb-1-1.l |
然后将它与相应的flex库文件(-lfl)链接,生成a.out
1 | cc lex.yy.c -lfl |
最后运行程序
1 | ./a.out |
尝试输入以下内容:
1 | The boy stood on the burning deck |
输出为(行数、单词数、字符数)
1 | 2,12,63 |
对于flex正则表达式匹配的一些说明:
- 默认贪婪匹配(匹配更长的字符串)
- 优先匹配程序里先出现的模式
3.让Flex和Bison协同工作
我们现在需要完成一个简单的计算器
首先使用编写一个简单的flex词法分析器,不显示的定义记号值,而是直接包含头文件,因为我们希望在语法分析器中直接调用它
文件名:fb-1-5.l
1 | %{ |
然后bison程序部分,bison的规则基本上就是BNF(可参考编译原理),bison程序和flex一样分成三部分:
- 第一部分首先也是声明,会拷贝到目标程序开头,随后事%token标记声明,以便告诉bison在语法分析中的记号名称
- 第二部分就是BNF定义的规则,使用单一的冒号:表示,和flex一样,匹配每一条规则后,就会执行后面用花括号括起来的动作代码,我们一般使用动作代码维护每个语法对应的符号关联语义值,目标符号的值在动作代码中用$$表示,右边语法符号的语义值依次为$1, $2…,直到这条规则结束。记号值总是存储在yyval中,这就对应我们上面的flex程序。
- 第三部分就是主程序,运行我们的语法分析程序。
文件名:fb-1-5.y
1 | %{ |
然后联合编译flex与bison程序,由于编译的步骤比较复杂,所以我们写一个Makefile,运行vim Makefile
, 写入如下内容
1 | fb-1-5:fb-1-5.l fb-1-5.y |
然后我们编译:
1 | make |
得到程序fb-1-5,直接运行就可以了,一个简易的计算器就完成了~