【编译原理】flex实现词法分析器

2023-11-03

flex自动实现词法分析器

FLEX 与 BISON 的使用

FLEX介绍

Flex是一个生成词法分析器的工具,它可以利用正则表达式来生成匹配相应字符串的C语言代码,其语法格式基本同Lex相同。

单词的描述称为模式(Lexical Pattern),模式一般用正规表达式进行精确描述。FLEX通过读取一个有规定格式的文本文件,输出一个C语言源程序。

FLEX的输入文件称为LEX源文件,它内含正规表达式和对相应模式处理的C语言代码。LEX源文件的扩展名习惯上用.l表示。FLEX通过对源文件的扫描自动生成相应的词法分析函数int yylex(),并将之输出到名规定为lex.yy.c的文件中。实用时,可将其改名为lexyy.c。- - - 百度百科

fex的输入是文件或输入设备,这些输入中的信息以正则表达式和C代码的形式组成,这些形式被称为规则(rule);
当可执行文件被执行时,其分析输入中可能存在的符合规则的内容,当找到任何一个正则表达式相匹配内容时,相应的C代码将被执行。
fex的输入文件由3段组成,用一行中只有%%来分隔;

定义: definition
%%
规则: rules
%%
用户代码:code

定义部分
其中定义有变量声明,正则表达式声明;

%{
	int a;
	int b;
%}
  • 正则表达式声明方式:

表达式名称 表达式

在使用时需要将表达式名称用{}括起来;

  • 规则部分

一个规则一行
正则表达式{动作函数}
动作函数可以调用在用户代码中定义的
下面有小例子

下载安装

下载地址:https://sourceforge.net/projects/winflexbison/
下载好后,解压到任意目录下都可以的。解压后:
在这里插入图片描述

操作例子

1、在减压的目录下创建一个以.l结尾的文件我这里创建的是lex.l,使用记事本打开文件(当然也可以使用别的了),编辑。在这里,就使用简单例子简洁说明一下:

%{
	#include<stdio.h>
	#include<stdlib.h>
	int line=1;
%}

DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*

%%
\n {++line;}
{DIGIT} {printf("line%d:(integer, %s)\n",line,yytext);} 
{OINTEGER} {printf("line%d:(integer, %s)\n",line,yytext);} 
. {}
[ \t]+ {}

%%
int main(){
	yyin=fopen("F:/data.txt","r");
	yylex();
	return 0;
}
int yywrap(){
	return 1;
}

2、在绝对路径下创建data文件,这里是F盘下(fopen("F:/data.txt","r")),编辑文件:

13 14 520

3、在项目目录下,DOS 命令提示符下(cmd)。执行win_flex ‐‐nounistd lex.l(lex.l为你的项目名),执行成功会生成一个lex.yy.c文件。
在这里插入图片描述
对C程序进行编译运行:
在这里插入图片描述

词法分析器

首先写正则表达式
例如:

单位整数:DIGIT [0-9]
整数:OINTEGER [1-9]{DIGIT}*

因此,需要根据各词的特征将正则表达式写出来。

  • lex.l
%{
	#include<stdio.h>
	#include<stdlib.h>
	#include<string.h>
	int line=1;
%}
LETTER [a-zA-Z]
ID ({LETTER}|_)({LETTER}|_|{DIGIT})* 
OPT ("+"|"-"|"*"|"/"|"+="|"-="|"*="|"/="|">="|"<="|"=="|">"|"<"|"="|"++"|"--") 
BRACKET ("("|")"|"["|"]"|"{"|"}"|";"|","|"\'"|"\""|"#") 
DIGIT [0-9]
OINTEGER [1-9]{DIGIT}*
INTEGER ("+"|"-")?{OINTEGER}
DECIMAL {INTEGER}(.{OINTEGER})
FLOAT ([0-9])*+[.]([0-9])*+[Ee]([+-]?[0-9]([0-9])*|[0])
ERROEFLOAT ([0-9])*+[.](0-9)*+("E"|"e")
TYPE void|int|double|char
KEYWORD if|else|do|while|for|scanf|printf|sqrt|abs|main|return|float
TYPEIDENTIFY %d|%c|%s|%f|&{ID}
SGPS \/\/.*
DBPS \/\*(.|\n)*\*\/ 

