编译器设计-符号表-中间代码生成

Compiler Design - Symbol Table

Compiler - Intermediate Code Generation

一.Compiler Design - Symbol Table

符号表是编译器为存储变量名、函数名、对象、类、接口等各种实体的出现情况而创建和维护的一种重要的数据结构。符号表既可用于编译器的分析部分,也可用于编译器的综合部分。 符号表可用于以下目的,具体取决于所使用的语言:

将所有实体的名称以结构化形式存储在一个位置。

以验证是否已声明变量。

要实现类型检查,请验证源代码中的赋值和表达式在语义上是否正确。

确定名称的作用域(作用域解析)。

符号表只是一个可以是线性表或哈希表的表。它以以下格式为每个名称维护一个条目:

<symbol name, type, attribute>

例如,如果符号表必须存储有关以下变量声明的信息:

static int interest;

然后它应该存储条目,例如:

<interest, int, static>

attribute子句包含与名称相关的条目。

实施Implementation

如果编译器要处理少量数据,那么符号表可以实现为无序列表,这很容易编码,但它只适用于小表。符号表可以通过以下方式之一实现:

线性(排序或未排序)列表

二叉搜索树

哈希表

其中,符号表主要实现为哈希表,其中源代码符号本身被视为哈希函数的键,返回值是关于符号的信息。

操作Operations

符号表(线性或哈希)应提供以下操作。

插入()

此操作在分析阶段使用得更频繁,即编译器的前半部分,其中标识了标记并将名称存储在表中。此操作用于在符号表中添加有关源代码中出现的唯一名称的信息。存储名称的格式或结构取决于手头的编译器。

源代码中符号的属性是与该符号关联的信息。此信息包含有关符号的值、状态、范围和类型。函数的作用是:将符号及其属性作为参数,并将信息存储在符号表中。

For example:

int a;

应该由编译器处理为should be processed by the compiler as:

insert(a, int);
查找()
lookup()操作用于搜索符号表中的名称以确定:
如果符号存在于表中。
如果在使用前声明。
如果在作用域中使用了该名称。
如果符号已初始化。
如果符号声明了多次。
lookup(symbol)
lookup()函数的格式因编程语言而异。基本格式应符合以下要求:
如果符号表中不存在该符号,则此方法返回0(零)。如果符号存在于符号表中,则返回存储在表中的其属性。
范围管理
编译器维护两种类型的符号表:一种全局符号表,它可以被所有过程访问,另一种是为程序中的每个作用域创建的作用域符号表。
为了确定名称的范围,符号表按层次结构排列,如下例所示:
. . .
int value=10;void pro_one(){int one_1;int one_2;{              int one_3;      |_  inner scope 1 int one_4;      | }              /int one_5; {                 int one_6;      |_  inner scope 2int one_7;      |}              /}void pro_two(){int two_1;int two_2;{              int two_3;      |_  inner scope 3int two_4;      |}              /int two_5;}
. . .
上述程序可以用符号表的层次结构表示:

全局符号表包含一个全局变量(int值)的名称和两个过程名称,这些名称应该对上面显示的所有子节点都可用。pro_one symbol表(及其所有子表)中提到的名称不适用于pro_two symbol及其子表。
此符号表数据结构层次结构存储在语义分析器中,当需要在符号表中搜索名称时,将使用以下算法进行搜索:
首先在当前范围内搜索一个符号,即当前符号表。
如果找到名称,则搜索完成,否则将在父符号表中搜索,直到,
找到该名称或已在全局符号表中搜索该名称。

二.Compiler - Intermediate Code Generation

一个源代码可以直接翻译成它的目标机器代码,那么我们为什么要把源代码翻译成一个中间代码,然后再翻译成它的目标代码呢?让我们看看需要中间代码的原因。

