【编译原理】【C语言】实验二:自动构造词法分析器
C语言
实验环境:Visual Studio Code、cmd.exe、flex.exe
author:zoxiii
词法分析器
- 1、实验内容
- 2、前期准备
- 2.1 LEX原理
- 2.2 待分析的C语言子集的词法
- 2.3 C语言子集的单词符号表示表
- 2.4 C语言子集对应的状态转换图
- 3、分析与运行
- 3.1 代码编写
- 3.2 源代码
- 3.3 代码运行
- 4、遇到的问题
1、实验内容
利用LEX或FLEX实验词法分析器,并测试输出。
2、前期准备
2.1 LEX原理
Lex是由美国Bell实验室的M.Lesk和Schmidt于1975年用C语言研制的一个词法分析程序的自动生成工具。对任何高级程序语言,用户必须用正规表达式描述该语言的各个词法类,Lex就可以自动生成该语言的词法分析程序。
Lex及其编译系统的作用如图1所示。
图1-Lex编译系统
描述词法分析器的文件*.l,经过lex编译后,生成一个lex.yy.c 的文件,然后由C编译器编译生成一个词法分析器scan。
词法分析器,简单来说,其任务就是将输入的各种符号,转化成相应的标识符(token),转化后的标识符 很容易被后续阶段处理。
Lex源程序文件由如下三部分组成,且每部分之间必须用“%%”分隔开才有效。
其中,辅助定义式和用户子程序是任选的,而识别规则是必需的。
辅助定义式
%%
识别规则
%%
用户子程序
2.2 待分析的C语言子集的词法
单词大概可分为的5类:标识符、保留字、常数、运算符、界符。
- 标识符:以字母开头的包含字母和数字的符号
- 保留字:while、if、else、switch、case
- 常数:数字0~9
- 运算符:+、-、*、/、?、<、<=、==、=
- 界符:;
- 需略除的:空格、制表符、换行符
2.3 C语言子集的单词符号表示表
根据我们要构造的C语言子集的简单词法分析器的词法,列出所要实现的单词符号以及它们的种别编码。
这里添加了助记符用于定义辅助定义式。具体如下表:
单词符号 | 种别编码 | 助记符 |
---|---|---|
while | 1 | WHILE |
if | 2 | IF |
else | 3 | ELSE |
switch | 4 | SWITCH |
case | 5 | CASE |
标识符 | 6 | letter |
常数 | 7 | digit |
+ | 8 | ADD |
- | 9 | DEL |
* | 10 | MUL |
/ | 11 | DIV |
? | 12 | QUESTION |
<= | 13 | RELOP |
< | 13 | RELOP |
== | 13 | RELOP |
= | 14 | EQUAL |
; | 15 | SEMI |
2.4 C语言子集对应的状态转换图
根据需要构造的词法分析器的单词符号,设计了对应的状态转换图。其中,首先对输入串预处理,去除空格、制表符等,再根据单子符号表得到状态转换图,并分析每种状态应输出的单词二元组信息。
图2-状态转换图
3、分析与运行
3.1 代码编写
(1) 辅助定义式
根据前面的词法的单词符号的助记符以及正规表达式的规则来辅助定义这些单词符号的组成形式。
例如,标识符就是以字母开头,加上不限制长度的字母或数字组成,所以得到标识符的定义式如下:
letter [A-Za-z][A-Za-z0-9]*
相应的其他单词符号也是按照这种方式定义,需要注意的是这里的空格符号、制表符等也需要定义。
(2) 识别规则
识别规则就是当识别到前面定义的单词符号应该有审美杨的活动,这里我们要求输出识别的单词符号及其对应的种别编码。
其中标识符的识别规则如下,其他的也类似:
{letter} {printf("(6,%s)\n",yytext);}
(3) 用户子程序
这里主要编写一个主程序,用于运行程序文件,对其进行词法分析。而要能将程序文件加入,就需要参数“argc”和“argv”。
int main(int argc,char** argv)
3.2 源代码
%{#include<stdio.h>#include<stdlib.h>
%}delim [" "\n\t]
whitespace {delim}+
WHILE [w][h][i][l][e]
IF [i][f]
ELSE [e][l][s][e]
SWITCH [s][w][i][t][c][h]
CASE [c][a][s][e]
letter [A-Za-z][A-Za-z0-9]*
digit ([0-9])+
ADD [+]
DEL [-]
MUL [*]
DIV [/]
QUESTION [?]
RELOP [<][=]|[<]|[=][=]
EQUAL [=]
SEMI [;]
%%
{whitespace} {}
{WHILE} {printf("(1,%s)\n",yytext);}
{IF} {printf("(2,%s)\n",yytext);}
{ELSE} {printf("(3,%s)\n",yytext);}
{SWITCH} {printf("(4,%s)\n",yytext);}
{CASE} {printf("(5,%s)\n",yytext);}
{letter} {printf("(6,%s)\n",yytext);}
{digit} {printf("(7,%s)\n",yytext);}
{ADD} {printf("(8,%s)\n",yytext);}
{DEL} {printf("(9,%s)\n",yytext);}
{MUL} {printf("(10,%s)\n",yytext);}
{DIV} {printf("(11,%s)\n",yytext);}
{QUESTION} {printf("(12,%s)\n",yytext);}
{RELOP} {printf("(13,%s)\n",yytext);}
{EQUAL} {printf("(14,%s)\n",yytext);}
{SEMI} {printf("(15,%s)\n",yytext);}
%%
int yywrap()
{return 1;
}
int main(int argc,char** argv)
{if(argc>1){if(!(yyin=fopen(argv[1],"r"))){perror(argv[1]);return 1;}}while(yylex());return 1;}
3.3 代码运行
首先构建运行环境,在网上下载了flex.exe文件,安装并添加路径到环境变量中,然后就可以在cmd.exe中使用了。
- 打开编写的文件所在路径:
cd ……
; - 编译编写的.l文件生成lex.yy.c文件:
flex.exe sy2.l
- 编译c文件生成运行文件:
gcc lex.yy.c -o scan
- 运行文件,添加参数为提前编写好的需分析的文档:
scan input.txt
,文件内容如下
Hello World?;
x=8;
y=13;
if 7<=9 x=6;
else if x<yx=y/3;
- 得到词法分析结果如图3;
图3-分析结果图
4、遇到的问题
(1) 在定义运算符时,对于“<”、“<=”、“==”的定义式编写有问题,编写成了如下形式:
RELOP [<=]|[<]|[\=\=]
后查阅资料发现对于由多个字符构成的运算符,必须分开写成“[<][=]”的形式才可以被分析出来。
(2) 生成词法分析程序中的yywrap函数必须由用户亲自在*.l文件中编写,否则可能会发生yywrap未定义的错误。
参考文献:《编译原理教程 (第4版)》 胡元义 2016
【编译原理】【C语言】实验二:自动构造词法分析器相关推荐
- k近邻算法原理c语言,实验二 K-近邻算法及应用
作业信息 一.[实验目的] 理解K-近邻算法原理,能实现算法K近邻算法: 掌握常见的距离度量方法: 掌握K近邻树实现算法: 针对特定应用场景及数据,能应用K近邻解决实际问题. 二.[实验内容] 实现曼 ...
- 编译原理SNL语言编译器实验报告
完成实验内容 实验要求: (1)设计并实现SNL程序设计语言的编译程序 (2)四个必做: 词法分析模块 语法分析模块(递归下降方法) 语法分析模块(LL(1)方法) 语义分析模块 (3)编程语言不限 ...
- 【编译原理】语言认知之Java、Python、C++快速排序三者运行效率与开发效率比较
[编译原理]语言认知之Java.Python.C++快速排序&三者运行效率与开发效率比较 一.实验目的 二.实验环境 三.实验步骤 四.快速排序程序 五.实验结果 六.总结 一.实验目的 强化 ...
- 【实验】编译原理——编译器认知实验
系列文章目录 学习笔记 [学习笔记]编译原理--第一章 编译引论 [学习笔记]编译原理--第二章 词法分析 实验 [实验]编译原理--编译器认知实验 文章目录 系列文章目录 学习笔记 实验 一.实验目 ...
- 太原理工 编译原理 c语言,太原理工大学编译原理实验
<太原理工大学编译原理实验>由会员分享,可在线阅读,更多相关<太原理工大学编译原理实验(19页珍藏版)>请在人人文库网上搜索. 1.本科实验报告课程名称: 编译原理 实验项目: ...
- 单片机原理及应用 实验二 数据处理与RAM转存
单片机原理及应用(C51语言版) 实验二 数据处理与RAM转存 实现功能如下: 对100-200之间的每个整数进行检查.将不能被3整除的数依次转存到地0x30开始的RAM中,能被整除的不做转存. 步骤 ...
- 周信东c语言实验二实验报告,周信东主编最新版C语言程序设计基础实验一实验报告.doc...
周信东主编最新版C语言程序设计基础实验一实验报告.doc 下载提示(请认真阅读)1.请仔细阅读文档,确保文档完整性,对于不预览.不比对内容而直接下载带来的问题本站不予受理. 2.下载的文档,不会出现我 ...
- 大前端开发者需要了解的基础编译原理和语言知识
转自:https://yq.aliyun.com/articles/180879 在我刚刚进入大学,从零开始学习 C 语言的时候,我就不断的从学长的口中听到一个又一个语言,比如 C++.Java.Py ...
- 编译原理:词法分析实验报告
词法分析实验报告 文章目录 词法分析实验报告 一.实验目的 二.实验原理 三.实验要求 四.实验步骤(利用Java语言来进行词法分析) ① 待分析的语言词法 ② 单词符号对应的种别码 ③ 词法分析程序 ...
- 周信东c语言实验二实验报告,周信东主编最新版 C语言程序设计基础实验一实验报告...
实验1 C程序的运行环境和最简单的C程序设计 学号:1700200224 姓名:莫新锋 实验日期: 2018.10.23 一. 实验目的和要求 (1)熟悉C语言程序开发环境(Visual C++),了 ...
最新文章
- apache nginx禁止跨目录访问
- 部署分布式文件系统(DFS)
- 【LeetCode从零单排】No.7 Reverse Integer
- 【每周NLP论文推荐】 生成式聊天机器人论文介绍
- tomcat无法启动(JVM错误)
- 高斯噪声和椒盐噪声python
- java中文乱码解决之道(五)—–java是如何编码解码的
- 将一个压缩文件分成多个压缩文件;RAR文件分卷
- Codeforces Round #726 (Div. 2) D. Deleting Divisors 博弈
- 敏捷开发智慧敏捷系列之五:定不定流程和模板?
- 开课吧课堂:C++开发语言的应用方向有哪些?
- 简单使用NSURLConnection、NSURLRequest和NSURL
- 大话设计模式--解释器模式
- 洛谷 P4568 [JLOI2011]飞行路线
- Python3入门机器学习经典算法与应用 第3章 numpy矩阵运算
- 超星尔雅移动图书馆账号密码
- html金额自动换算成大写,JavaScript实现将人民币小写金额自动转换成大写的方法...
- 局计算机房制度,岳阳市统计局机房管理制度
- 监控系统java调用摄像头_java调用摄像头实例
- 模拟网易云的H5音乐播放器