%%
\n {++line;}
{TYPE} {printf("line%d:(type, %s)\n",line,yytext);}
{KEYWORD} {printf("line%d:(keyword, %s)\n",line,yytext);}
{DIGIT} {printf("line%d:(integer, %s)\n",line,yytext);} 
{OINTEGER} {printf("line%d:(integer, %s)\n",line,yytext);} 
{ID} {printf("line%d:(identify, %s)\n",line,yytext);} 
{BRACKET} {printf("line%d:(bracket, %s)\n",line,yytext);} 
{OPT} {printf("line%d:(OPT, %s)\n",line,yytext);}
{INTEGER} {printf("line%d:(integer, %s)\n",line,yytext);}
{DECIMAL} {printf("line%d:(decimal, %s)\n",line,yytext);}
{FLOAT} {printf("line%d:(float, %s)\n",line,yytext);}
{TYPEIDENTIFY} {printf("line%d:(typeidentify, %s)\n",line,yytext);}
{ERROEFLOAT} {printf("ERROEFLOAT\n");}
({SGPS}|{DBPS}) {}
. {}
[ \t]+ {}

%%
int main(){
	yyin=fopen("F:/data.txt","r");
	yylex();
	return 0;
}
int yywrap(){
	return 1;
}

  • 第一个测试样例:data.txt
int main(){

    int a = 10;

    double b = -20.9;

    if(a<=b)        

    a+=b;

    return a;
}

在这里插入图片描述

  • 第二个测试样例:data.txt
int main(){
    int a = 10;
    double b = -20.9;
    float c=1.2E-3;
    if(a<=b)        
    	a+=b;
    return a;
}

在这里插入图片描述

  • 第三个测试样例:data.txt
int main(){
    int a = 10;
    double b = -20.9;
    float c=1.2E3;
    printf("%d",&a);
    return a;
}

在这里插入图片描述
特别提醒:如果需要处理错误情况(如:浮点数错误,符号错误),依然是写出错误情况的正则表达式,进行匹配。需要像报错那样,只输出错误情况,而且在错误之前的语句也不输出,需要把输出存储起来,然后判断是否有错误,有错,则输出错误,否则按照正常输出。

参考文献

