程序设计语言与编译原理_第九章语义分析和中间代码生成

合集下载

编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成在编译原理中,语义分析是编译器的重要组成部分之一,它负责验证和处理源代码中的语义信息,为后续的中间代码生成做准备。

本文将介绍语义分析的基本概念和流程,并探讨中间代码生成的相关技术。

一、语义分析的基本概念和流程语义分析是指对源代码进行语义检查和语义信息提取的过程。

其主要目标是确保源代码在语义上是正确的,并从中提取出各种语义信息,以便后续阶段使用。

语义分析的基本流程如下:1. 词法分析和语法分析:在进行语义分析之前,需要先对源代码进行词法分析和语法分析,以便将代码转化为具有结构的中间表示形式(如抽象语法树)。

2. 符号表的构建:符号表是语义分析的重要数据结构,用于存储程序中出现的各种标识符及其相关信息,如类型、作用域等。

在语义分析阶段,需要构建符号表并实时更新。

3. 类型检查:类型检查是语义分析的核心任务之一。

它通过对表达式、赋值语句、函数调用等进行类型推导和匹配,来验证程序是否存在类型错误。

4. 语义规则检查:除了类型检查外,语义分析还需要检查程序是否符合语言规范中的其他语义规则,如变量是否已声明、函数调用是否正确等。

5. 语义信息提取:语义分析还负责提取源代码中的各种语义信息,如函数调用关系、变量的定义和引用关系、控制流信息等。

这些信息将为后续的代码优化和代码生成提供依据。

二、中间代码生成的相关技术中间代码是指某种形式的中间表示形式,通常与源代码和目标代码之间存在一定的映射关系。

它在编译过程中起到连接前后两个阶段的桥梁作用,并且可以进行一些优化。

常见的中间代码形式之一是三地址码。

三地址码是一种低级的代码表示形式,每条指令最多包含三个操作数。

它具有简洁明了的特点,适合进行后续的优化工作。

在进行中间代码生成时,需要考虑以下几个方面的技术:1. 表达式的翻译:在将源代码转化为中间代码时,需要将源代码中的表达式进行翻译。

这包括对表达式的计算顺序、运算符优先级等方面的处理。

2. 控制流的处理:在编译过程中,需要将源代码中的控制流转化为中间代码中的条件分支和循环结构。

编译原理 语义分析和中间代码的产生

编译原理 语义分析和中间代码的产生

n 语义分析的概念:源程序经过词法分析、语法分析后,表明该源程序书写正确、符合程序语言所规定的语法,但语法分析并未对程序内部的逻辑含义加以分析,因此编译程序接着进行语义分析,即审查每个语法成分的静态语义。

如果静态语义正确,则生成与该语言成分等效的中间代码,或直接生成目标代码。

直接生成机器语言或汇编语言形式的目标代码的优点是编译时间短且无需中间代码到目标代码的翻译,而生成中间代码的优点是使编译结构在逻辑上更为简单明确,特别是使目标代码的优化较易实现。

语义分析进行的语义检查有两类:动态语义检查和静态语义检查。

动态语义检查需生成相应的目标代码,在运行时进行;静态语义检查在编译时进行。

教学要求n 掌握:n 1. 逆波兰式, DAG图, 抽象语法树, 三地址代码, 三元式, 四元式等中间代码表示;n 2. 简单赋值语句的翻译, 带数组元素引用的赋值句的翻译;n 3. 布尔表达式的翻译, 控制语句中布尔表达式的翻译;n 4. 控制语句的翻译。

n 了解理解:说明语句的翻译,过程调用和参数的处理。

教学内容n 7.1 中间语言n 后缀式,DAG,三地址码(四元式,三元式,间接三元式)n *7.2 说明语句的翻译n 7.3 赋值语句的翻译,数组元素引用的翻译n 7.4 布尔表达式的翻译n 求布尔式值的翻译,作为控制条件的翻译n 7.5 控制语句的翻译n if , while , goto , casen 7.6 过程调用的处理, 参数传递的处理n *7.7 类型检查(不作要求,不讲)7.1 中间语言n 要掌握几种中间语言的基本结构:n 逆波兰表示即后缀式n 抽象语法树n DAG图n 三地址代码(四元式、三元式、间接三元式)7.1.1 后缀式n 波兰逻辑学家卢卡西维奇(Lukasiewicz)发明的一种表示法,又称逆波兰式表示法。

n 后缀式这种方法是,把运算量(操作数)写在算符的前面,把算符写在运算量的后面(后缀)。

编译原理中间代码生成

