编译器设计-自下而上分析器-误差恢复-语义分析

Compiler Design - Bottom-Up Parser

Compiler Design - Error Recovery

Compiler Design - Semantic Analysis

一.Compiler Design - Bottom-Up Parser

自底向上的解析从树的叶节点开始,向上工作直到到达根节点。在这里,我们从一个句子开始,然后以相反的方式应用产生式规则,以达到开始符号。下面给出的图像描述了可用的自下而上的解析器。

移位减少分析

Shift-reduce解析使用两个独特的步骤进行自底向上的解析。这些步骤称为移位步骤和减少步骤。

移位步骤:移位步骤是指输入指针向前移动到下一个输入符号,称为移位符号。这个符号被推到堆栈上。移位的符号被视为解析树的单个节点。

Reduce step:当解析器找到一个完整的语法规则(RHS)并将其替换为(LHS)时,称为reducestep。当堆栈顶部包含句柄时发生这种情况。为了减少,在堆栈上执行POP函数,该函数从句柄弹出,并用LHS非终端符号替换它。

LR分析器

LR解析器是一个非递归、移位减少、自底向上的解析器。它使用了大量的上下文无关语法,这使得它成为最有效的语法分析技术。L R解析器也称为LR(k)解析器,其中L表示从左到右扫描输入流;R表示反向构造最右边的派生,k表示要做出决策的先行符号的数量。

有三种广泛使用的算法可用于构造LR解析器:

SLR(1)
– Simple LR Parser:

Works on smallest class of grammar Few number of states, hence very small table Simple and fast construction

LR(1) – LR Parser:

Works on complete set of LR(1) Grammar Generates large table and large number of states Slow construction

LALR(1) – Look-Ahead LR Parser:

Works on intermediate size of grammar
Number of states are same as in SLR(1)

LR解析算法

这里我们描述一个LR解析器的骨架算法:

token = next_token()

repeat forever

s = top of stack

if action[s, token] = “shift si” then

  PUSH tokenPUSH si token = next_token()

else if action[s, token] = “reduce A::= β“ then

  POP 2 * |β| symbolss = top of stackPUSH APUSH goto[s,A]

else if action[s, token] = “accept” then

  return

else

  error()

LL vs. LR

二.Compiler Design - Error Recovery

解析器应该能够检测并报告程序中的任何错误。当遇到错误时,解析器应该能够处理它并继续解析其余的输入。大多数情况下,解析器需要检查错误,但在编译过程的各个阶段可能会遇到错误。一个程序在不同阶段可能有以下几种错误:

词法:某个标识符的名称键入不正确

语法:缺少分号或括号不平衡

语义:不兼容的值赋值

逻辑:代码不可访问,无限循环

可以在解析器中实现四种常见的错误恢复策略来处理代码中的错误。

紧急模式

当解析器在语句中的任何地方遇到错误时,它将忽略语句的其余部分,不处理从错误输入到分隔符(如分号)的输入。这是最简单的错误恢复方法,而且还可以防止解析器开发无限循环。

语句模式

当解析器遇到错误时,它会尝试采取纠正措施,以便语句的其余输入允许解析器提前解析。例如,插入一个缺少的分号,用分号替换逗号等等。解析器设计者在这里必须小心,因为一个错误的更正可能导致无限循环。

错误产品

编译器设计器知道代码中可能出现的一些常见错误。此外,设计人员可以创建要使用的扩充语法,作为在遇到错误时生成错误构造的产品。

整体校正

解析器将手边的程序视为一个整体,并试图找出程序的意图,并试图找出与之最接近的匹配项,这是无错误的。当错误的输入(语句)X被馈送时,它会为某个最接近的无错误语句Y创建一个解析树。这可能允许解析器对源代码进行最小的更改,但由于此策略的复杂性(时间和空间),它尚未在实践中实现。

抽象语法树

解析树表示不容易被编译器解析,因为它们包含的细节比实际需要的多。以下面的解析树为例:

如果仔细观察,我们会发现大多数叶节点都是父节点的单个子节点。在将信息传送到下一阶段之前,可以消除这些信息。通过隐藏额外信息,我们可以获得如下所示的树:

Abstract tree can be represented as:

ASTs是编译器中重要的数据结构,具有最少的不必要信息。ASTs比解析树更紧凑,编译器可以很容易地使用它。

