简述

Flex是重写Lex诞生的快速词法分析生成器,在编译前端(词法分析->语法分析->语义分析)中处在最靠前的位置,它可以用来生成特定的词法分析程序。

安装Flex:

apt-get install flex

没有专用于Flex的IDE,可以在VSCode安装Lex Flex Yacc Bison插件,可以让Flex语法高亮。

Flex使用示例

Flex程序通常写成.l文件,其中由两个%%分成上中下三部分,第一部分是声明和选项设置(编译后被原样写入生成的词法分析程序最顶端),第二部分是正则表达式模式和相应Action,第三部分主程序中是一些与Action相关的例程(也会被照抄)。

第一部分如果不需要就不用写。第三部分如果不写,Flex会提供一个最小的调用词法分析器的主程序。

核心就在第二部分,因为一个正则表达式可以对应一个有限自动机,Flex就是将正则表达式翻译成DFA,然后在DFA转移时执行相应的Action完成处理。

如课本上的统计行数、单词数、字符数的Flex程序:

%{int chars = 0; //用于记录字符数int words = 0; //用于记录单词数int lines = 0; //用于记录行数
%}%% //分割第一部分和第二部分[^ \t\n\r\f\v]+ { words++; chars+=strlen(yytext); } //匹配到单词(没有空白符的连续串)时,单词数+1,字符数+=单词长度
\n              { chars++; lines++; } //匹配到换行符时,字符数+1,行数+1
.               { chars++; } //匹配到其它任何字符,只增加字符数%% //分割第二部分和第三部分//主函数
int main(int argc, char **argv)
{yylex(); //调用Flex提供的词法分析例程yylex()printf("%8d%8d%8d\n", lines, words, chars); //输出统计结果
}

使用flex命令对其翻译:

flex WordCount.l

在同一目录下生成了近1800的C语言程序lex.yy.c,这就是Flex生成的程序,只不过这个例子不是词法分析目的。将这个程序用gcc(或者Unix的cc)编译:

gcc lex.yy.c -lfl

其中-lfl参数用于链接flex的库函数。编译后在目录下生成了a.out,直接执行就可以使用这个程序了,输入可换行的文本并最终Ctrl+D(这是Unix/Linux下的换行符)结束输入:

lzh@DESKTOP-HCSIG2E:/mnt/e/Compiler/flex$ ./a.out
I am sb lzh.
I like cute cat, and i wanna eat foods.
That's all, bye!3      16      70

这表示,输入的文本有3行,16个单词("That’s"整个视为一个单词),70个字符。

Flex生成词法分析程序

这里按照课本上的案例,做一个整数的四则运算器。

Flex在这里生成词法分析程序,词法分析程序会识别输入的单词,然后将分析结果输出。

%%"+"     { printf("PLUS\n"); }
"-"     { printf("MINUS\n"); }
"*"     { printf("TIMES\n"); }
"/"     { printf("DIVIDE\n"); }
"|"     { printf("ABS\n"); }
[0-9]+  { printf("NUMBER %s\n", yytext); } //数字
\n      { printf("NEWLINE\n"); }
[ \t]   { } //忽略空白符
.       { printf("Mystery charactor %s\n", yytext); } //其它字符是不合法的,提示错误%%

翻译,编译,运行:

lzh@DESKTOP-HCSIG2E:/mnt/e/Compiler/flex$ ./a.out
2019+11-30/2
NUMBER 2019
PLUS
NUMBER 11
MINUS
NUMBER 30
DIVIDE
NUMBER 2
NEWLINE
77 + 8 8 | abc
NUMBER 77
PLUS
NUMBER 8
NUMBER 8
ABS
Mystery charactor a
Mystery charactor b
Mystery charactor c
NEWLINE

改进的词法分析程序

一般为模式匹配的Action中设置返回值(而不是像前面那样直接print),这样yylex()每次识别到相应的模式,如果有返回值,就立即返回,然后继续调用yylex()识别下一个模式;如果是没有返回值的模式,就会继续向后识别。

另外,还可以设置记号编号记号值。记号编号用于记录词的类别,而记号的值则用于记录此类别的某个具体值。例如记号编号可以是NUMBER,然后记号值取10,就表示了整型常量10。

Bison创建的语法分析器自动从258开始指派记号编号,这是为了防止和文字字符冲突。Flex里为了和Bison统一,也不妨从258开始编号。

记号的值为了能给不同的类型使用,通常使用union类型。不过这个例子里因为只有数字需要有记号值,所以直接就用int类型。

%{//记号编号enum yytokentype{NUMBER = 258,ADD = 259,SUB = 260,MUL = 261,DIV = 262,ABS = 263,EOL = 264};//存储记号值int yylval;
%}%%"+"     { return ADD; }
"-"     { return SUB; }
"*"     { return MUL; }
"/"     { return DIV; }
"|"     { return ABS; }
[0-9]+  { yylval = atoi(yytext); return NUMBER; } //匹配到数字时,将其转为int写入记号值的变量中
\n      { return EOL; }
[ \t]   { } //忽略空白符
.       { printf("Mystery charactor %c\n", *yytext); } //其它字符是不合法的,提示错误%%int main(int argc, char **argv) {int tok;while(tok=yylex()) { //每次从记号流中匹配出一个记号编号printf("%d", tok);if(tok==NUMBER) //如果是数字,还需要输出记号值printf(" = %d\n", yylval);elseprintf("\n");}return 0;
}

