当前课程知识点:Compilers Techniques >  6 Intermediate Code Generation >  6.2 Declaration Statements >  6.2 Declaration Statements

返回《Compilers Techniques》慕课在线视频课程列表

6.2 Declaration Statements在线视频

下一节:7.1 Issues in the Design of Code Generator

返回《Compilers Techniques》慕课在线视频列表

6.2 Declaration Statements课程教案、知识点、字幕

各位同学大家好

这节课我们继续来学习

中间代码生成

这节课我们来学习声明语句

我们看到声明语句当中

我们需要为它在符号表当中

建立条目

为它来分配存储单元

然后我们在符号表当中

需要包含这个名字的类型

以及分配给它存储单元的相对地址

需要把这些信息记录下来

我们来看一个例子

假设我们有一个文法

P→D

D→T id ; D1

D→ε

那么我们希望在这个情况下

来计算过程当中

名字的类型和相对地址

我们看到在P→D 这条语句当中

在D之前

我们可以设计一下

相对变量的地址是offset

它的相对地址等于0

在第二条语句当中

D→T id ; D1

在D1之前

我们仍然需要向符号表中写入对应的变量

以及计算它的偏移地址

我们首先看

这里涉及到一个过程enter

这个过程为名字name

来建立它的符号表条目

所以我们在D1之前

需要为id来建立符号表条目

然后我们来计算它的偏移

那么偏移offset

等于原有的偏移offset加上T的宽度

T来决定id的类型

所以T来决定了id的宽度

接下来我们可以通过改写文法

让所有的语义动作

都出现在产生式的末尾

比如说 P→D

在D之前我们发现出现了一个语义动作

offset等于0

我们可以增加一个标记非终结符M

来改写文法

将它写为 P → MD

M → ε

然后在 M→ε 这个语句之后

我们引入offset=0这个语义动作

我们再从另一个例子

学习一下声明语句对应的语义动作

应该如何加入其中

我们先看一下这个文法

P是一个过程

P→D ; S

D是一个声明语句

S是对应的程序语句

D→D ; D

然后D→id : T

也就是D可以产生一个声明id的声明

T可以产生整型、实型、数组类型

或者是指针类型

接下来我们来看一下

它的声明语句

是如何来计算名字的类型和相对地址的

首先针对第一个产生式P→D ; S

我们知道在这种情况下

相对地址应该是0

所以在D之前

我们写入offset=0

针对第三行产生式D→id : T

我们知道,这个时候

出现了一个新的变量id

所以我们使用enter这个函数

将id写入到符号表中

然后我们来计算

当前新的偏移量offset

等于原有的偏移量offset加上T的宽度

T是id的类型

接下来T→integer

那么在这种情况下

我们只需要来计算T的长度和它的类型

所以T的类型T.type

等于integer

也就是整型

T的宽度等于4

下一个产生式是 T可以产生数组类型

在这种情况下

数组元素中

每一个的类型

都和T1的类型是一样的

然后它的宽度等于

T的宽度乘以数组元素的个数

对于最后一个产生式来说

T可以产生指针T1

那么它的类型是指针类型

它的宽度是4

接下来我们通过一个实例

来学习作用域信息的保存

我们先来看一下

我们所讨论语言的文法

P→D ; S

D→D ; D | id : T | proc id ; D ; S

那么我们是以快速排序的算法为例

来学习作用域信息的保存

我们首先来看一下

这是我们构造出来的符号表实例

那么这个符号表是

如何构造出来的呢?

首先我们来学习一下

符号表的特点

每一个过程

都需要有各自的符号表

符号表之间是双向链接的

构造符号表的时候

我们需要符号表的栈

构造符号表的时候

我们也需要用到活动记录的栈

接下来我们来学习一下

语义动作所涉及到的4个函数

首先是mktable这个函数

对于这个函数来说

我们需要去新构造一个符号表

并且返回新符号表的指针

其次是enter这个函数

我们需要在符号表table当中

指向的符号表中

为变量name

来建立一个对应的新条目

接下来是addWidth

那么我们用这个函数来计算

我们需要用到的宽度

也就是在table中

指向的符号表中

所有局部变量条目的累加宽度

记录在这个符号表的首部

最后我们用enterProc这个函数

来在table中指向的符号表中

为一个过程名name建立新的条目

接下来

我们通过快速排序的这段程序

来学习一下

如何构造符号表

首先我们去扫描程序

发现最外围是sort这个函数

而sort向外的指针是空的

那么对于第一个变量a来说

我们将它记录到符号表中

需要用到enter这个函数

当然X也需要用到enter这个函数

写入到对应的符号表中

接下来我们继续来读取快速排序的程序

我们会读取到readarray这个过程

读取到这个过程之后

我们首先会使用mktable

去来构造一个新的表

然后我们会使用enterProc这个函数

将readarray写入到我们的sort符号表中

接下来我们需要继续去读取程序

我们发现接下来

我们读到的是exchange这个过程

那么对于exchange来说

它同样是一个新的过程

我们仍然需要去构造一个新的符号表

然后我们需要将exchange

这个过程写入到

我们对应的符号表中

接下来我们发现

下一个函数是quicksort

那么quicksort也需要新构造一个符号表

然后quicksor和sort之间

是具有双向链接的

继续去读取快速排序程序

我们发现quicksort当中

包含partition这个函数

那么对于partition来说

我们仍然需要构造出它对应的符号表

然后写入到quicksort这个符号表中去

接下来我们来观察一下

对应的语义动作

首先P→M D ; S

那么我们为了将所有的语义动作