三.Compiler Design - Semantic Analysis

在语法分析阶段,我们学习了解析器如何构造解析树。在那个阶段构造的纯解析树通常对编译器没有用处,因为它不携带任何关于如何计算树的信息。上下文无关语法的产生,决定了语言的规则,不适应如何解释它们。

For example

E → E + T

上面的CFG产品没有与之相关联的语义规则,它无法帮助理解产品。

语义学

语言的语义为其结构提供了意义,如标记和语法结构。语义有助于解释符号、它们的类型以及它们之间

CFG + semantic rules = Syntax Directed Definitions

For example:

int a = “value”;

不应在词汇和语法分析阶段出现错误,因为它在词汇和结构上都是正确的,但应在赋值类型不同时产生语义错误。这些规则由语言的语法设定,并在语义分析中进行评估。语义分析应完成以下任务:

范围分辨率

类型检查

数组绑定检查

语义错误

我们已经提到了一些语义分析器需要识别的语义错误:

类型不匹配

未声明的变量

保留标识符误用。

作用域中变量的多重声明。

访问范围外变量。

实际参数与形式参数不匹配。

属性语法

属性语法是上下文无关语法的一种特殊形式,它将一些附加信息(属性)附加到一个或多个非终端,以提供上下文敏感信息。每个属性都有定义良好的值域,如integer、float、character、string和expressions。

属性语法是为上下文无关语法提供语义的一种媒介,它可以帮助指定编程语言的语法和语义。属性语法(当被视为解析树时)可以在树的节点之间传递值或信息。

Example:

E → E + T { E.value = E.value + T.value }

CFG的右边部分包含语义规则,这些规则指定如何解释语法。这里,将非终端E和T的值相加,结果被复制到非终端E。

语义属性可以在解析时从其域中分配给其值,并在分配或条件时进行计算。根据属性获取值的方式,它们可以大致分为两类:合成属性和继承属性。

综合属性

这些属性从其子节点的属性值中获取值。为了说明这一点,假设以下产品:

S → ABC

如果S从它的子节点(A、B、C)中获取值,则它被称为合成属性,因为ABC的值被合成为S。

如前一个示例(E→E+T)所示,父节点E从其子节点获取其值。合成属性从不从其父节点或任何同级节点获取值。

继承的属性

与合成属性不同,继承属性可以从父属性和/或兄弟属性中获取值。在接下来的制作中,

S → ABC

A可以从S、B和C中获取值。B可以从S、A和C中获取值。同样,C可以从S、A和B中获取值。

扩展:根据语法规则将非终端扩展为终端时

归约:根据语法规则将一个终端归约为其对应的非终端。语法树从上到下和从左到右进行分析。每当进行约简时,我们都会应用相应的语义规则(动作)。

语义分析使用语法导向的翻译来执行上述任务。

语义分析器从其前一阶段(语法分析)接收AST(抽象语法树)。

语义分析器将属性信息附加到AST中,称为属性AST。

属性是两个元组值,<attribute name,attribute value>

For example:

int value = 5;<type, “integer”><presentvalue, “5”>

对于每个产品,我们都附加一个语义规则。

S属性SDT

如果SDT只使用合成属性,则称为S属性SDT。这些属性使用S属性的SDTs进行评估,这些sdt在产品(右侧)之后编写语义操作。

如上所述,S属性的sdt中的属性在自下而上的解析中求值,因为父节点的值依赖于子节点的值。

L属性SDTs

这种形式的SDTs既使用合成属性,也使用继承属性,并且限制不从正确的兄弟节点获取值。

在L属性的SDTs中,非终端可以从其父节点、子节点和同级节点获取值。在下面的生产中

S → ABC

S可以取A、B和C(合成)的值。A只能从S获取值。B可以从S获取值,A可以从S、A和B获取值。任何非终端都不能从其右边的同级中获取值。

L属性SDT中的属性是通过深度优先和从左到右的解析方式计算的。

我们可以得出结论,如果一个定义是S属性的,那么它也是L属性的,因为L属性的定义包含S属性的定义。