如果编译器在没有生成中间代码的选项的情况下将源语言转换为目标机器语言,那么对于每台新机器,都需要一个完整的本机编译器。
中间代码通过保持所有编译器的分析部分相同,消除了对每台唯一计算机使用新的完整编译器的需要。
编译器的第二部分,synthesis,是根据目标机器而改变的。
通过在中间代码上应用代码优化技术,可以更容易地应用源代码修改来提高代码性能。
中间表示法Intermediate Representation
中间代码可以用多种方式表示,它们有自己的优点。
高级别的IR-高级别的中间代码表示非常接近源语言本身。它们可以很容易地从源代码生成,我们可以很容易地应用代码修改来提高性能。但对于目标机优化,则不太可取。
低级别的IR-这是一个接近目标机器,这使得它适合于寄存器和内存分配,指令集选择等。这是一个很好的机器相关的优化。
中间代码可以是特定于语言的(例如,Java的字节码)或独立于语言的(三地址码)。
三地址码 Three-Address Code
中间代码生成器以带注释的语法树的形式接收来自其前一阶段语义分析器的输入。然后,可以将该语法树转换为线性表示法,例如后缀表示法。中间代码往往是与机器无关的代码。因此,代码生成器假设有无限数量的内存存储(寄存器)来生成代码。

For example:

a = b + c * d;
中间代码生成器将尝试将此表达式划分为子表达式,然后生成相应的代码。
r1 = c * d;
r2 = b + r1;
a = r2
r用作目标程序中的寄存器。
一个三地址码最多有三个地址位置来计算表达式。三地址码可以用两种形式表示:四位和三位。
四倍Quadruples
四位数表示中的每条指令分为四个字段:operator、arg1、arg2和result。以上示例以四位数格式表示如下:

三元组
三元组表示中的每条指令都有三个字段:op、arg1和arg2。各子表达式的结果由表达式的位置表示。三元组表示与DAG和语法树的相似性。它们在表示表达式时等价于DAG。

三元组在优化时面临代码不可移动的问题,因为结果是位置的,更改表达式的顺序或位置可能会导致问题。
间接三元组
此表示是对三元组表示的增强。它使用指针而不是位置来存储结果。这使优化器能够自由地重新定位子表达式以生成优化的代码。
声明 Declarations
变量或过程在使用之前必须声明。声明涉及内存空间的分配以及符号表中类型和名称的输入。一个程序的编码和设计可以考虑到目标机器的结构,但可能并不总是能够准确地将源代码转换成目标语言。
将整个程序作为过程和子过程的集合,就可以声明过程的所有本地名称。内存分配是以连续的方式完成的,名称是按照在程序中声明的顺序分配给内存的。我们使用offset变量并将其设置为零{offset=0},表示基址。
源程序设计语言和目标机器体系结构的名称存储方式可能不同,因此使用相对寻址。当从内存位置0{offset=0}开始分配第一个名称时,后面声明的下一个名称应该在第一个名称旁边分配内存。
例子:
我们以C语言为例,其中一个整数变量被分配2字节的内存,一个浮点变量被分配4字节的内存。
int a;
float b;Allocation process:
{offset = 0}int a;id.type = intid.width = 2offset = offset + id.width
{offset = 2}float b;id.type = floatid.width = 4offset = offset + id.width
{offset = 6}
要在符号表中输入此详细信息,可以使用过程enter。该方法可以具有以下结构:
enter(name, type, offset)
此过程应在符号表中为变量名创建一个条目,将其类型设置为类型,并在其数据区域中设置相对地址偏移量。