翻译,编译,运行:

lzh@DESKTOP-HCSIG2E:/mnt/e/Compiler/flex$ ./a.out
2019+11-30/2
258 = 2019
259
258 = 11
260
258 = 30
262
258 = 2
264

【Flex学习笔记】1:生成简易的词法分析程序相关推荐

  1. Flex学习笔记(零)

    推荐Flex的初学者学习Adobe官方提供的Flex in a Weekvideo series, Flex 4.5.这一系列教程虽然是英文视频,但是Adobe很贴心地给出了pdf格式的视频内容和源代 ...

  2. Flash/Flex学习笔记(30):不用startDrag和stopDrag的对象拖动

    对于从Sprite类继承来的对象,要实现拖放当然是Flash/Flex学习笔记(13):对象拖动(startDrag/stopDrag) 里讲的方法最方便,但是对于不是从Sprite类继承得来的对象, ...

  3. Flash/Flex学习笔记(51):3维旋转与透视变换(PerspectiveProjection)

    Flash/Flex学习笔记(49):3D基础 里已经介绍了3D透视的基本原理,不过如果每次都要利用象该文中那样写一堆代码,估计很多人不喜欢,事实上AS3的DisplayObject类已经内置了z坐标 ...

  4. Spring学习笔记:第一个Spring Boot程序HelloWorld

    Spring学习笔记:第一个Spring Boot程序HelloWorld 一.跟着 Spring 了解技术趋势 1.看看 Spring 5.x 的改变暗示了什么 2.Spring Boot 和 Sp ...

  5. 【Bison学习笔记】1:生成简易的语法分析程序,使Bsion和Flex协同工作

    简述 Bison是在Yacc上改写并添加了大量特性后诞生的语法分析生成器,在编译前端(词法分析->语法分析->语义分析)中处在中间的位置,它可以用来生成特定的语法分析程序. 安装Bison ...

  6. 【TensorFlow-windows】学习笔记七——生成对抗网络

    前言 既然学习了变分自编码(VAE),那也必须来一波生成对抗网络(GAN). 国际惯例,参考网址: 论文: Generative Adversarial Nets PPT:Generative Adv ...

  7. Flex学习笔记(1)——入门,HelloFlex

    稍微有些资历的Web程序员想必都还记得Macromedia这个公司吧,想当初网页编程三剑客:Dreamweaver.Flash.Fireworks是多么的红火,可惜现在Macromedia已经是一个过 ...

  8. 【java学习笔记day01】运行第一个程序Helloworld!

    java学习笔记day01 2.什么是软件工程师? 3.什么是软件? 4.开发软件需要计算机编程语言,计算机编程语言有很多,例如 c, c++,Java,NET,c#,php... 5.Java软件工 ...

  9. Java学习笔记(二):Java程序基础

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://mp.csdn.net/mdeditor/100619398 目录 ...

最新文章

  1. 多个表关联的查询语句
  2. openmv集成应用_使用OpenMV引导无人机飞行
  3. 单片机控制两个步进电机画圆_51单片机控制两个步进电机
  4. 数据结构与算法(6) -- heap
  5. mysql优化varchar索引_MySQL优化--概述以及索引优化分析
  6. Linux查看centos版本 - 命令篇
  7. 这些Python代码技巧,你肯定还不知道
  8. SpringBoot配置ELK环境
  9. 优先队列重载(理解)
  10. 干活,分享!!三套简单有趣的后台登录页面模板分享
  11. 新浪微博平台的多级架构
  12. html 点击方块旋转,前端每日实战:86# 视频演示如何用纯 CSS 创作一个方块旋转动画...
  13. leshan基于OMALightweight M2M(LwM2M)协议的Java实现(入门)
  14. bash xx.sh与sh xx.sh以及./xx.sh的区别
  15. 解决日志打印过多问题
  16. 线程中的同步和异步的区别
  17. 李永乐(七)向量组的秩、矩阵的秩——笔记
  18. JS实现最美的3D宇宙效果
  19. 开源轻量级显示框架LVGL简介
  20. 事业单位资产管理系统功能优势?加强资产日常监管,杜绝资产流失

热门文章

  1. 读取图片并转为numpy数组
  2. zynq 实现液晶显示器显示(ADV7511)
  3. 【电气专业知识问答】问:高压断路器失灵保护的工作原理是什么?
  4. MyBatisPlus大于等于、小于等于等等函数
  5. c语言编程温度传感器代码,单片机控制的温度传感器C语言程序代码(WORD档).doc
  6. 给一个培训还是自学的理由
  7. viewpager+fragment 懒加载
  8. TRACE32 Simulator License
  9. 没GPU也能玩梵高作画:Ubuntu tensorflow CPU版
  10. 海尔智家的“科创土壤”和“人才密码”