编译原理中间代码生成

编译原理中间代码生成在编译原理中,中间代码生成是编译器的重要阶段之一、在这个阶段,编译器将源代码转换成一种中间表示形式,这种中间表示形式通常比源代码抽象得多,同时又比目标代码具体得多。

中间代码既能够方便地进行优化,又能够方便地转换成目标代码。

为什么需要中间代码呢?其一,中间代码可以方便地进行编译器优化。

编译器优化是编译器的一个核心功能,它能够对中间代码进行优化,以产生更高效的目标代码。

在中间代码生成阶段,编译器可以根据源代码特性进行一些优化,例如常量折叠、公共子表达式消除、循环不变式移动等。

其二,中间代码可以方便地进行目标代码生成。

中间代码通常比较高级,比目标代码更具有表达力。

通过中间代码,编译器可以将源代码转换成与目标机器无关的形式,然后再根据目标机器的特性进行进一步的优化和转换,最终生成目标代码。

中间代码生成的过程通常可以分为以下几步:1.词法分析和语法分析:首先需要将源代码转换成抽象语法树。

这个过程涉及到词法分析和语法分析两个步骤。

词法分析将源代码划分成一个个的词法单元,例如标识符、关键字、运算符等等。

语法分析将词法单元组成树状结构,形成抽象语法树。

2.语义分析:在语义分析阶段,编译器会对抽象语法树进行静态语义检查,以确保源代码符合语言的语义规定。

同时,还会进行类型检查和类型推导等操作。

3.中间代码生成:在中间代码生成阶段,编译器会将抽象语法树转换成一种中间表示形式,例如三地址码、四元式、特定的中间代码形式等。

这种中间表示形式通常比较高级,能够方便进行编译器的优化和转换。

4.中间代码优化:中间代码生成的结果通常不是最优的,因为生成中间代码时考虑的主要是功能的正确性,并没有考虑性能的问题。

在中间代码生成之后,编译器会对中间代码进行各种优化,以产生更高效的代码。

例如常量折叠、循环优化、死代码删除等等。

5.中间代码转换:在完成了中间代码的优化之后,编译器还可以对中间代码进行进一步的转换。

这个转换的目的是将中间代码转换成更具体、更低级的形式,例如目标机器的汇编代码。

编译原理中的中间代码生成

编译原理中的中间代码生成

编译原理中的中间代码生成编译原理是计算机科学的一门重要课程。

在编译器的构造过程中,中间代码生成是其核心部分之一。

它是将源代码翻译为目标代码的重要中间阶段。

中间代码生成的过程涉及到链表、树,生成三元式、四元式等多种中间形式。

本文将介绍中间代码生成的过程和其在编译中的作用。

一、中间代码的概念中间代码是指在源程序和目标程序之间所生成的一系列指令的集合。

目标代码是指机器可执行的二进制代码,而中间代码则是一种可传递、可处理和可修改的编译代码形式。

中间代码属于一种中间状态,它不是源代码也不是目标代码,但可以被转换成目标代码。

中间代码可以基于语法树、语法分析栈、语法分析表进行生成,生成的中间代码需要满足语言语法结构和语义规则。

二、中间代码生成的流程在编译过程中,中间代码生成是指将源代码转换成中间代码的过程。

它是在词法分析、语法分析和语义分析阶段之后完成的。

下面介绍一下中间代码生成的流程。

1.源代码转换为语法树编译器通过词法分析和语法分析将源代码转换成语法树。

语法树是一种树形结构,它记录了源代码中各个语句的组成情况。

2.语法树进行语义分析在语法分析之后,编译器进行语义分析,检查语法树的合法性,然后根据语言的语义规则对语法树进行标注。

标注的内容包括符号表信息、数据类型等。

3.中间代码的生成在语义分析后,编译器进入中间代码的生成阶段,生成语句的中间代码。

中间代码通常采用三元式或四元式等形式。

三元式包含操作符、操作数以及结果的地址,四元式中还包括了类型信息。

4.中间代码优化在中间代码生成的过程中,编译器会尽可能地优化中间代码。

可以对中间代码进行多种优化,如常量合并、变量替换、公共子表达式消除等。

5.中间代码转换为目标代码在中间代码生成后,编译器将中间代码转换为目标代码。

目标代码可以是汇编代码或机器代码等不同形式的二进制代码。

三、中间代码生成优化的意义编译器中间代码优化的目标是提高程序的执行效率和降低其资源消耗。

执行效率的提高可以通过以下方式实现:1.减少内存使用编译器可以通过删除冗余代码、去除死代码和不必要的变量等方式来减少中间代码的内存使用。

