背景知识

在学编译原理的时候,同时在做南京大学的编译原理课程实验,这里是链接,整个实验的效果是实现一个完整的 C-- 语法的编译器。C-- 语法是他们老师指定的一种类 C 语言。

Flex 和 Bison 是两个在编译前期最常实验的工具,分别是用来做 lexical analyse 和 semantic analyse 的,这两个工具的使用基本不需要很深的编译知识,只需要掌握正则表达式的书写(lexical analyse阶段使用)和上下文无关文法(semantic analyse 阶段使用),就可以完成这两个阶段的分析了。

Flex大体介绍

Flex 主要是用在词法分析阶段,不需要我们去手写分析器,只需要制定好相应的正则表达式规则,他可以自动对输入文件进行词法分析。

Flex 主要在 Linux 系统下工作,安装方式也很简单。

sudo apt-get install flex

安装好 flex 之后,我们创建一个 .l 后缀的文件,这个文件里面主要由三部分组成,定义了词法分析的规则,整个文件的结构如下。

definitions
%%
rules
%%
user subroutines

在编写好文件后,可以使用命令 flex file.l 进行编译,编译之后,我们会得到一个名为 file.yy.c 的文件,这个文件代码中,我们只需要使用里面的 yylex() 函数,这个函数可以读入文件中的一个词法单元,然后进行规则匹配,即词法分析。

我们可以在外部定义一个自己的 main() 进行调用,可也以在第三部分 {user subroutines} 中书写 main() 函数进行调用。便于文件的组织,这里我们使用外部文件的方式定义一个新的主函数。

主要的代码框架如下

