最近顶着考研的压力去做了一下编译原理的实验,实验的要求是写一个PL/0语法的编译器,一开始想从网上找找有没有现成的代码改一改就完事了,结果百度的结果都是递归下降分析,而老师的课程大部分都在讲自底向上分析的知识,而我甚至不知道这个文法是不是SLR的,所以为了讲实验一咬牙干脆自己写一个好了,如果算出来是SLR的就去讲实验,不是SLR大不了分不要了,因为LL(1)表的构造实在是让人难受,幸好结果证明这文法确实是SLR的。
有限的时间中大多数都花在了构造语法分析表的部分,所以后面的翻译执行并没有完成。

完整的python实现程序已经上传到了码云,需要的话可以参考:
编译原理实验-PL0自底向上分析

1.原文法

〈程序〉→〈分程序>.

〈分程序〉→ [<常量说明部分>][<变量说明部分>][<过程说明部分>]〈语句〉

<常量说明部分> → CONST<常量定义>{ ,<常量定义>};

<常量定义> → <标识符>=<无符号整数>

<无符号整数> → <数字>{<数字>}

<变量说明部分> → VAR<标识符>{ ,<标识符>};

<标识符> → <字母>{<字母>|<数字>}

<过和说明部分> → <过程首部><分程度>;{<过程说明部分>}

<过程首部> → procedure<标识符>;

<语句> → <赋值语句>|<条件语句>|<当型循环语句>|<过程调用语句>|<读语句>|<写语句>|<复合语句>|<空>

<赋值语句> → <标识符>:=<表达式>

<复合语句> → begin<语句>{ ;<语句>}end

<条件> → <表达式><关系运算符><表达式>|ood<表达式>

<表达式> → [+|-]<项>{<加减运算符><项>}

<项> → <因子>{<乘除运算符><因子>}

<因子> → <标识符>|<无符号整数>|(<表达式>)

<加减运符> → +|-

<乘除运算符> → *|/

<关系运算符> → =|#|<|<=|>|>=

<条件语句> → if<条件>then<语句>

<过程调用语句> → call<标识符>

<当型循环语句> → while<条件>do<语句>

<读语句> → read(<标识符>{ ,<标识符>})

<写语句> → write(<标识符>{,<标识符>})

<字母> → a|b|c…x|y|z

<数字> → 0|1|2…7|8|9

2.词法分析

这里我用字符串分析的方法来做的,具体逻辑可以见代码语法分析树文件夹下的tokens.py。在词法分析的同时,我把一部分非终结符变成了终结符方便处理:

终结符
const var procedure begin end ood if then while do read call write:= = { } ( ) ; , .
id-<标识符> 
un-<无符号整数> 
re-<关系运算符>  #|<|<=|>|>=
mn-<加减运算符> +|-
td-<乘除运算符> *|/

3.状态分析表构造

