原本是一个正则引擎,用dot可视化状态机,后来增加了很多新东西
可用于检查编译原理作业正确性
graphviz
生成的gv
或svg
格式, 可以在src/tools/visualize.py
中将他们转化为html
文件方便查看. 其中visualize.py
是从操作系统:设计与实现 (2022 春季学期) 中某个工具简化而来, 我只保留了 svg
图片转html
的功能.#
, 需要注意. 并且尽量只使用#
当作栈底. Ubuntu
系统上开发, 没有中文输入法, 所有英文注释均为此时所写.main
函数中.ANSI Escape Code
在终端上显示颜色的效果非常好, 我很喜欢.markdown
语法.src/tools/zlog.py
中input
文件夹中./src/core/NFA.py
/src/core/DFA.py
/src/core/zre.py
/src/core/graph.py
三个文件包含了该项目最初写的简单的正则引擎 ,graph.py
封装了抽象的图,在此基础上依次封装NFA
和DFA
在各自文件中,最终在zre.py
中实现了汤普森算法和子集构造法,实现从正则语句到NFA到DFA的转化。并生成svg
格式的图,我提供了visualize.py
将svg
图片放到还算好看的html
界面中。该算法的实现有很大问题,只能解决很小部分的正则表达式,例如(a|b*)
可以生成如下的图.
/src/BNF.py
包含了将原始BNF语法识别为Token
流的抽象 (又是一个小的词法分析 ! ),算是封装的很成功的模块,在后面的所有算法中都用到了,能够读取bnf
文件,支持的语法如下
|
,不支持括号嵌套::=
符号前面的都是非终结符,其他都是终结符,所以不限制非终结符一定要大写#
注释,不支持行内注释ε
字符视为epsilon
,其他均不可一些符合这个语法的BNF
文件示例放在input/
下,对于简单的例子,学习编译原理而言是足够使用的
该分析器拥有
GUI
界面
/src/core/Up_Down.py
自顶向下分析算法中的LL(1)
识别器,可以依次生成First首符集
Follow随符集
预测分析表
,并在此基础上实现递归下降分析,识别一个句子是否符合输入的BNF语法,例如经典的表达式文法input/calc.txt
(已经手动消除左递归处理的BNF)
可以成功识别a+a*a
这样的句子
该分析器拥有
GUI
界面
/src/core/Operator_First.py
算符优先文法识别器,可以依次生成Firstvt
Lastvt
算符优先表并可视化,并识别句子,还是以经典的表达式文法为例
并且在识别句子时可以显示整个规约过程, 例如识别i*(i+i)'
算符优先是最小巧我最满意的, 缺点是能识别文法太少了, 这也是算法本身的问题.
该分析器拥有
GUI
界面
/src/core/SLR.py
实现SLR(1)
分析器,是截止当前最复杂的,并且在我的封装下更加复杂了, 首先将产生式分解成带有活前缀的项目,据此生成识别活前缀的DFA
,再根据DFA
生成action_goto
表格,再根据该表格实现SLR(1)
分析。整个过程中,生成DFA
的过程相比于正则引擎需要汤普森算法需要递归,这里只需要循环迭代即可生成,然而还是在理解上遇到困难,并且现在还是存在一些小问题,例如在生成新的DFA
节点时,在某些情况(我也没发现到底是什么情况)下无法合并到已经存在的DFA
节点上。接下来以下述BNF语法为例, 该语法不仅是SLR(1)
文法, 同时也是LR(0)
文法, 事实上本分析器也是支持表达式文法的.
E ::= a A | b B
A ::= c A | d
B ::= c B | d
生成DFA
如下. (还记得基础说明中的第一点吗)
生成action_goto
表格如下
在分析时可以显示全部的分析过程,例如对于字符串bcd
,有如下的分析过程
由于本人开始写LR(0)
时还不懂LR(1)
算法, 没有为前看符号预留位置, 导致现在要把SLR
扩展为LR(1)
出现了灾难性的困难 --- 几乎要全部重写. 不想写了
本来这种编译底层的东西做成界面毫无意义, 但是为了学校实验结果看起来炫酷一点, 还是为每个分析器增加了GUI
界面, 存放在src/HW
目录下. **并且所有可执行文件我都会打包在发行版中. **
其中src/HW/core/zlex.py
是为了完成作业单独写的一个词法分析器核心, 对应的界面在src/HW/gui/zlex_gui.py
下. 使用方法如下:
lex
文件, 详细可见input/HW/lex0.txt
, 这个文件是我调试过的, 使用引号表示匹配相同的字符串, 使用正则表达式匹配数字, 标识符等, 使用冒号分隔Token
名和正则文法. lex
文件后, 再将源文件喂给程序, 程序就会吐出Token
流了./HW/gui/zll1_gui.py
是LL(1) 算符优先 SLR(1)
三个分析器的前端界面.
大逆不道的将其称为Compiler
, 实际上只实现了一些语法分析而已. 然而如果以一种广义的角度来说, 这其实也是一种Compiler
, 读取lex
文件BNF
文件, 正则引擎解析, 这些都是一个个小小的编译器. 正是由于这些小小的编译器, 最终才有可能创造出大大的编译器.
qt
的资源管理特性, 只把图标等全部存放在同一个位置, 导致项目结构管理会出现一些麻烦的问题.此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。