语法分析树的作用

编译原理笔记9:语法分析树、语法树、二义性的消除

具体语法树和抽象语法树是两个不同的概念。
通常情况下,前者被称为“具体语法树”,它能够展现推导的步骤;而后者则被称为“抽象语法树”,它只关注最终的结果,并不涉及推导过程。
具体语法树是语言推导过程的图形化表示,它反映了语言的本质和推导过程。
对于上下文无关文法(CFGG)的句型,分析树被定义为一棵具有特定性质的树,它能够展示推导过程,包括最左推导和最右推导。
虽然这两种推导方式在推导过程中的分析树可能不同,但最终得到的句子是相同的,因此最终的分析树是一样的。
分析树能够反映句型的推导过程和结构。
然而,实际上我们更关心的是推导的结果,而不是过程。
因此,我们需要对分析树进行改造,得到抽象语法树。
在抽象语法树中,只包含终结符,不包含非终结符,并且没有括号。
抽象语法树的特点是:叶子节点都是操作数,内部节点都是操作符,树中不包含非终结符和括号。
抽象语法树表达了操作符作用于操作数的关系。
例如,对于表达式-(id+id)和-id+id,它们的抽象语法树能够直观地展示运算顺序。
然而,有时候一个句子可能对应多个抽象语法树,这就是二义性问题。
例如,对于文法G:E→E+E|EE|(E)|-E|id,句子id+idid和id+id+id可能的分析树有多种情况。
虽然对于id+id+id,无论“+”是左结合还是右结合都不会影响结果,但如果“+”的含义变成了减法,那么左结合和右结合就会导致不同的结果。
在这里,我们所说的“二义性”指的是一个句子对应多个分析树,而不是语义上的歧义。
二义性的产生是由于句子产生过程中的某些推导有多种选择。
例如,悬空else问题就是一个很好的例子,它展示了超过一种选择导致的二义性问题。
在二义文法中,由于else可以与多个then配对,因此会导致二义性。
为了解决这个问题,我们可以规定else右结合,即与左边最靠近的then结合。
为了消除二义性,我们可以使用改写的方法,将二义文法改写为非二义文法。
改写的关键是将优先级和结合性明确说明白,确保每个非终结符只负责一个优先级的运算符号,避免出现歧义。
改写后的非二义文法具有以下特点:优先级由低到高分别是+、-,距离开始符号越近,优先级越低;每个符号对应一层的非终结符;根据所需的结合性,确定是左递归还是右递归。
我们已经掌握了改写这个工具,可以用来消除二义性。
接下来,我们将使用这个工具来解决悬空else问题。
悬空else问题出现的原因是then数量多于else,导致else有多个可以结合的then。
在二义文法中,由于可以选择不同的then和else配对,因此会导致二义性。
在这里,我们规定else右结合,即与左边最靠近的then结合。
为了改写此文法,我们可以将S分为完全匹配(MS)和不完全匹配(UMS)两类。
在MS中,then和else数量相等,且else右结合;在UMS中,then和else数量不匹配,且else右结合。
通过改写后的文法,我们可以消除二义性。
虽然二义文法会导致二义性,但它也有一些优点。
例如,在Yacc中,我们可以直接指定优先级和结合性,而无需自己重写文法。
left表示左结合,right表示右结合,越往下的算符优先级越高。
实际上,我们可以将语言本身定义成没有优先级和结合性的,然后通过括号来控制运算顺序。
例如,在Ada中,通过明确的标志来标记过程的结束;在Pascal中,通过给表达式加括号来实现运算顺序的控制。

AST抽象语法树原理与创建

AST抽象语法树的构成与构建概述 概念阐述:抽象语法树(AST)是对源代码语法结构的抽象化表示,采用树形结构直观地展示代码的组织形式。
每个节点映射源代码的特定元素,如指令、表达式和变量等。
通用性:AST不拘泥于特定编程语言的语法细节,如规则和实现方式,它提供了一种普遍适用的、跨语言的表示手段。
功能价值:AST在编译器各个阶段,包括前端和后端,充当了沟通的桥梁,促进了编译流程的高效执行和优化。