编译原理(龙书)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【编译原理】flex实现词法分析器 的相关文章

  • safari浏览器中使用flex布局出现图片拉伸显示图片原始宽高

    在safari浏览器中使用flex布局出现图片拉伸的情况 一般设置图片宽度 图片高度会根据图片宽高比 高度自动伸缩进行调整 解决方案 1 在使用了flex的情况下 设置图片定宽定高 2 去掉flex 布局 图片设为display inlin
  • 简单的递归下降语法分析程序

    简单递归分析程序 其代码如下 include
  • 编译原理基础知识+笔记(1)

    一 编译原理概述 1 翻译程序 把某一种语言程序 称为源语言程序 等价地转换成另一种语言程序 称为目标语言程序 的程序 2 编译程序 把某一种高级语言程序等价地转换成另一种低级语言程序 如汇编语言或机器语言程序 的程序 又分为 诊断编译程序
  • 编译原理 实验四 LR(1)分析法程序

    源代码仓库 CompilePrincipleLearning experiment 4 yusixian CompilePrincipleLearning github com 源代码在demo文件夹中 一 实验目的 掌握LR 1 分析法的
  • YACC工具ParserGenerator的下载和配置过程

    工具准备 parser generator http www bumblebeesoftware com downloads htm VC6 0 网上到处都是 1 parser generator的环境设置 安装好parser genera
  • GDB 程序调试常用命令

    调试之前 若要在GDB中调试程序在编译时需要加上调试信息 在GCC中添加的方法 GCC g a c o a exe 或下面提供更符合GDB的调试信息 GCC ggdb a c o a exe 运行流程 命令 作用 start 开始执行程序
  • PL0语言出错编号表

    Notes 编译原理第 3 版的书貌似没有这个表 做实验和写课设的时候很不方便 把别人拍的第 2 版书上的这个表在这备份一份 Error Code Table 出错编号 出错原因 1 常数说明中的 写成 2 常数说明中的 后应是数字 3 常
  • LLVM SSA 介绍

    最近做研究碰到了一个难题 需要对程序变量按生命期进行重命名 考虑到 SSA 中一个变量在不同的程序分支中赋值时会进行重命名 因此打算以此作为参考 看看能否采取同样的方法达到目的 由于之前看到的文档中都说 LLVM IR 是 SSA 形式的
  • The Backus-Naur Form (BNF) & The Extended Backus-Naur Form (EBNF)

    The Backus Naur Form BNF The Backus Naur Form BNF is a notation used for formal description of the syntax of programming
  • 编译原理实验二:Bison

    编译原理实验二 Bison 实验要求 1 了解Bision基础知识 如何将文法产生式转换为Bison语句 2 阅读 src common SyntaxTree c 对应头文件 include SyntaxTree h 理解分析树生成的过程
  • 合肥工业大学编译原理实验一词法分析

    基本思路 词法分析是对输入语句串中一个个单词符号进行分析 最后格式化输出种别码 类型 位置等信息 那么 就可以考虑一次读入一个字符将它们拼接成一个字符串 当碰到空格或者分界符 时 就把前面已读的字符串格式化输出 再输出当前分界符 然后再往后
  • OCaml 安装以及简单的加减乘除Demo(以Ubuntu16.04为例)

    安装nix 参考 https mirrors tuna tsinghua edu cn help nix 安装nix sh lt curl https mirrors tuna tsinghua edu cn nix latest inst
  • 语法分析—自上而下分析

    1 美图 2 位置 语法分析器的功能 语法分析的任务是分析一个文法的句子结构 语法分析器的功能 按照文法的产生式 语言的语法规则 识别输入符号串是否为一个句子 合式程序 语法分析的方法 不行 看不懂 我太难了 不看了
  • 编译原理——自顶向下分析中FOLLOW集的计算

    一 FOLLOW集的定义 对于非终结符号A FOLLOW A 被定义为 可能在某些句型中紧跟在A右边的终结符号的集合 为什么说是可能 因为在一些推导出来的文法符号串中 该非终结符号A可能在最右边 比如 A gt TA 如果存在S gt Aa
  • 编译原理-总概

    语言执行过程 代码 解释器编译器 机器代码 cpu执行 编译型语言 在程序在执行之前需要一个专门的编译过程 通过编译器把程序编译成为可执行文件 再由机器运行这个文件 运行时不需要重新翻译 直接使用编译的结果就行了 解释型语言 是一边执行一边
  • 在Vue中使用flex布局 echarts多图标不能自适应缩放问题

    前言 最近有个项目需要用到echarts绘制多个图表 需求是要支持大屏展示 还有需要支持不同比例的缩放和任意手动缩放 因此 深入学习了echarts和flex布局 虽然遇到很多问题 但都一一解决了收获良多 故此写下遇到的问题与坑 与之共勉
  • 语义分析- 符号表

    符号表 1 用来存储程序中的变量相关信息 类型 作用域 访问控制信息 2 必须非常高效 程序中的变量规模会很大 符号表的接口 ifndef TABLE H define TABLE H typedef Table t 数据结构 新建一个符号
  • TextSymbol使用方法

    private var grapbiaozhu GraphicsLayer new GraphicsLayer grapbiaozhu clear map addLayer grapbiaozhu var gra Graphic new G
  • 自下而上分析方法-算符优先,LR(0),SLR,LR(1),LALR大全

    文章目录 自下而上分析法 一 规范规约 相关定义 短语 直接短语 句柄 素短语 最左素短语 语法树表示 示例 规范规约 二 语法分析器 三 算符优先分析算法 算符文法 1 算符优先文法 2 FIRSTVT P 和LASTVT P 1 FIR
  • Go 程序编译过程(基于 Go1.21)

    版本说明 Go 1 21 官方文档 Go 语言官方文档详细阐述了 Go 语言编译器的具体执行过程 Go1 21 版本可以看这个 https github com golang go tree release branch go1 21 sr

