# Linux环境下的针对PL0语言的语法词法语义分析
# 摘 要
此次编译原理课程设计,我利用flex工具进行PL/0语言的词法分析、自己用C++语言实现了LR语法分析、语义分析以及中间代码生成,我选择的是布尔表达式文法,对符合文法的布尔表达式能够产生相应四元式,处理了控制结构的真链与假链,对错误的表达式能够给出错误提示。
鉴于flex工具原本来自Unix以及个人日常习惯,本实验开发环境选用Linux,代码在Ubuntu16.10中测试通过。
**关键字**:flex;词法分析;Linux;语法分析;中间代码生成;真假链
# 引 言
编译原理是一门实践性比较强的学科,学习了课本上理论知识,阅读了书后示例PL/0编译程序,此次课程设计针对PL/0语言进行了词法分析、语法分析及布尔表达式的中间代码(四元式)生成。其中PL/0的词法分析程序的功能是为语法语义分析提供单词,把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析;而语法分析的任务是识别单词符号序列是否符合给定的语法规则。实验中在语法分析过程中需要用到flex工具,这个工具源于Unix和Linux,很多同学使用Windows还需要配置相关环境,我日常使用Linux,因此选用它作为编程环境,免去了不必要的麻烦,配置较为方便。
# 一、实验目的
实现对布尔表达式的词法分析、语法分析、语义分析并产生四元式中间代码,完成真假链的回填及合并。
## 1.1 词法分析部分
利用C++和flex工具设计编写一个词法分析程序,实现对标志符、数字、保留字和算符等一系列符号的识别,用于后面做语法分析和语义分析;
## 1.2 语法分析部分
采用LR(0)语法分析方法,设计、开发如下文法描述语言的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,加深课堂相关理论教学内容的理解,提高语法分析方法的实践能力。语法分析完成之后可用于语义分析。
## 1.3 语义分析部分
基于以上两步词法和语法分析的工作,采用一边归约一边建立语义栈并做语义分析的方法,分析给出的布尔表达式是否符合相应文法,最后产生四元式 ,实现真假链的回填及合并 。
# 二、实验内容
## 2.1 词法分析阶段
词法分析阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词。利用词法分析程序实现对某输入串的词法分析,将各个符号识别并送给语法分析程序;
## 2.2 语法分析阶段
利用上述词法分析的结果,一个一个送进LR语法分析的函数 SLR\_parser而判断整个输入串是否满足布尔表达式的文法,具体文法如下:
**布尔表达式文法**
```c++
[1]E -> E or E
[2]E -> E and E
[3]E -> not E
[4]E -> ( E )
[5]E -> id rop id
[6]E -> true
[7]E -> false
```
其中:E-布尔表达式,rop-关系运算符
## 2.3 语义分析阶段
语义分析阶段,利用上述两步的结果,在归约和移进的过程做语义分析并产生四元式。语义分析时,我将用于语法分析的函数SLR\_parser进行扩充,使之在每步归约的时候做中间代码生成以及回填的工作。
具体的流程如下:
![](http://www.writebug.com/myres/static/uploads/2021/10/19/17918a7ad402f474bbee0514d0bdd1cc.writebug)
词法分析之后的语法和语义分析详细过程如下图所示:
![](http://www.writebug.com/myres/static/uploads/2021/10/19/663c3ceb4bf12ed18a6ef7c1660964a3.writebug)
# 三、主要实现功能
## 3.1 功能一:词法分析
接收字符串形式的源程序,按照源程序输入的次序依次扫描源程序,在扫描的同时根据语言的词法规则识别出具有独立意义的单词,并产生与源程序等价的属性字(Token)流。
我的词法分析通过从读取源文件,得到输入串,利用flex工具,写正则表达式去匹配单词,识别它们的类型,分析结果存到mytoken数组中,待语法分析和语义分析程序使用。
## 3.2 功能二:语法分析
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.语法分析程序可以用YACC等工具自动生成。
应所给题目要求,这里不借助yacc工具,而是自己手写C++代码,完成相应功能。SLR(1)分析核心是要得到一张SLR(1)分析表,理论上可以通过编程求first集和follow集,进而得到这张表。这里我们采用手写的方式得到这张分析表,然后建立状态栈和符号栈,不断查表判断是应该归约还是移进。
## 3.3 功能三:语义分析
语义分析是编译过程的一个逻辑阶段, 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查,进行类型审查。语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。
本次课程设计最终目的是产生布尔表达式对应的四元式。上一步语法分析主要通过一个函数SLR\_parser实现,此步的语义分析及目标代码生成及真假链的回填与合并是在归约的时候做的,于是就把函数SLR\_parser继续扩充,遇到归约就调用相应的函数来生成四元式,实现书上的布尔表达式翻译方案,完成回填和合并工作。如果输入串符合语法 , 把最终生成的四元式写入pcode.txt;若不合语法,给出错误提示。
# 四、主要功能的设计
## 4.1 词法分析
词法分析部分借助flex工具,我的C++代码pl0lex.cpp完成这一功能,在%{和%}之间写自己的C++代码,之外写正则表达式去匹配相应的符号,在{和}之间写匹配后应该做的事务。通过man flex命令查看系统中flex的帮助文档,我学会了如何让程序既可以从控制台读入又可以从文本读入,主函数是int main( int argc, char \*\*argv ),通过判断调用时后面是带参数函数还是不带参数,选择用标准输入输出还是从文件读入。在每次匹配成功,用于统计总共符号数的total_token加一,rawstr字符串数组存入已经读入的原字符串,mytoken数组存入识别后的结果。这两者有一种对应关系,比如rawstr字符串数组中有一个是x,则mytoken数组中相应位置就存其类型:标识符;rawstr中是大于小于大于等于这类符号,mytoken就存其类型:关系运算符。这样就达到了词法分析的目的,同时还存好了原来的语义值。
对照课本P15的PL/0语言文法的EBNF表示,通过阅读EBNF范式,我将其逐步转化为正则表达式代码。
### PL/0语言文法的EBNF表示
```c++
<程序>::=<分程序>.
<分程序> ::=[<常量说明>][<变量说明>][<过程说明>]<语句>
<常量说明> ::=CONST<常量定义>{,<常量定义>};
<常量定义> ::=<标识符>=<无符号整数>
<无符号整数> ::= <数字>{<数字>}
<变量说明> ::=VAR <标识符>{, <标识符>};
<标识符> ::=<字母>{<字母>|<数字>}
<过程说明> ::=<过程首部><分程序>{; <过程说明> };
<过程首部> ::=PROCEDURE <标识符>;
<语句> ::=<赋值语句>|<条件语句>|<当循环语句>|<过程调用语句>
|<复合语句>|<读语句><写语句>|<空>
<赋值语句> ::=<标识符>:=<表达式>
<复合语句> ::=BEGIN <语句> {;<语句> }END
<条件语句> ::= <表达式> <关系运算符> <表达式> |ODD<表达式>
<表达式> ::= [+|-]<项>{<加法运算符> <项>}
<项> ::= <因子>{<乘法运算符> <因子>}
<因子> ::=
精选_毕业设计_Linux环境下的针对PL0语言的语法词法语义分析_完整源码
版权申诉
194 浏览量
2022-03-05
15:19:24
上传
评论
收藏 9.27MB ZIP 举报
工具盒子
- 粉丝: 60
- 资源: 1313
最新资源
- module-0004.SyncTensorsGraph.7578.sm-8.0-gpu-after-optimizations
- python39.dll
- 【Matlab 六自由度机器人】Fixed Angles(固定角度) 和 Euler Angles(欧拉角) 之间的区别
- STLINK下载器调试过程中常见问题排查
- BMSP430工程PPT说明书.zip
- FlinkFlinkF
- 《计算机网络-自顶向下方法》答案
- 基于pyqt5框架开发的demo项目 全栈开发,短小精悍,入门学习,上手简单
- 国内IP地址大全 站长资源 访问IP设置 Order allow,deny 使用方法
- 【JavaScript实现点击鼠标出现爱心特效脚本】直接引入index.html文件可用!!!
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