理论教育 编译器设计之路-构造转换图与转换表

编译器设计之路-构造转换图与转换表

时间:2023-11-04 理论教育 版权反馈
【摘要】:笔者根据Neo Pascal的词法定义绘制了完整的转换图,如图2-6所示。图2-6 Neo Pascal词法转换图为了便于读者理解,这里对图2-6作几点说明:图中[全部]、[其他]、[字母]、[数字]是字符集的简化表示形式。由于状态42是终止状态,根据程序2-1的算法,缓冲区与当前字符位置都将回退一个字符。从转换图导出转换表的算法是非常简单的,却比较费时费力,具体过程请参见2.2节,读者可在Neo Pascal的电子文档中找到完整的转换表。

编译器设计之路-构造转换图与转换表

笔者根据Neo Pascal的词法定义绘制了完整的转换图,如图2-6所示。作为一门完整的程序设计语言,Neo Pascal的转换图必定是比较复杂的,读者可以配合词法定义阅读。

978-7-111-32164-4-Chapter02-14.jpg

图2-6 Neo Pascal词法转换图

为了便于读者理解,这里对图2-6作几点说明:

(1)图中[全部]、[其他]、[字母]、[数字]是字符集的简化表示形式。例如,[字母]表示箭弧射出状态下输入任意字母时都转入箭弧射入状态。

(2)终止状态都以“”开头,以区别非终止状态。

(3)由于Neo Pascal是不带编译预处理器的,所以注释也将作为单词识别,只是不将识别得到的单词输出而己。Neo Pascal接受两种注释形式,即(**)与//,功能与C语言的/* */与//完全一样。

下面通过一个特例来说明程序2-1算法的不足。(www.daowen.com)

在标准Pascal语言中,一般会使用如下形式的语句声明数组

【声明2-1l】

VAR i:ARRAY [1..10] OF INTEGER;

那么,当词法分析器识别完单词“[”后,返回状态1,当前字符位置指向“1”,准备识别下一个单词。在状态1下读取“1”转入状态4,当前字符位置指向第一个“.”。在状态4下读取“.”转入状态5,当前字符位置后移一位指向第二个“.”。在状态5下读取“.”转入状态-42,当前字符位置后移一位指向“1”。由于状态42是终止状态,根据程序2-1的算法,缓冲区与当前字符位置都将回退一个字符。此时缓冲区的字符串为“1.”而当前字符位置指向第二个“.”。显然,将字符串“1..”识别为单词“1.”与“.”都不正确,而应该识别为单词“1”与“..”。实际上,主要是由于在识别“..”时需要超前搜索两个字符,而通常情况只超前搜索一个字符。因此,在处理终止状态42时,必须将缓冲区与当前字符位置回退两个字符,故程序2-1无法正确识别单词。

超前搜索几个字符与词法定义有关,有些设计不精良的语言可能需要超前搜索三个甚至四个字符才能正确识别单词。反复回溯搜索会大大降低词法分析器的执行效率,故在设计一门程序设计语言时,应尽可能做到只需超前搜索一个字符就可以完成所有单词的识别。读者不妨考虑一下,C语言是否也存在超前搜索两个字符的情况呢?

通常,完全可以通过修改程序设计语言的词法定义避免超前搜索两个字符。但为了与标准Pascal兼容,Neo Pascal仍然继承标准Pascal的词法定义。

从转换图导出转换表的算法是非常简单的,却比较费时费力,具体过程请参见2.2节,读者可在Neo Pascal的电子文档中找到完整的转换表。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