编译原理中的语法分析与中间代码生成

编译原理中的语法分析与中间代码生成

编译原理中的语法分析与中间代码生成编译原理是计算机科学中一门非常重要的学科,主要研究将高级语言翻译成机器语言的方法和技术。

其中,语法分析和中间代码生成是编译器实现的两个重要步骤。

一、语法分析语法分析是编译器将源代码转换成抽象语法树的过程。

在这个阶段,编译器会检查源代码的语法是否符合语言规范,并将代码转化为一系列的语法结构。

一个好的语法分析器能够快速准确地识别代码中的语言结构,同时能够在出现语法错误的时候给出有意义的错误报告。

常见的语法分析方法包括LL(1)分析、LR分析等。

LL(1)分析器通过构造预测分析表来实现分析,而LR分析器则采用自底向上的分析方法,通过状态迁移来实现分析。

在语法分析的过程中,编译器还需要处理语法的优先级,如算术运算符的优先级,逻辑运算符的优先级等。

对于不同的语言规范,将有不同的算法来处理语法。

例如,C语言中的运算符优先级和结合性与其他语言不同,因此需要特殊的处理方式。

二、中间代码生成中间代码生成是语法分析后的下一步,它的作用是将抽象语法树转化为中间表示,通常是三地址码或四地址码。

中间代码可以看作是目标代码的前一步,它是一种更加抽象的代码形式,方便后续的优化和翻译。

中间代码的生成方法有很多种,最常用的是遍历抽象语法树并根据语法结构生成中间代码。

不同的语言规范会对中间代码的生成方式有不同的要求。

例如,Java语言规范对着重于类型检查和异常处理的中间代码生成,而C语言的中间代码生成则着重于指针和数组的处理等。

在生成中间代码的过程中,编译器还需要考虑优化问题。

编译器能够在生成中间代码的时候进行一些基本的优化,例如删除冗余代码、常量合并等等,这样可以减少目标代码的大小和程序的运行时间。

总之,语法分析和中间代码生成是编译器实现的两个关键步骤。

它们需要一个好的算法和优秀的实现方式,以便在编译过程中产生高效、可靠的目标代码。

编译原理课件07语义分析和中间代码产生

编译原理课件07语义分析和中间代码产生

语义分析阶段中的关键问题和 挑战
语义分析阶段面临着许多关键问题和挑战,例如识别复杂的语义错误、处理 不完整的代码等。
在处理大型程序时,编译器需确保语义分析的效率和准确性,并能处理各种 语法结构。
中间代码的定义和作用
中间代码是一种介于高级语言和底层机器代码之间的形式,它是一种可读性 较强且易于生成和优化的表示。
语义分析的基本任务和目标
语义分析的主要任务是识别和验证程序中的语义错误,例如类型不匹配、变量未定义等。 它的目标是确保程序的语义是一致的,以便于理解和执行。语义语义分析使用了各种技术和方法,包括符号表、类型检查、控制流分析等。 符号表用于记录变量和函数的信息,类型检查用于比较表达式和操作数的类 型是否一致。 控制流分析用于检测条件语句、循环语句和函数调用等代码块的流程。
编译原理课件07语义分析 和中间代码产生
在这一节中,我们将学习关于语义分析和中间代码产生的定义、概述以及它 们在编译过程中的作用。我们将探讨语义分析的任务、方法和挑战,以及中 间代码产生的基本原理和实际应用。
语义分析和中间代码产生的定义和概述
语义分析是编译过程中的重要阶段,用于分析程序的意义和语法结构,并生成中间代码。中间代码产生是将高 级语言代码转换为更低级的可执行形式的过程。 在这一阶段,编译器将检查语法的正确性和静态语义的正确性,以确保程序在执行时没有语法错误。 语义分析和中间代码产生是编译器的核心部分,它们直接影响了程序的性能和可读性。
中间代码作为编译器和解释器的输入,是程序在执行前的一个中间阶段,并 可用于代码优化和跨平台编译。
中间代码产生的基本原理和方法
中间代码产生的基本原理是将程序的语义结构转换为一系列指令序列,这些指令不依赖于具体的计算机体系结 构。 中间代码生成的方法包括源代码到抽象语法树的转换、语法树到中间代码的转换等。

编译原理-语义分析和中间代码生成

