如何构建一个语法分析器?


实验一要求构建一个词法分析器。词法分析器的构建过程比较简单。
由于是给定的词法,所以我们只要能够构造出状态图,将再将DFA转化为NFA,然后只用最朴素的case或者ifelse就可以完成。
当然,如果你考虑到使用缓冲区解决代码长度问题等等也是很棒的。
实验二要求构造一个语法分析器。语法分析器相对于词法分析器显得复杂很多。龙书上给出了基本所有的伪代码。
马上就到deadline,所以,我想将自己的构建过程和大家分享一下。
由于当初是选择MATLAB语言作为载体,所以大家可能没有办法直接copy我的代码。不过,MATLAB代码很直观,大家完全可以仿照写出自己的代码。
本博文仅仅是为大家实验二的设计提供一个整体的思路,如果有不足的地方,还请指正。
写在前面:
1.大家不要把自己吓坏了!这个语法分析器并不是很难。
2.老师检查并不是要求我们做的完美。主要是希望我们能够体验这个语法分析的全过程。
3.主要难度在于如何构建一个合理的数据结构来贯穿整个始终。
4.如果大家对整个语法分析器还一头雾水,那强烈建议大家去复习一遍第四章的知识点。

选择很多:
语法分析器的功能如果想要足够强大,那么需要的模块就显得非常多。但是,如果你的语法分析器仅仅只是为了通过实验二的测试,那么我可以告诉你,肯定很轻松就可以。因为即使你的语法分析器不能正常工作,只要你能够将过程解释清晰,老师并不会为难大家。为了比较完整的叙述,我会将我所涉及的部分按照逻辑顺序展开。最后会告诉大家如何做出合理的选择以通过实验二测试。

思路整理:根据书本P167图4-40的算法,我们知道,如果要构造一个语法分析器(LR(1)),我们需要构造一个ACTION和GOTO表。这两张表格的构造,需要我们构造一个函数,这个函数可以试验闭包的计算,也就是CLOSURE这个函数。而构建CLOSURE这个函数的过程中,需要使用到一个很重要的子函数去求解FIRST集合。因此,我们还需要构造一个函数进行FIRST集合的求解。因此,我们主要分为以下几步:
1.构造FIRST函数
2.构造CLOUSRE函数
3.构造LR(1)项集
4.通过LR(1)项集构造ACTION & GOTO 表
5.运用P160图4-36算法实现语法分析程序

接下来会比较枯燥,大家可以不需要一口气写完。,每天完成一些步骤就可以了。当初我也是摸着石子过河。第一次花了两个星期,结果满是bug。然后实在不满意,写了一遍,又花了一个星期,才完成的。

1.构造FIRST函数
FIRST函数的构造,书上没有伪代码,但是给出了文字解释,在P140页。
在FIRST集合的求解过程中,很重要的一点就是如何进行空产生式的推导。
为此,大家可以单独构造一个函数实现空产生式的推倒。
在求解FIRST集合时,是不允许文法存在左递归的。如果存在左递归将会导致程序的无限循环。
我们的文法可能并不一样。所以这里大家可以有多种处理方式:

  1. 如果你的文法没有左递归,那么直接忽略这步。
  2. 如果你的文存在左递归,但是你有不想多写太多的函数,那么,你可以选择直接进行手动消除,然后在输入。
  3. 如果你想让你的编译器可以处理各种文法,而不是仅仅局限于实验二,那么,你需要花比较多的时间另写一个模块实现左递归的消除。其中包括直接左递归与间接左递归。
    4.如果你既不想手动推导也不想编写程序,那么只需要才FIRST集合推导的过程中加入循环次数的限制,一般也是ok的。
    我采用的是思路3 。在消除间接左递归时,我们需要另外写一个函数进行环路判断。具体的代码我放在群里了。

2.构造CLOSURE函数
其实只要有了FIRST函数,这个函数的构造显得十分简单。我们需要做的就是设计一个良好的结构体来按部就班的实现书上的代码。

3..构造LR(1)项集
LR(1)项集的构造也是书上算法的直接实现。

4.通过LR(1)项集构造ACTION & GOTO 表
在得到LR(1)项集后,我们通过遍历项集中的每一个闭包,就可以构造出分析表。这个过程在P167算法4.56有详细描述。

5.运用P160图4-36算法实现语法分析程序
这只是简单的ifelse分支操作。并不复杂。我们要构建两个栈,符号栈和状态栈。在进行出栈入栈时,时刻保持栈顶高度一致。

写在后面:
由于期末时间比较紧缺,写的比较粗糙,望谅解。
我把代码和我的测试用例都上传到群文件了。同时我还上传了一份使用java和c#混合编写的代码,供大家参考。
诡异一笑:
如果大家实在来不及,可以选择手动生成ACTION和GOTO表格,然后直接进入第5步。(然而,事实告诉我这么做是很不好的。)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM