从零开始的编译原理(5):语义分析与中间代码生成
一、前言 我语言的局限,即是我世界的局限 —— 路德维希·约瑟夫·约翰·维特根斯坦 二、从文法树到语义 经过语法分析阶段的处理,我们将词序列组织成了一棵文法树。而在语义分析阶段,我们的目标就是理解该文法树的含义,并按其含义将该文法树翻译含义等价的另一种语言。 上面的表述十分宽泛。这是因为语义分析阶段不像前两个阶段有着明确的输入输出和确定的算法,根据使用场景的不同采用各自的处理方法。 举个例子,对比 C 语言和 SQL 语言,虽然它们都会采用编译技术进行语句的处理,但是 C 语言的语义分析产物是类似汇编的中间代码;而 SQL 语言的语义分析的结果则是对数据库中数据的处理操作。 因此,语义分析并没有通用的算法,就算同样是编程语言,面向过程、面向对象、函数式等不同的语言类别在语义分析上也有许多不同的处理。所以在本篇文章中,我们只会介绍最为简单和普遍的一种语义分析方法,那就是语法制导翻译。 三、语法制导翻译 (1)属性翻译文法 通过前面的文章,我们知道文法树表达了句子的结构。这种结构从语义上来说有两种含义: 一是指整体由部分组成。这反映了文法树中父节点的含义。例如对于表达式会 $1 + 2$,表达式本身是文法树中的父节点,而 $1$ $+$ 和 $2$ 则是子节点。 二是指部分处于整体之中。这反映了文法树中子节点的含义。 在使用语法制导翻译进行语义分析时,这两种含义我们称为属性。第一种属性由 “父” 传递到 “子”,称之为继承属性;第二种属性由 “子” 传递到 “父”,称之为综合属性。 (2)符号表管理 四、中间代码