编译原理-语义分析和中间代码生成
编译原理-语义分析和中 间代码生成
编译器是一种将高级语言翻译成低级语言的程序。语义分析和中间代码生成 是编译器中非常重要的两个步骤。在本次演讲中,我们将深入探讨它们的内 容和作用。
定义和目的
1 语义分析
对代码的意义和上下文进行全面的分析。
2 目的
识别出语法正确但不符合语言规范的代码,以及提取中间代码。
检查和错误
1
步骤
类型检查、控制流检查、错误信息收集。
2
类型
变量未声明、数组维数不符、类型不匹配、函数参数个,中断代码生成流程。
中间代码生成
概述
表示形式
将源代码翻译为一种可读性和 可执行性都比较好的中间代码。
三元式、四元式、静态单赋值 形式。
算法
递归下降法、语法制导翻译、 继承型翻译。
实例和案例分析
实例
对表达式 "a = b + c * d" 进行语义分析和中 间代码生成。
案例
使用LLVM对C语言代码生成中间代码。
总结
语义分析
中间代码生成
全面分析代码以及上下文,发现不符合语言规 范的代码。
将源代码翻译为可读性和可执行性都比较好的 中间代码。
“Your code isn't wrong, it's just not right yet.” "If you can't run with the big dogs, stay on the porch."

编译原理语义分析与中间代码生成

编译原理语义分析与中间代码生成

产生式的语义描述
(1)A→i:=E { p=lookup(); if (p==NULL) error(); else emit(p ’=’ E.place)} (2) E→E(1)+E(2) {E.place=newtemp(); emit(E.place ’=’ E(1).place ’+’ E(2).place)} (3)E→E(1)*E(2) {E.place=newtemp(); emit(E.place ’=’ E(1).place ’*’ E(2).place)} (4) E→-E(1) {E.place=newtemp(); emit(E.place ’=’’uminus’ E(1).place)} (5)E→(E(1)) {E.place ’=’ E(1).place} (6)E→i { p=lookup(); if (p==NULL) error(); else E.place=p}
中间代码

中间代码(Intermediate code ):
源程序的一种内部表示,不依赖目标机的结构,
易于机械生成目标代码的中间表示。

几种中间语言
后缀式(逆波兰表示法) 三地址代码
四元式 三元式 间接三元式 树
后缀式

表达式的一种表示形式
运算符直接跟在运算量后面
又称为逆波兰表示法

有穷的属性集有穷的属性集每个属性与一个文法符号相关联每个属性与一个文法符号相关联这些属性代表与文法符号相关的语义信息这些属性代表与文法符号相关的语义信息如类型地址值代码符号表内容等等如类型地址值代码符号表内容等等属性与变量一样可以进行计算和传递属性与变量一样可以进行计算和传递属性加工的过程即是语义处理的过程属性加工的过程即是语义处理的过程属性加工与语法分析同时进行属性加工与语法分析同时进行属性的表示

程序设计语言与编译原理_第九章语义分析和中间代码生成

程序设计语言与编译原理_第九章语义分析和中间代码生成
• 中间语言(复杂性界于源语言和目标语言 之间)的好处:
– 便于进行与机器无关的代码优化工作 – 易于移植 – 使编译程序的结构在逻辑上更为简单明确
Compiler
Compiler
源语言 Front End 中间语 Back End 目标语
程序
言程序
言程序
10
程序设计语言与编译
• 常用的中间语言:
找包含它的最小switch、while或for语句方可找到
转向点,否则出错。
(3) 一致性检查
如在相同作用域中标识符只能说明一次、
case语句的标号不能相同、函数调用参数个数要相同
等。
程序设计语言与编译
常见的语义错误
声明和使用相关的语义错误 –标识符没有声明; –重复声明;
如何检查? –每当遇到新声明的标识符,查符号表
– 后缀式,逆波兰表示 – 图表示: DAG、抽象语法树 – 三地址代码
• 三元式 • 四元式 • 间接三元式
11
程序设计语言与编译
四元式形式: (op,ARG1,ARG2,RESULT) op—运算符 ARG1—第一运算量 ARG2—第二运算量 RESULT—结果
程序设计语言与编译 如: A:=-B*(C+D)
形如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
» 如果当前有效的所有标识符中有相同名字的,则 是重复声明错误;

编译原理语义分析和中间代码生成

