当前位置:
文档之家› 程序设计语言与编译原理_第九章语义分析和中间代码生成
程序设计语言与编译原理_第九章语义分析和中间代码生成
为每个产生式配上一个语义子程序,完成语义检查和 语义处理:在语法分析过程中,当用一个产生式进行 匹配或归约时,就调用相应的语义程序进行翻译。
语义检查和语义处理 核心是生成相应的中间代码
程序设计语言与编译
三、语义值
在描述语义动作时,需要赋予每个文法符号以各种不 同的“值”,这些值统称为“语义值”.如,“类型”, “种属”,“地址”或“代码”等。通常用 X.TYPE,X.CAT,X.VAL来表示这些值。
形如x:=y op z的赋值语句,op为二目算术
算符或逻辑算符;
赋值语句x:=op y,op为一元算符,如一元
减uminus, not, 移位及转换算符(如将定点 数转换为浮点数);
赋值语句x:=y; 无条件转移语句 goto L;
16
程序设计语言与编译
条件转移语句 if x relop y goto L 或 if a goto
动态语义检查
需要生成相应的目标代码,它是在运行时进行的;
例如:除零溢出错误。
静态语义检查
在编译时完成的,它涉及以下几个方面:
(1) 类型检查
(2) 控制流检查
(3) 一致性检查
程序设计语言与编译
(1) 类型检查
int x; float f(); x = f();
符合变量声明的语法、语义 符合函数声明的语法、语义 符合赋值语句的语法、不符合语义
得较为容易,但语义分析不像词法分析和
语法分析那样可以分别用正规文法和上下
文无关文法描述。
由于语义是上下文有关的,因此语
义的形式化描述是非常困难的,目前较为
常见的是用属性文法作为描述程序语言语
义的工具,并采用语法制导翻译的方法完
成对语法成分的翻译工作。
程序设计语言与编译 二. 语法制导翻译
语法制导翻译:在语法分析过程中,根据每个产生式对 应的语义子程序(语义动作)进行翻译(生成中间代码) 的方法称为语法制导翻译。
» 如果当前有效的所有标识符中有相同名字的,则 是重复声明错误;
» 否则生成它的属性信息,保存到符号表中;
–每当遇到标识符的使用,查符号表
» 如果没有找到,说明该标识符没有声明; » 否则, 得到该标识符的属性,进行进一步分析;
程序设计语言与编译
语义分析阶段只产生中间代码而不
生成目标代码的方法使编译程序的开发变
– 各种条件表达式的类型不是布尔类型; – 运算符的分量类型不相容; – 赋值语句左右类型不相容; – 形、实参类型不相容; – 函数说明和函数返回类型不相容;
– ……
程序设计语言与编译
(2) 控制流检查
用以保证控制语句有合法的转向点。如C语言
中不允许goto语句转入case语句流;break语句需寻
(@,B,_,t1)
翻译成:
(+,C,D,t2) (*,t1,t2,t3)
(:=,t3,_,A)
四元式出现顺序和表达式计值顺序一致; 四元式之间的联系通过临时变量来实现。
程序设计语言与编译
五、三地址代码
三地址代码是由下面一般形式的语句构 成的序列:x:=y op z,其中, x, y, z为名字、 常数或编译时产生的临时变量,op代表运算 符号,如定点运算符、浮点运算符、逻辑运 算符等,每个语句的右边只能有一个运算符, 如源语言表达式 x+yz可翻译为:
例: E→E+E E→0 E→1
E→E1+E2{E.VAL:=E1.VAL+E2.VAL} E→0{E.VAL:=1}
E→1{E.VAL:=0}
EE+EE+E+E…E+E+E+E…1+0+1+1+0 每使用一次产生式则调用相应的语义子程序,则推导完 成时,语义值E.VAL也计算出来。
程序设计语言与编译 四、中间代码
– 后缀式,逆波兰表示 – 图表示: DAG、抽象语法树 – 三地址代码
• 三元式 • 四元式 • 间接三元式
11
程序设计语言与编译
四元式形式: (op,ARG1,ARG2,RESULT) op—运算符 ARG1—第一运算量 ARG2—第二运算量 RESULT—结果
程序设计语言与编译 如: A:=-B*(C+D)
一致性检查: (1)表达式中操作数是否保持类型一致; (2)赋值语句的左右两边是否类型一致; (3)形、实参数类型是否一致; (4)数组元素与数组说明是否一致。
越界检查:数组下标是否越界;子界类型是否越界等等。
语义处理: 对说明语句:登记信息; 对可执行语句:生成中间代码。
程序设计语言与编译
语义分析时语义检查的分类:
程序设计语言与编译
第9章 语义分析和中间代码生成
本章主要讨论对语法正确的句子进行语义分析; 语义分析的目的是生成代码并实现句子的语义; 语义分析生成的不是最终的目标代码,而是便于 实现优化的某种中间代码;
程序设计语言与编译
第一节 语义分析概论
一. 语义分析的主要工作 语义检查: 主要进行一致性检查和越界检查。
T1:=y z
T2:=x + T1
14
程序设计语言与编译
三地址代码所表示的语句通常包含三个 地址,两个操作数,一个结果。实际实现时, 三地址代码中的名字将由指向符号表中相应 名字入口的指针所代替。
15
程序设计语言与编译 三地址语句类似汇编代码,可带有符号标号,
而且存在各种控制流语句,其种类大致有:
• 中间语言(复杂性界于源语言和目标语言 之间)的好处:
– 便于进行与机器无关的代码优化工作 – 易于移植 – 使编译程序的结构在逻辑上更为简单明确
Compiler
Compiler
源语言 Front End 中间语 Back End 目标语
程序
言程序
言程序
10
程序设计语言与编译
• 常用的中间语言:
L, relop为关系算符(<, =, >, <=, >=, < >等), a为布尔变量或常量;
过程调用语句 param x和call p, n,以及返
找包含它的最小switch、while或for语句方可找到
转向点,否则出错。符只能说明一次、
case语句的标号不能相同、函数调用参数个数要相同
等。
程序设计语言与编译
常见的语义错误
声明和使用相关的语义错误 –标识符没有声明; –重复声明;
如何检查? –每当遇到新声明的标识符,查符号表