设计一个处理两种类型地址的地址簿程序_编译器设计-符号表-中间代码生成相关推荐

  1. 设计一个处理两种类型地址的地址簿程序_短信平台的API接口都有哪些类型?

    在这里以 SUBMAIL API 接口为例,解读下接口短信的分类和特点: SUBMAIL 的API 功能是基于云端的通信接口,用户通过接入和集成 API 就可以方便.高效地使用云通信功能,不需要先投入 ...

  2. 计算机辅助布置设计软件的两种类型,桥梁计算机辅助设计软件WYCAD介绍

    摘要:桥梁辅助设计软件WYCAD简介及简支梁(板)桥.连续刚构桥.斜拉桥.拱桥.下部构造及一些实用小程序等模块介绍. 关键字:WYCAD模块功能介绍 前言 计算机辅助桥梁设计能极大地提高设计人员的效率 ...

  3. 设计一个扩展自抽象类geometricobject的新的triangle类_面向对象设计原则之开放封闭原则(开闭原则OCP)...

    (1) 定义 一个软件实体(类.模块.函数等),对于扩展是开放的,对于更改是封闭的. 对于扩展是开放的:这意味着模块的行为是可以扩展的.当应用的需求发生改变时,我们可以对模块进行扩展,比如增加新的类或 ...

  4. 创建一个银行账户的继承层次,表示银行的所有客户的账户。每个客户都能在他们的银行账户存钱,取钱。但是账户可以分为更具体的两种类型,例如,依靠存款生息的存储账户SavingsAccount类,另一种就是信

    不要自卑,去提升实力 互联网行业谁技术牛谁是爹 如果文章可以带给你能量,那是最好的事!请相信自己 加油o~ 创建一个银行账户的继承层次,表示银行的所有客户的账户.每个客户都能在他们的银行账户存钱,取钱 ...

  5. 创建一个银行账户的继承层次,表示银行的所有客户的账户。每个客户都能在他们的银行账户存钱,取钱。但是账户可以分为更具体的两种类型,例如,依靠存款生息的存储账户SavingsAccount类

    关联与继承练习题 题目: 源码: Account(账户)类: CheckingAccount(信用卡)类: SavingsAccount(借记卡)类: Person(用户)类: Transaction ...

  6. M.2 固态硬盘的两种类型:SATA 和 NVMe 的区别?

    参考 https://www.kingston.com.cn/cn/solutions/pc-performance/two-types-m2-vs-ssd 前言 在存储技术领域,当我们讨论 M.2 ...

  7. 对两种类型的蘑菇图像进行识别与分类——使用SVM分类器(matlab)

    该项目已免费开源!点个收藏和赞吧!https://gitee.com/zhengzsj/mushroom-classification-system-based-on-matlab-image-pro ...

  8. 在c语言程序设计中函数有两种类型 和,在C语言程序设计中函数有两种类型:__________和__________...

    在C语言程序设计中函数有两种类型:__________和__________ 以下程序的输出结果是()intA:6B:3C:2D:1 红楼梦中提到的名菜有A:酒酿清蒸鸭子B:奶油松瓤卷酥C:四喜丸子D ...

  9. FLASH中的BOOT Sectored 和 Uniform Sectored两种类型的区别和联系

    关注+星标公众号,及时获取更多技术分享~  作者 | 冰茶奥利奥 微信公众号 | 嵌入式电子创客街 前天有一个同事过来问我一个问题,就是他们一直在生产的一个板卡上的一篇镁光的芯片停产了,问我用这系列的 ...

最新文章

  1. node.js(一)
  2. WindowsSdkDir 从何处来?
  3. javafx 打开新窗口_新的JMetro JavaFX 11兼容版本
  4. GIS基础知识汇总篇(五)-无人机真正射影像的概念和制作原理
  5. PhpStorm之操作数据库
  6. 数字滤波器(二)--最小相位延时系统和全通系统
  7. 跨链永续衍生品协议AntiMatter完成150万美元种子轮融资,NGC领投
  8. wps中下划线怎么也去不掉_黑头究竟怎么形成的?为什么总是去不掉?那是因为你用错方法...
  9. 厚积薄发 - 关于runtime的几个问题
  10. 2019年数据库系统工程师上午真题及答案解析
  11. 安卓开发中wifi连接打印机打印图片
  12. python 标准库: csv
  13. 高中计算机课简单介绍,高中课程介绍
  14. 考研二战上岸985的经验教训分享
  15. IT信息考证人,证书记得要延续 ITSS CISAW CISP PMP CISSP 证书延续 有效期
  16. Laya页面嵌套和Scene.destory导致的Bug
  17. 第1章第8节:如何删除、复制和隐藏幻灯片 [PowerPoint精美幻灯片实战教程]
  18. docker内应用连接宿主机mysql
  19. 【Python+OpenCV 图像透视变换 warpPerspective函数】
  20. u盘显示请插磁盘f_为什么总是认不到U盘,打开显示成“请插入磁盘驱动器F”.

热门文章

  1. 【Python】判断列表 list 是否为空
  2. 【Leetcode】岛屿问题(数量,周长,面积)
  3. [云炬创业基础笔记]第七张创业资源测试12
  4. PHP一行命令打印当前系统时间
  5. 一个原来知道却懵懂好久的道理2017-12-08
  6. 吐血整理!10 个机器学习教程汇总,爱可可推荐!
  7. 手机qpython下载_QPython
  8. bootsect.s文件阅读问题集
  9. docker 上关于hyper-v和wsl2的一些要点
  10. 试分析下列程序段:请选择(L1、L2、L3或L4)填入相应的括弧中