编译原理语义分析和中间代码生成
语义分析是编译过程中的一个关键阶 段,主要负责对源代码进行语义检查, 确保其符合语言的语法和语义规则。
在语义分析阶段,编译器会检查源代 码中是否存在类型错误、未定义的变 量和函数、不符合控制流规则的语句
等。
语义分析的主要任务包括类型检查、 函数和变量的解析、控制流的检查等。
如果发现错误,编译器会报错并停止 编译过程;如果没有发现错误,编译 器将继续生成中间代码。
02 中间代码生成
中间代码生成概述
中间代码是源代码和目标代码之间的代 码形式,用于表示源程序的结构和语义
信息。
中间代码生成是编译过程的一个重要阶 中间代码生成可以提高编译器的灵活性
段,它把源代码转换成一种更接近于机 和可移植性,因为中间代码与具体的机
器语言的代码形式,以便进行后续的优 器语言无关,可以在不同的平台上使用
代码优化
编译器通过优化技术 对源代码进行优化, 以提高生成代码的执 行效率,减少运行时 间。
代码分析
编译原理还可以用于 代码分析,检查代码 的语法、语义和结构, 发现潜在的错误和漏 洞。
程序理解
编译原理可以帮助理 解程序的内部结构和 行为,为程序修改、 重构和优化提供支持。
编译原理的发展趋势
静态分析
在语法分析阶段,编译器根据 语言的语法规则将词素或标记 组合成一个个的语法结构,如 表达式、语句、程序等。
语义分析阶段是在语法分析的 基础上,对这些语法结构进行 语义检查和语义处理。
语义分析的例子
01
02
假设有以下C语言代码 ```c
03
int a = "hello";
04
```
05
在语义分析阶段,编译 器会发现变量a被赋值为 一个字符串字面量,而 字符串字面量是字符数 组类型的值,因此会报 错,因为整型变量不能 赋值为字符数组类型的 值。

理学09第9章 语义分析和代码生成

理学09第9章 语义分析和代码生成
例如,对于算术表达式 F*3.1416*R*(H+R)
可转换成波兰后缀表示: F3.1416*R*HR+*
对于赋值表达式:S=F*3.1416*R*(H+R)
可转换为:SF3.1416*R*HR+*=
9.2.1波兰后缀表示
波兰后缀表示除可用来表示表达式类的语言结构以外,也能够通过操作 符的扩充来表示其他的语言结构。增加相应的操作符就可以表示条件转 移、下标变量语法单位的语言结构。 例如,条件语句:if <expr> then <stmt1> else <stmt2> 可转换成波兰后缀表示:
9.2.1波兰后缀表示
波兰后缀表示是使用较早并且流行至今的一种中间代码形式。对于 波兰后缀表达式,处理起来比较容易。在将中缀表达式转换成波兰 后缀表示的算法中,设置一个操作符栈,当扫描到操作数时,就立 即输出该操作数。当遇到操作符时,则要与栈顶操作符比较其优先 级,若栈顶操作符优先级高于栈外操作符,则输出该栈顶操作符; 反之,则栈外操作符入栈。而对于赋值表达式,只需定义赋值操作 符“=”的优先级低于可在表达式中出现的其他操作符,那么可使用 同一算法将其转换成波兰后缀表示。
4)使用中间代码的主要缺点是编译的效率比直接产生机器码编译的效率要低一些。 中间代码的选择也是一个重要的研究课题。人们期望能找到这样的一种中间语言, 它即适合于将各种高级程序设计语言翻译成这种中间语言,又能比较方便地将这 种中间语言翻译成各种类型机器的目标语言。目前,中间代码有很多种,下面介 绍几种常见的中间代码。
(1) *,W, X
(2) +,Y, Z
(3) +,(1),(2)
9.2.2 N-元表示
对三元式序列中的每一个三元式都编上号码,且对前面三元式的计算结果 的引用可用在括号内加上三元式的编号来表示。 例如,条件语句if (X>Y)Z=X;else Z=Y+1; 可以用如下三元式序列表示: (1) -,X,Y (2) BMZ,(1),(5) (3) =,Z,X (4) BR, ,(7) (5) +,Y,1 (6) =,Z,(5)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为每个产生式配上一个语义子程序,完成语义检查和 语义处理:在语法分析过程中,当用一个产生式进行 匹配或归约时,就调用相应的语义程序进行翻译。
语义检查和语义处理 核心是生成相应的中间代码
程序设计语言与编译
三、语义值
在描述语义动作时,需要赋予每个文法符号以各种不 同的“值”,这些值统称为“语义值”.如,“类型”, “种属”,“地址”或“代码”等。通常用 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语句的标号不能相同、函数调用参数个数要相同
等。
程序设计语言与编译
常见的语义错误
声明和使用相关的语义错误 –标识符没有声明; –重复声明;
如何检查? –每当遇到新声明的标识符,查符号表
相关文档
最新文档