extern File* yyin;
int main(int argc, char ** args) {
if (argc > 1) {
if( ! (yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return 1;
}
}
while(yylex()!= 0);
return 0;
}

这个 yyin 可以理解成输入文件的文件指针,用来读取文件,在 file.yy.c 中定义。

然后我们进行整体的编译

gcc main.c file.yy.c -lfl -o scanner

-lfl 参数是指定一个库函数,对于 MacOS 用户,可以使用 -ll 参数进行代替。

这样之后,对某个文件进行词法分析就可以直接运行 ./scanner test.cmm 了。

Flex 规则部分

我们需要注意的是对 Flex 中的规则的编写,整个 FLex 文件分别由三个部分,第一个部分通常定义一些之后常用的正则表达式,可以简化书写,定义格式为:

name definition

defintion 是一个具体的正则表达式,而 name 是其别名,比如,如果想定义一个识别任意数字的正则表达式,可以这样定义

digit [0-9]

这个 digit 就是这个正则表达式的别名,和这个正则表达式的效果一样,会和任意一个数字进行匹配。

第二部分是规则部分,即针对每一个特定的语法单元,我们对其有什么样的操作。定义格式为

pattern {action}

这个pattern 和我们上面的一样,都是正则表达式,而对应的 action 则指定了如果遇到了这个 pattern 之后,我们的应对方法。这个 pattern 我们可以重新定义,也可以直接使用在第一部分定义好的对应的 name,如果使用 name,则格式为 {name}。针对一些没有匹配任何规则的词法元素,我们可以使用 . 这个 pattern 指定对应的动作。

第三部分是用户自定义的代码部分,而这部分定义的方法,函数,都应该在第一部分中进行声明,声明格式为

%{

%}

这样,声明后的变量,函数和自定义的代码片段都会在 file.yy.c 中生成,方便我们调用。

完成了这三个部分后,我们就可以生成一个简单的语法分析器了。下面给出一个使用 flex 进行单词统计的完整文件。

%{
int chars = 0;
int words = 0;
int lines = 0;
%}
letter [a-zA-Z]
%%
{letter}+ {words ++; chars += yyleng; }
\n {chars++; lines ++;}
. {chars++;}
%%
int main(int argc, char** argv) {
if (argc > 1) {
if (!(yyin = fopen(argv[1], "r"))) {
perror(argv[1]);
return 1;
}
}
yylex();
printf("lines are %d words are %d chars are %d\n", lines, words, chars);
return 0;
}

这里的 yyleng 是 flex 内置提供的变量,记录当前单词的长度。

这样,整个词法分析的过程就结束了,我们可以输入对应的词法流,在语法分析阶段进行下一步的分析。而语法分析所用的工具,就是 bison。

Flex 和 Bison 使用方法的更多相关文章

  1. 在windows下安装flex和bison

    学习Stellar-core 需要依赖项flex .bison .gcc三个依赖项 下载得网址:链接: https://pan.baidu.com/s/1mitCLcs 密码: 3jaj   通过 w ...

  2. 在windows下安装flex和bison、GCC

    学习Stellar-core 需要依赖项flex .bison .gcc三个依赖项 下载得网址:链接: https://pan.baidu.com/s/1mitCLcs 密码: 3jaj   通过 w ...

  3. Flex内存泄露解决方法和内存释放优化原则

    Flex内存泄露解决方法和内存释放优化原则 你对Flex内存泄露的概念是否了解,这里和大家分享一下Flex内存释放优化原则和Flex内存泄露解决方法,希望本文的介绍能让你有所收获. Flex内存释放优 ...

  4. flex and bison学习笔记01

    工作需要,学习一下Flex and bison,以前在编译原理的课上听老师说过他们的前辈,lex and yacc.Flex and bison就是lex and yacc的升级版. 参考书:flex ...

  5. flex与bison

    flex与bison 中文版 目录: 第一章:flex和bison简介 第二章:使用flex 第三章:使用bison 第四章:分析sql 第五章:flex规范参考 第六章:bison规范参考 第七章: ...

  6. flex 和bison的安装和使用

    1.在ubutu上安装 yacc的命令: sudo apt-get install flex bison flex:词法分析器 flex是一个词法分析器.用来将一个.l文件生成一个.c程序文件.即生成 ...

  7. win7下面安装flex和bison

    通过Cygwin工具进行安装 下载地址cygwin 安装截图: 搜索flex,选择相应的版本进行安装 搜索bison 然后下一步 安装完成后,将D:\cygwin64\bin路径添加到PATH环境变量 ...

  8. 使用flex和bison实现的sql引擎解析

    因为老师要求,近期在做oceanbase存储过程的实现,在oceanbase 0.4曾经是不支持存储过程的.实现的主要步骤主要包含 1.语法解析 2.词法解析 3.详细运行语法树的步骤 如今先来说说语 ...

  9. flex与bison的学习

    获取bison http://www.gnu.org/software/bison 获取flex http://flex.sourceforge.net/ 本书的范例 ftp://ftp.iecc.c ...

随机推荐

  1. ABP vNext 不使用工作单元为什么会抛出异常

    一.问题 该问题经常出现在 ABP vNext 框架当中,要复现该问题十分简单,只需要你注入一个 IRepository<T,TKey> 仓储,在任意一个地方调用 IRepository& ...

  2. ELK 学习笔记之 Kibana安装

    Kibana安装: 安装地址: https://www.elastic.co/downloads/kibana 安装: tar -zxvf kibana-5.6.1-linux-x86_64.tar. ...

  3. MySQL 数据库删除表中重复数据

    采集数据的时候,由于先期对页面结构的分析不完善,导致采漏了一部分数据.完善代码之后重新运行 Scrapy,又采集了一些重复的数据,搜了下删除重复数据的方法. N.B. 删除数据表的重复数据时,请先备份 ...

  4. Node.js入门教程 第三篇 (模块及路由)

    Node.js的模块 Node.js的模块与传统面向对象的类(class)不完全相同.Node.js认为文件即模块,即一个文件是一个模块.单一文件一般只专注做一件事情,保证了代码的简洁性. 创建模块: ...

  5. python编程基础之十五

    二维列表 l1 = [[1, 2, 3], [4, 5, 6]] print(l1[0][0]) 列表负值 列表复制为两种:深复制,浅复制 浅复制:只复制容器,容器里的元素不产生副本,只是技术引用增加 ...

  6. 最强最全的Java后端知识体系

    目录 最全的Java后端知识体系 Java基础 算法和数据结构 Spring相关 数据库相关 方法论 工具清单 文档 @(最强最全的Java后端知识体系) 最全的Java后端知识体系 最全的Java后 ...

  7. 爬虫破解知乎登入(不使用Selenium模块)

    一.分析 知乎完成登入的步骤 首先获得cookies(如果不获得后面验证码无法获得) 获得验证码 提交登入相关内容 前两步简单稍微细心寻找规律即可 其中最难的是第三步应该他前端进行了js加密 这里没什 ...

  8. postman环境变量设置

    1.点击小齿轮进入到环境变量添加页面,点击add添加环境变量 2.输入变量名称和变量值 3.添加成功 4.接口中设置变量

  9. Python3之多线程学习

    这里做一个自己复习多线程的笔记 Python中使用线程有两种方式:函数或者用类来包装线程对象. 函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程.语法如下: ...

  10. opencv::Brisk检测与匹配

    Brisk(Binary Robust Invariant Scalable Keypoints)特征介绍 构建尺度空间 特征点检测 FAST9-16寻找特征点 特征点定位 关键点描述子