构建步骤: 1 . 词法分析:对源代码进行解析,分解为基本元素(词素),并清除无关的空白和注释,这是构建AST的初始步骤,为后续的语法分析打下基础。
2 . 语法分析:将词法分析的结果组织成树形结构,并检查语法是否合规。
生成的AST与源代码不完全相同,因为分析器会剔除一些冗余的标识,例如未闭合的括号。
3 . 语义分析:对AST进行深入审查,确保程序遵循语言的语义规则,并搜集类型数据。
类型验证是语义分析的关键环节,它确认运算符与操作数是否兼容,并允许进行适当的类型转换。
此阶段为生成中间代码提供必要的语义和类型信息。

具体实施:在特定开发环境中,可利用相应的API生成有效的AST。
随后,借助编译器对象添加引用和AST,并通过GetSemanticModel方法获取语义模型,以支持后续的语义分析。

总结:AST作为源代码的抽象表示,其构建过程包括词法、语法和语义分析等多个环节,为代码的生成和优化提供了清晰的框架和类型信息。

计算机自制解释器Pascal(七):抽象语法树AST

抽象语法树(AST)在Pascal解释器中扮演着核心角色,其构建方式如下所述: AST概述:简称为AST,它是以树形结构展示源代码语法结构的抽象表示。
在Pascal的编译或解释阶段,AST充当一个中间层,用来保存源代码的语法信息,便于进一步的代码处理。
解析器模块在AST构建中的角色:解析器是构建AST的核心部分,它通过递归调用多个函数,依据语法规则,将词法分析器输出的TOKEN组织成树形结构。
这些函数各自负责处理特定的语法元素,如数字、括号、运算符等,逐步构建出完整的AST。
以“6 /3 2 +4 5 ”表达式为例,解析器首先用factor函数识别出6 、3 、2 、4 作为树的叶子节点。
随后,term函数处理乘除运算,将乘法运算符与数字节点连接,形成子树。
expr函数最终处理加减运算,将加号与之前的子树结合,形成整个表达式的AST。
AST的深度遍历:在解释器执行阶段,需要对AST进行深度遍历。
这意味着从expr节点开始,递归访问每个节点,直到达到数字或运算符节点,确保解释器能按正确顺序执行计算,得出正确结果。
从代码到AST的转变过程:Token类与词法分析器协同工作:词法分析器扫描源代码,识别出TOKEN,为AST的构建打下基础。
解析器的动作:解析器接手TOKEN,依据语法规则,通过递归调用和树形组合函数,逐步构建出完整的AST。
解释器的角色:解释器遍历AST,按照既定顺序执行计算,并输出最终的执行结果。
通过这一过程,Pascal源代码被转换成易于理解和执行的AST结构,实现了对Pascal代码的解释和执行。

文章推荐

15笔画的繁体字大全集
15笔画的繁体字大全集

请问笔画为十画和十五画的繁体字有哪些?莜、荺、莘、莙、华(繁体)、莅、霂、霅、霈,这些字里带有的雨字旁,象征着雨水滋润万物,尤其是小草的生长,所以从这些字中选择以雨字部为特点的“季霈华”(繁体),其发音和形态都显得悦耳动听。笔画有15画的繁体字有哪

模样的拼音怎么标
模样的拼音怎么标

模样的拼音怎么写模样这个词的拼音写作“múyàng”。这个拼音由两个音节组成,“mú”和“yàng”。“mú”的发音和“mu”类似,它由声母“m”和韵母“ú”构成。而“yàng”是一个独立的音节,发音时要注意声母“y”和韵母“àng”的结合。在意义上,“模样”是一个复合词,用来形容人或物的外部特征。当用来形

带五个成语的句子
带五个成语的句子

用5个成语写一段话或句子1.我在屋内翻箱倒柜,终于找到一张纸,小心翼翼地描绘出螳螂捕蝉、黄雀在后的场景。画毕,室内物品摆放杂乱无章。2.春日的公园充满生机,美景如画,花朵竞相绽放,杨柳轻拂,鸟鸣声声,游客络绎不绝,男女老少皆沉浸在美景之中,久久不愿离去。3.走进“大厦”,只见蜜蜂成群结队,穿

仅的拼音组词组词语
仅的拼音组词组词语

仅能组什么词仅这个字,读音有jìn和jǐn两种,可以组成不少词语,比如“绝无仅有”、“不仅”、“仅仅”等等,像“仅此而已”、“硕果仅存”、“仅次于”、“仅以身免”、“仅容旋马”、“仅见”、“仅存”、“仅然”、“仅事”这些词,都包含了“仅”字。关于“仅”的解释,它是一个形声字,从人,堇声,最初的意思是“