正在加载图片...
China-pub.com 第6章语义分析 199 下载 理的语言最有用,它表明程序的语义内容与它的语法密切相关。所有的现代语言都有这个特性。 然而,编译程序的编写者通常必须根据语言手册手工构造属性文法,因为语言设计者很少为之 提供。更糟糕的是,由于坚持语言清晰的语法结构,属性文法的构造会有不必要的复杂性。语 义计算表达式的一种更好标准是抽象语法,就像抽象语法树表示的那样。但是抽象语法树的说 明通常也由语言设计者留给了编译程序编写者。 语义分析实现的算法也不像语法分析算法那样能洁晰地表达。这部分原因也是因为在考虑 语义分析说明时,出现了刚刚提及的同样的问题。还有另外一个问题,它是由编译过程中分析 的时间选择引起的。如果语义分析可以推迟到所有的语法分析(以及抽象语法树的构造)完成之 后进行,那么实现语义分析的任务就相当容易,其本质上由指定对语法树遍历的一个顺序组成, 同时在遍历中每次遇到节点时进行计算。这就意味着编译程序必须是多遍的。另 一方面,如乐 必须要求绵译程序在一遍中完成所有的操作(包括代码生成),那么语义分析的实现就更加会变 成寻找计算语义信息的正确顺序和方法的特别的过程(假定这样的顺序实际存在)。当然,现代 的惯例越来越允许编译程序编写者使用多遍扫描简化语义分析和代码生成的过程。 尽管有点扰乱语义分析的状态,研究属性文法和规范发布仍是特别有用的,因为这能从写 出更加清晰、简练、不易出错的语义分析代码中得到补偿,同时代码也更加易懂 因此,本章从研究属性和属性文法开始。接下来是通过属性文法说明实现计算的技术,包 括推断与树的遍历相连的计算顺序。随后的两节集中于语义分析的两个主要方面:符号表和类 型检查。最后一节讲述前一章介绍的TNY编程语言的语义分析程序。 与第5章不同,本章没有包含对语义分析程序生成器(semantic analyzer generator)或构造语 义分析程序的通用工具的描述。尽管已经构造了许多这样的工具,但没有 个能得到广泛的使 用且能用于Lex或Yacc。在本章最后的“注意与参考”一节中,我们提及了几个这样的工具, 并为感兴趣的读者提供了参考文款。 6.1属性和属性文法 届性(attribute)是编程语言结构的任意特性。属性在其包含的信息和复杂性等方面变化很大, 特别是当它们能确定时翻译/执行过程的时间。属性的典型例子有: ·变量的数据类型。 ·表达式的值。 ·存储器中变量的位置 ·程序的目标代码。 ·数的有效位数。 可以在复杂的处理(甚至编译程序的构造)之前确定属性。例如,一个数的有效位数可以根 据语言的定义确定(或者至少给出一个最小值)。属性也可以在程序执行期间才确定,如(非常 数)表达式的值,或者动态分配的数据结构的位置。属性的计算及将计算值与正在讨论的语言 结构联系的过程称作属性的联编(binding)。联编属性发生时编译/快行过程的时间称作联编时间 (binding time)。不同的属性变化,甚至不同语言的相同属性都可能有完全不同的联编时间。在 执行之前联编的属性称作静态的(static),而只在执行期间联编的属性是动态的(dynamic)。对于 编译程序编写者而言,当然对那些在翻译时联编的动态属性感兴趣。 考虑先前给出的属性表的示例。我们时论表中每个属性在编译时的联编时间和重要性 ·在如C或Pascali这样的静态类型的语言中,变量或表达式的数据类型是一个重要的编译时 属性。类型检查器(type checker)是一个语义分析程序,它计算定义数据类型的所有语言 理的语言最有用,它表明程序的语义内容与它的语法密切相关。所有的现代语言都有这个特性。 然而,编译程序的编写者通常必须根据语言手册手工构造属性文法,因为语言设计者很少为之 提供。更糟糕的是,由于坚持语言清晰的语法结构,属性文法的构造会有不必要的复杂性。语 义计算表达式的一种更好标准是抽象语法,就像抽象语法树表示的那样。但是抽象语法树的说 明通常也由语言设计者留给了编译程序编写者。 语义分析实现的算法也不像语法分析算法那样能清晰地表达。这部分原因也是因为在考虑 语义分析说明时,出现了刚刚提及的同样的问题。还有另外一个问题,它是由编译过程中分析 的时间选择引起的。如果语义分析可以推迟到所有的语法分析 (以及抽象语法树的构造)完成之 后进行,那么实现语义分析的任务就相当容易,其本质上由指定对语法树遍历的一个顺序组成, 同时在遍历中每次遇到节点时进行计算。这就意味着编译程序必须是多遍的。另一方面,如果 必须要求编译程序在一遍中完成所有的操作 (包括代码生成),那么语义分析的实现就更加会变 成寻找计算语义信息的正确顺序和方法的特别的过程 (假定这样的顺序实际存在 )。当然,现代 的惯例越来越允许编译程序编写者使用多遍扫描简化语义分析和代码生成的过程。 尽管有点扰乱语义分析的状态,研究属性文法和规范发布仍是特别有用的,因为这能从写 出更加清晰、简练、不易出错的语义分析代码中得到补偿,同时代码也更加易懂。 因此,本章从研究属性和属性文法开始。接下来是通过属性文法说明实现计算的技术,包 括推断与树的遍历相连的计算顺序。随后的两节集中于语义分析的两个主要方面:符号表和类 型检查。最后一节讲述前一章介绍的T I N Y编程语言的语义分析程序。 与第5章不同,本章没有包含对语义分析程序生成器 (semantic analyzer generator)或构造语 义分析程序的通用工具的描述。尽管已经构造了许多这样的工具,但没有一个能得到广泛的使 用且能用于L e x或Ya c c。在本章最后的“注意与参考”一节中,我们提及了几个这样的工具, 并为感兴趣的读者提供了参考文献。 6.1 属性和属性文法 属性( a t t r i b u t e )是编程语言结构的任意特性。属性在其包含的信息和复杂性等方面变化很大, 特别是当它们能确定时翻译/执行过程的时间。属性的典型例子有: • 变量的数据类型。 • 表达式的值。 • 存储器中变量的位置。 • 程序的目标代码。 • 数的有效位数。 可以在复杂的处理(甚至编译程序的构造)之前确定属性。例如,一个数的有效位数可以根 据语言的定义确定 (或者至少给出一个最小值 )。属性也可以在程序执行期间才确定,如 (非常 数)表达式的值,或者动态分配的数据结构的位置。属性的计算及将计算值与正在讨论的语言 结构联系的过程称作属性的联编( b i n d i n g )。联编属性发生时编译/执行过程的时间称作联编时间 (binding time)。不同的属性变化,甚至不同语言的相同属性都可能有完全不同的联编时间。在 执行之前联编的属性称作静态的( s t a t i c ),而只在执行期间联编的属性是动态的( d y n a m i c )。对于 编译程序编写者而言,当然对那些在翻译时联编的动态属性感兴趣。 考虑先前给出的属性表的示例。我们讨论表中每个属性在编译时的联编时间和重要性。 • 在如C或P a s c a l这样的静态类型的语言中,变量或表达式的数据类型是一个重要的编译时 属性。类型检查器(type checker)是一个语义分析程序,它计算定义数据类型的所有语言 第 6章 语 义 分 析 1 9 9 下载
<<向上翻页向下翻页>>
©2008-现在 cucdc.com 高等教育资讯网 版权所有