词法分析与语法分析教程
flex与bison
在如下网址下载flex和bison,安装后将其bin目录配置到环境变量,在shell中能正确使用这两个命令表示配置成功。
wget https://netactuate.dl.sourceforge.net/project/gnuwin32/bison/2.4.1/bison-2.4.1-setup.exe
wget https://versaweb.dl.sourceforge.net/project/gnuwin32/flex/2.5.4a-1/flex-2.5.4a-1.exe
$ flex --version
D:\dev-tool\flex\GnuWin32\bin\flex.exe version 2.5.4
$ bison --version
bison (GNU Bison) 2.4.1
Written by Robert Corbett and Richard Stallman.
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
flex
flex所做的就是生成词法分析器,将输入分隔成有意义的单元,然后找出这些单元之间的关系。
通过编写特定的代码,在使用flex编译之后,就可以生成词法分析器的C程序。
flex 实例
- 编写flex文件
/* number.flex */
%{
#include <stdio.h>
%}
%%
([1-9]+[0-9]*)|[0] ECHO;
[0-9]+\.[0-9]+
[a-zA-Z]+
.
%%
int main(int argc, char **argv)
{
yylex();
yywrap();
}
int yywrap()
{
return 1;
}
- 使用flex将.l文件编译为.c文件
flex .\number.l
D:\code\blog\code\flex_bison_test> ls
目录: D:\code\blog\code\flex_bison_test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/8/15 16:24 37876 lex.yy.c
-a---- 2023/8/15 16:24 217 number.l
- 使用gcc编译:
D:\code\blog\code\flex_bison_test> gcc .\lex.yy.c -o number
PS D:\code\blog\code\flex_bison_test> ls
目录: D:\code\blog\code\flex_bison_test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/8/15 16:26 37876 lex.yy.c
-a---- 2023/8/15 16:27 62193 number.exe
-a---- 2023/8/15 16:24 217 number.l
- 运行(输入字符串后回车会把数字打印出来)
D:\code\blog\code\flex_bison_test> .\number.exe
a=23
23
test1
1
bbhhvvg
233456
233456
- ctrl-c退出运行
flex语法规则
定义(definations)
%%
规则(rules)
%%
代码(user code)
flex的代码分为三个部分,由%%分割,这些部分可以为空,但为了让flex代码能够按照我们此前介绍的方法成功编译,需要加入部分内容,形成下方的新手框架:
%{
%}
%%
%%
int main(int argc, char **argv)
{
yylex()
return 0;
}
int yywrap()
{
return 1;
}
1. %{ %},
这对大括号内没有任何内容,所以目前起不到任何作用。加入这对大括号的目的是,在这个部分可以使用C语言代码进行预处理,例如使用#include<stdio.h>
,或是定义宏、常量等等
2. 这里要写入的代码是重点内容
3. 用来写C语言代码的,因此不需要使用%{%}
括号对。在这里,我们添加了两个函数。
- flex代码要先编译为C代码,显然需要一个main函数,所以需要我们手写一个main函数,这就是第一个函数的由来。
yylex()
函数,其实会由第二部分我们写入的匹配规则自动生成,也就是说,它其实就是由lex产生的词法分析程序,当我们调用它时,才会正式开始词法分析。- yywarp函数,这是一个约束函数,当它返回1时,代表扫描结束,此时结束程序。