自底向上的分析方法需要状态分析表才能够实现,所以其实我最主要干的事就是造了这个分析表。
首先需要改写文法,因为当前这种文法表示形式是不能去用所学的算法构造分析表的,所以我改成了等价文法(其实并不等价,那个#当做终结符用了,所以其实最后结果中的#并没有当不等号用,如果需要可以再完善这个文法):

S→<程序>
<程序>→<分程序>.
<分程序>→ <常量说明部分><变量说明部分><过程说明部分><语句>
<常量说明部分>→
<常量说明部分> → const <常量定义><常量定义组>;
<常量定义组>→,<常量定义><常量定义组>
<常量定义组>→
<常量定义> → id=un
<变量说明部分>→
<变量说明部分> → var <参数组>;
<参数组>→id<标识符组>
<标识符组>→,id<标识符组>
<标识符组>→
<过程说明部分>→
<过程说明部分> → <过程首部><分程序>;<过程说明部分>
<过程首部> → procedure id;
<语句> → <赋值语句>
<语句> → <条件语句>
<语句> → <当型循环语句>
<语句> → <过程调用语句>
<语句> → <读语句>
<语句> → <写语句>
<语句> → <复合语句>
<语句> →
<赋值语句> → id:=<表达式>
<条件语句> → if<条件>then<语句>
<条件> → <表达式>re<表达式>
<条件> → ood<表达式>
<表达式> → <项><表达式组>
<表达式组> → <加减运符><项><表达式组>
<表达式组> →
<加减运符>→mn
<项>→<因子><因子组>
<因子组> → td<因子><因子组>
<因子组>→
<因子> → id
<因子> → un
<因子> →(<表达式>)
<读语句> → read(<参数组>)
<写语句> → write(<参数组>)
<复合语句> → begin<语句><中间语句>end
<中间语句>→;<语句><中间语句>
<中间语句>→
<当型循环语句> → while<条件>do<语句>
<过程调用语句> → call id

一开始手算了一点,算着算着就发现这玩意手算估计我当天晚上就不用睡觉了:
于是决定开始写程序去算,具体的逻辑实在太过复杂,First,Follow还有最后的状态收集打印都花了我不少时间,这里直接讲述一下分析表生成程序的用法,所有关于分析表生成的程序都在状态表构造V2目录下:

3.1.将文法保存在gra.txt

如图,将自己的文法写到gra.txt中。

3.2.运行程序得到分析表

在命令行键入

python3 main.py

即可运行程序

如图,程序运行会打印出所有状态,可以利用管道把这个状态输出到文件中便于进行调试。这里的xtzdj.csv就是生成的分析表,可用Excel打开查看:
这里行是状态,列是终结符或者非终结符,表中单元则是转移或者规约动作。

4.进行语法分析

得到语法分析表之后,就可以愉快的分析源程序的语法了,其实编写程序的过程并不愉快,文法的读取、状态的收集去重等还是花了我很长时间,这里也不具体讲述代码了,简单说一下程序执行方式:

4.1.把文法和语法分析表拷贝到语法分析树v2目录下

如图,把这两个文件放到该目录下。

4.2.把要分析的源码写到目录下的test.pl0中

这里我的逻辑默认从test.pl0中读取源代码分析,如果需要的话可以修改syntax.py来修改这个默认名称。

4.3.运行语法分析程序

在命令行中键入

python3 syntax.py

即可运行程序。
如图所示,成功的识别了测试的pl0程序,并打印出了语法树的树枝。即语法分析成功。

其实到这一步整个编译器的工作并没有完成,接下来应该为其编写对应的属性文法,然后把源代码翻译成四元组,然后再是代码的优化,最后是执行,剩下的部分如果以后能闲下来再去探究吧。

编译原理实验-PL0自底向上语法分析相关推荐

  1. 编译原理实验:自下而上语法分析

    编译原理实验:自下而上语法分析 1. 实验题目:自下而上语法分析 实验目的 实验内容 实验要求 输入输出 2. 设计思想 3. 算法流程 4. 源程序 5. 调试数据 1. 实验题目:自下而上语法分析 ...

  2. 编译原理实验:自上而下语法分析

    编译原理实验:自上而下语法分析 1. 实验题目:自上而下语法分析 实验目的 实验内容 实验要求 输入输出 2. 设计思想 3. 算法流程 4. 源程序 5. 调试数据 1. 实验题目:自上而下语法分析 ...

  3. 编译原理实验二 自上而下语法分析

    自上而下 语法分析实验 一.实验目的 (1)给出 PL/0 文法规范,要求编写 PL/0语言的语法分析程序. (2)通过设计.编制.调试一个典型的自上而下语法分析程序,实现对词法分析程序所提供的单词序 ...

  4. 编译原理实验Sicily--LR(K) 语法分析程序

    Description 输入开始符号,非终结符,终结符,产生式 输出LR(k)优先分析过程 以拓广算术表达式G[A]: 为例 A→E E→E+T | T T→T*F | F F→(E) | a Inp ...

  5. 编译原理--实验2 语法分析

    文章目录 前言 1.1实验目的 1.2 实验任务 1.3 实验内容 1.3.1 实验要求 1.3.2 输入格式 1.3.3 输出格式 1.3.4 样例 1.4 程序 1.4.1 程序流程图 1.4.2 ...

  6. 编译原理实验二:赋值语句的语法分析程序设计

    编译原理实验二:赋值语句的语法分析程序设计 1.1实验内容 目的: 在前面实验的基础上,通过设计.编制.调试一个典型的赋值语句的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查,进一步掌握 ...

  7. 编译原理实验(三)——LR(0)语法分析

    编译原理实验(三)--LR(0)语法分析 实验要求 参考程序 实验结果 程序输入说明 截图 实验要求 根据LR(0)分析法编写一个语法分析程序 直接输入根据已知文法构造的分析表M;对于输入的文法和符号 ...

  8. 编译实验 lr c语言代码,编译原理-实验5-LR(1)分析法

    <编译原理-实验5-LR(1)分析法>由会员分享,可在线阅读,更多相关<编译原理-实验5-LR(1)分析法(6页珍藏版)>请在人人文库网上搜索. 1.编译原理实验报告项目名称 ...

  9. 编译原理实验二:Bison

    编译原理实验二:Bison 实验要求 1.了解Bision基础知识,如何将文法产生式转换为Bison语句 2.阅读/src/common/SyntaxTree.c,对应头文件 /include/Syn ...

  10. 贵州大学-编译原理实验2-句法分析器

    贵州大学-编译原理实验2-句法分析器 考虑下面的C语言子集的文法,其中<>括起来的为非终结符,粗体为终结符. ® <statement_list> <statement_ ...

最新文章

  1. Java API —— Collections类
  2. 【WPF】获取电磁笔的压感
  3. 过拟合(overfitting)和欠拟合(underfitting)出现原因及如何避免方案
  4. 5G来了 多款4G手机开始降价销售
  5. win10下的用交叉线实现文件共享
  6. Redis单台的安装部署及集群部署
  7. Java中System.getProperty()的作用及使用
  8. 《Go语言实战》学习笔记——包
  9. 编译contrail-nodemgr
  10. git使用kdiff3合并乱码问题
  11. 标准差和标准误差的区别
  12. ITMS-90096错误解决
  13. VUE游戏开发:使用Box2D模拟球体的飞行和撞击特效
  14. Python批量复制文件夹及其内容、并按Excel表格遍历重命名文件夹
  15. 网易2018校园招聘题目
  16. TPAMI 2022|金字塔池化的骨干网络!南开达摩院联合推出P2T
  17. Oracle 修改字符集(AL32UTF8 转换成UTF8字符集)
  18. 多项式计算(python)
  19. 造轮子 Websocket 现在就 Go
  20. 中高级Java面试中你不得不会的知识点,完整版开放免费下载!

热门文章

  1. 快速获取颜色的RGB或十六进制码(取色技巧)实战教学
  2. 【道高一尺,魔高一丈】Python爬虫之如何应对网站反爬虫策略
  3. zabbix-agent key属性列表
  4. 如何实现实时监测配电室环境数据
  5. cad编程c语言,基于C.NET的AutoCAD二次开发简版.pdf
  6. emmx文件用什么软件打开电脑_fbx文件是什么_电脑fbx文件用什么软件打开
  7. 超详细的Java基础面试题总结
  8. 3dsMax批量设置可编辑样条线的视口渲染
  9. 小京东V5.X短信宝插件开发
  10. 作为一名优秀的软件测试工程师,需要具备哪些能力?