编译器设计-自下而上分析器-误差恢复-语义分析相关推荐

  1. 编译器设计-解析类型

    编译器设计-解析类型 Compiler Design - Types of Parsing 语法分析器遵循由上下文无关语法定义的产生式规则.生成规则的实现方式(派生)将解析分为两种类型:自上而下解析和 ...

  2. 编译器设计-有限自动机

    编译器设计-有限自动机 Compiler Design - Finite Automata 有限自动机是一种状态机,它以一串符号作为输入,并相应地改变其状态.有限自动机是正则表达式的识别器.当正则表达 ...

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

    编译器设计-符号表-中间代码生成 Compiler Design - Symbol Table Compiler - Intermediate Code Generation 一.Compiler D ...

  4. 毕业设计 c语言编译器的设计开发-字节代码格式设计与实现 开题报告,C语言编译器设计与实现...

    C语言编译器设计与实现(任务书,外文翻译,毕业论文20000字,答辩PPT) 摘 要 随着计算机的广泛应用,计算机程序设计语言也从初期的机器语言发展为汇编语言,以及现在的各种高级程序设计语言.而编译技 ...

  5. 最严谨的计算机语言p,用于PLC的华P语言编译器设计及实现.pdf

    2009年10月 沈阳理工大学学报 V01.28No.5 OFSHENYANGUGONGUNIVERSITYOct.2 第28卷第5期 TRANSACTIONS 0 09 文章编号:1003-1251 ...

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

    编译器设计-符号表-中间代码生成 Compiler Design - Symbol Table Compiler - Intermediate Code Generation 一.Compiler D ...

  7. c 语言编译器 论文,毕业论文--C语言编译器设计与实现.doc

    太原理工大学毕业设计(论文)用纸 太 原 理 工 大 学 毕业设计(论文)任务书 第1页 毕业设计(论文)题目: C语言编译器设计与实现 毕业设计(论文)要求及原始数据(资料): 1.C语言简介和国内 ...

  8. c语言编译器2017,2016-2017年本科C语言编译器设计与实现毕业论文设计.doc

    北京邮电 大 学 毕业设计(论文)任务书 第1页 毕业设计(论文)题目: C语言编译器设计与实现 毕业设计(论文)要求及原始数据(资料): 1.C语言简介和国内外编译器技术研究现状: 2.深入了解编译 ...

  9. 编译器设计-代码优化

    编译器设计-代码优化 Compiler Design - Code Optimization 优化是一种程序转换技术,它试图通过使代码消耗更少的资源(如CPU.内存)来改进代码,并提供高速. 在优化中 ...

最新文章

  1. 线性表之顺序表(C语言实现)
  2. logrotate 进行nginx日志分割
  3. ML之Hog_HammingDistance:基于Hog特征提取“RGB”图像的768个值的单向vector利用汉明距离算法进行判别
  4. 基于聚类算法的文本热点问题挖掘算例实现(文本聚类)
  5. VTK:vtkActor2D用法实战
  6. leetcode 58. 最后一个单词的长度(C语言)
  7. MyEclipse内存溢出问题
  8. spring的service不启动事务的配置。
  9. 【Linux系统编程学习】 GCC编译器
  10. tty,串口,控制台与驱动程序
  11. 【CodeForces-1041C】Coffee Break(贪心,STL,set二分维护,题意难,有坑,SJ题,构造)(知识点总结)
  12. c语言fread malloc,流操作之读写(fread、fwrite、fopen、malloc)
  13. 晋职称不考外语 计算机,评职称不考外语计算机的价值导向
  14. 360压缩电脑版_震惊!360竟然出了一款这么良心的软件
  15. xlsx文件打开乱码_xlsx文件怎么打开乱码
  16. STM32F7通过QSPI驱动W25Q256芯片
  17. 抢食生鲜,美团最大对手会是拼多多
  18. ANSI颜色使用研究 (转)
  19. 人工智能欠缺对语言和情感的理解和处理能力
  20. NO.35——qq音乐全站分布式爬虫(一)

热门文章

  1. idea中如何打开RunDashboard窗口,微服务最实用设置
  2. 【Kaggle Learn】Python 5-8
  3. php会话的销毁和退出,销毁PHP会话
  4. java写游戏的聊天怎么写_怎么用JAVA编写一个打字游戏
  5. HA: InfinityStones靶机渗透测试
  6. 【Springboot】日志
  7. 实践学习:首次项目合作
  8. 配置动态路由协议OSPF
  9. 【tensorflow】】模型优化(一)指数衰减学习率
  10. MindInsight训练可视整体设计介绍