都写入到产生式的末尾

我们引入了第一个标记非终结符M

M→ε

那么M→ε 对应的语义动作

是去构造一个新的符号表

t=mktable(nil);

而此时这个符号表是

一个最外围的符号表

所以它的指针为空

然后我们去进行压栈的动作

所以有两个push

一个是将当前的指针压栈

另外一个是将当前的偏移量压栈

接下来我们来看一下第5行产生式

D→id : T

那么对于这个产生式来说

我们需要将id写入符号表中

所以我们调用了enter这个函数

然后我们需要读取栈顶的元素

所以我们用了top(offset)等于top(offset)加上T的宽度

接下来我们来看一下

第4个产生式

D→proc id ; N D1 ; S

我们需要去读取栈顶的元素

然后我们需要去计算

当前的地址偏移

也就是将

之前我们所压栈的数值取出来

来计算它的宽度

接下来我们将当前的这个过程

写入到对应的符号表中去

对于最后一个产生式N→ ε

我们仍然需要去新建一个符号表

并且把它的指针

指向前一个符号表

然后我们去执行压栈的动作

接下来我们来看一下

第一个产生式对应的动作

P→M D ; S

我们在这种情况下

需要去计算它的宽度

以及需要读取栈顶元素

我们观察到在其中

N也作为一个标记非终结符

使得我们将一个语义动作

写入到N→ ε

这个产生式的末尾

这一小节就到这

谢谢大家

Compilers Techniques课程列表:

1 Overview of Compilers Techniques

-1.1 Overview of Compilers Techniques

--Chapter 1 Overview of Compilers Techniques

--Overview of Compilers Techniques

2 Lexical Analysis

-2.1  Lexical Tokens, Strings and Language

--2.1  Lexical Tokens, Strings and Language

--2.1 Lexical Tokens, Strings and Language

-2.2  Regular form

--2.2 Regular form

--2.2 Regular form

-2.3  Finite automata

--2.3 Finite automata

--2.3 Finite automata

-2.4  DFA construction, Subset construction, Simpleset DFA

--2.4  DFA construction, Subset construction, Simpleset DFA

-2.5 Lex

--2.5 Lex

3 Syntax Analysis

-3.1 Context-free Grammars

--3.1.1 The Role of the Parser

--3.1.2 The Formal Definition of a Context-free Grammar

--3.1.3 Derivations

--3.1.4 Ambiguity

-3.2 Writing a Grammar

--3.2.1 Elimination of Left Recursion

--3.2.2 Left Factoring

--3.2 Top-Down Parsing

-3.3 Languages and Grammars

--3.3 Languages and Grammars

--3.3 Language and Grammars

-3.4 Top-Down Parsing

--3.4.1 First and Follow

--3.4.2 LL(1) Grammers

--3.4.3 Recursive Descent Analysis

--3.4.4 Nonrecursive Descent Analysis

-3.5 Bottom-up Parsing

--3.5.1 Reductions and Handle

--3.5.2 Shift- Reduce Parsing

--Bottom-up Parsing

-3.6 LR Parsing

--3.6.1 LR Parsing

--3.6.2 Viable Prefixes

--3.6.3 Simple LR

--3.6.4 LR(1)

--3.6.5 LALR

--3.6.6 Characteristics of LR Parsing

--3.6.7 Non Ambiguous and Not LR Context-Free Grammars

4 Syntax-Directed Translation

-4.1 Syntax-Directed Definitions

--4.1.1 Attribute Grammars

--4.1.2 Attribute Dependency Graphs and Ordering the Evaluation of Attributes

--Syntax-Directed Definitions

-4.2 Bottom-Up Calculation of S Attribute

--4.2.1 Bottom-Up Calculation of S-Attributed

--4.2.2 Stack Code

-4.3 L-Attributed Definitions

--4.3.1 L-Attributed Definitions

--4.3.2 Translation Schemes

--4.3.3 Design of Predictive Translator

--L-Attributed Definitions

-4.4 Bottom-Up Parsing of L-Attributed Translation

--4.4.1 Bottom-Up Parsing of L-Attributed Translation

--4.4.2 Simulate the Parsing of Inherited Properties

--Bottom-Up Parsing of L-Attributed Translation

5 Organization and Management of Run-Time Storage Space

-5.1 Overview

--5.1 Overview

--Overview

-5.2 Global Stack Storage

--5.2 Global Stack Storage

-5.3 Calling Sequences

--5.3 Calling Sequences

-5.4 Non Local Names

--5.4 Non Local Names and dynamic scope

--Non Local Name

6 Intermediate Code Generation

-6.1 Overview of Intermediate Code Generation

--6.1 Overview of Intermediate Code Generation

-6.2 Declaration Statements

--6.2 Declaration Statements

7 Code Generation

-7.1 Issues in the Design of Code Generator

--7.1 Issues in the Design of Code Generator

-7.2 Target Machine

--7.2 Target Machine

--Target Machine

-7.3 Basic Blocks and Flow Graphs

--7.3 Basic Blocks and Flow Graphs

-7.4 A Simple Code Generator

--7.4 A Simple Code Generator

8 Design and Implementation of a Simple Compiler

-8.1 Demonstration of Compiler Framework based on Python

--8.1 Demonstration of Compiler Framework based on Python

-8.2 Basic

--8.2.1 Scanner

--8.2.2 Parser -1LRItem

--8.2.3 Parser-2ActionGoto

--8.2.4 SA

-8.3 SimpleJava

--8.3 SimpleJava

6.2 Declaration Statements笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。