随机推荐

  • C语言中字符数组只能存放字符串?字符数组和字符串的唯一区别?

    C语言中字符数组只能存放字符串 不是的 C语言中字符数组既可以保存字符 又可以保存字符串 字符数组本意就是是指用来存放字符数据的数组 字符数组的元素是字符类型的 字符数组用于存放字符或字符串 C语言中字符数组的一般形式为 char 数组名
  • 形容词变副词

    1 辅音 y 改y为i ly happy happily y发ai音直接加ly dry dryly 2 元音 e 去e ly ture turly due duly nice nicely wise wisely 3 le去e y poss
  • 笔试

    文章目录 前言 38 FIFO的深度计算问题 1 情况1 fa gt fb 且在读和写中都没有空闲周期 2 情况2 fa gt fb 两个连续的读写之间有一个时钟周期延迟 3 情况3 fa gt fb 在读和写中都有空闲周期 4 情况4 f
  • 以字符串形式读取github上.json文件

    如下 https github com hpu spring87 ebooks blob master update json 如果直接用httpclient读取该URL地址 得到结果是这样的
  • Java JFrame常用的布局

    setLayout 布局对象 声明布局格式的方式 如 setLayout new FlowLayout 1 FlowLayout布局 FlowLayout布局是JPanel 的默认布局 组建按照加入的先后顺序从左到右排列 一行排满之后就转到
  • 二进制应用

    一 什么是二进制 逢二进一的计数规则 规律 数字 0 1 进位基权 2 权 8 4 2 1 基数的幂次 二 为什么要用二进制 成本最优的解决方案 三 如何用二进制 3 1二进制与十进制的转换 3 1 1 十进制转二进制 方法为 十进制数除2
  • 写之前的项目关于使用git remote -v 找不到项目地址的解决方案

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一 报错解析 1 报错内容 2 报错翻译 3 报错解析 1 使用git branch来查看git仓库有几个分支 2 使用git remote v 3 查看根目录的g
  • Wireshark 实验

    Wireshark 实验 Wireshark 实验 数据链路层 实作一 熟悉 Ethernet 帧结构 实作二 了解子网内 外通信时的 MAC 地址 实作三 掌握 ARP 解析过程 网络层 实作一 熟悉 IP 包结构 实作二 IP 包的分段
  • matlab arma 仿真,基于Matlab的ARMA模型时间序列分析法仿真

    自适应滤波器设计等等 基于Matlab的ARMA模型时间序列分析法仿真 ARMA模型时间序列分析法简称为时序分析法 是一种利用参数模型对有序随机振动响应数据进行处理 从而进行模态参数识别的方法 参数模型包括AR自回归模型 MA滑动平均模型和
  • llvm编译linux,在Linux上编译LLVM/Clang 8.0.0等全部源代码

    本教程使用的操作系统是Ubuntu Linux 18 04 2 LTS版本 编译器是GCC 6 5 0 不用新版的原因是某些代码不支持更高的版本 要编译的LLVM源代码是8 0 0 1 安装必要的软件 它们是 build essential
  • 使用mediapipe训练手指数字识别

    mediapipe手指数字识别 本文是从0开始创建一个识别手势的机器学习模型 为了识别手势 采用mediapipe模型 这个模型会返回手指的位置 之后再通过训练一个模型将这些位置分类得到手势 一 导入依赖 import cv2 import
  • js中的var详解

    var是js的一个关键字 它是用来声明变量的 声明一个变量有两种方式 第一种 var num 1 如果在方法中声明 则为局部变量 如果在全局中声明 则为全局变量 第二种 num 1 事实上这是对属性进行赋值操作 首先 它会尝试在当前作用域链
  • 操作符浅解

    1 移位操作符 作用的对象是数的二进制位 1 gt gt 向左边移动一位 左边丢弃 右边补0 相当于这个数乘以2移动n位 相当于乘以2的n次方 int main int a 2 int b a lt lt 1 打a的二进制向左移动一位 pr
  • vulnhub靶机练习-Me and My Girlfriend: 1

    vulnhub靶机练习 Me and My Girlfriend 1 靶机下载地址 https www vulnhub com entry me and my girlfriend 1 409 点击直接下载 靶机介绍 Description
  • 安达发

    APS Advanced Planning and Scheduling 先进计划与排程 是一种集成了生产计划 物料需求计划 MRP 库存控制和车间调度等功能的管理系统 在制造业中 物料清单 BOM 管理是APS系统中的一个重要组成部分 它
  • 电脑显示DNS服务器没检测到,连网时出现"该设备或资源(DNS 服务器)没有检测到有响应",怎么办?...

    连网时出现 该设备或资源 DNS 服务器 没有检测到有响应 怎么办 卡饭网 梦在深巷 2016 05 05 11 23 15 小编整理了以下2种解决方法大家可以参考以下 方法一 有可能是由于无线网络连接里面的DNS服务器错误 导致的网卡断网
  • 自动化遍历-appcrawler

    下载appclawler 下载地址 https pan baidu com s 1dE0JDCH list path 2F 查看帮助文档 java jar appcrawler 2 4 0 jar with dependencies jar
  • JS-ES6类

    使用js的class需注意以下几点 1 通过class关键字创建类 类名我们还是习惯性定义首字母大写 2 类里面有个constructor函数 可以接受传递过来的参数 同时返回实例对象 3 constructor 函数只要new生成实例时
  • seq2seq

    我的书 淘宝购买链接 当当购买链接 京东购买链接 seq2seq是通用编码器 解码器框架 encoder decoder framework 可以用在机器翻译 文本摘要 会话建模 图像描述 源码 https github com googl
  • 【编译原理】flex实现词法分析器

    flex自动实现词法分析器 FLEX 与 BISON 的使用 FLEX介绍 Flex是一个生成词法分析器的工具 它可以利用正则表达式来生成匹配相应字符串的C语言代码 其语法格式基本同Lex相同 单词的描述称为模式 Lexical Patte