跳到主要内容

词法分析与语法分析教程

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时,代表扫描结束,此时结束程序。

reference

  1. https://blog.csdn.net/weixin_44007632/article/details/108666375