1.语义分析
语义分析可以分为两类。
第1类是程序的分析,要求根据编程语言的规则建立其正确性,并保证其正确执行。对于不同的语言来说,语言定义所要求的这一类分析的总量变化很大。在LISP和Smalltalk这类动态制导的语言中,可能完全没有静态语义分析;而在A d a这类语言中就有很强的需求,程序必须提交执行。其他的语言介于这两种极端情况之间(例如 Pascal 语言,不像A d a和C对静态语义分析的要求那样严格,也不像 LISP 那样完全没有要求)。
语义分析的第2类是由编译程序执行的分析,用以提高翻译程序执行的效率。这一类分析通常包括对“最优化”或代码改进技术的讨论。
这两类分析也不是相互排斥的,因为与没有正确性要求的语言相比,如静态类型检查这样的正确性要求能使编译程序产生更加有效的代码。另外,值得注意的是,这里讨论的正确性要求永远不能建立程序的完全正确性,正确性仅仅是部分的。但这样的要求仍然是有用的,可以给编程人员提供一些信息,提高程序的安全性和有效性。
1.1 属性和属性文法
属性( attribute)是编程语言结构的任意特性。属性在其包含的信息和复杂性等方面变化很大,特别是当它们能确定时翻译/执行过程的时间。
属性直接与语言的文法符号相联系(终结符号或非终结符号) 。如果X是一个文法符号,a 是X的一个属性,那么我们把与X关联的a的值记作X.a。
属性的典型例子有:
• 变量的数据类型。
• 表达式的值。
• 存储器中变量的位置。
• 程序的目标代码。
• 数的有效位数。
属性文法:
若有一个属性的集合a1 , . . . , ak ,语法制导语义的原理应用于每个文法规则X0→X1 X2 . . . X n(这里X0 是一个非终结符号,其他的Xi 都是任意符号),每个文法符号Xi 的属性Xi .aj 的值与规则中其他符号的属性值有关。每个关系用属性等式(或语义规则)表示:
Xi .aj = fij (X0.a1 , . . . , X0.ak ,X1.a1 , . . . , X1.ak , . . . , Xn .a1 , . . . , Xn .ak )
这里的 fij 是一个数学函数。属性a1 , . . . , ak 的属性文法(attribute grammar)是对语言的所有文法规则的所有这类等式的集合。
属性文法的表格表示:
1.2 继承属性和综合属性
综合属性用于自下而上传递信息,继承属性用于自上而下传递信息。