编译器设计-有限自动机

Compiler Design - Finite Automata

有限自动机是一种状态机,它以一串符号作为输入,并相应地改变其状态。有限自动机是正则表达式的识别器。当正则表达式字符串被输入到有限自动机中时,它会为每个文本更改其状态。如果输入字符串成功处理并且自动机达到其最终状态,则接受它,即刚刚输入的字符串被认为是当前语言的有效标记。

有限自动机的数学模型包括:

Finite
set of states (Q)
Finite
set of input symbols (Σ)
One
Start state (q0)
Set
of final states (qf)
Transition
function (δ)

设L(r)是有限自动机(FA)识别的正则语言。

状态States:FA的状态用圆圈表示。状态名写在圆圈里。

开始状态Start state:自动机开始的状态,称为开始状态。开始状态有一个箭头指向它。

中间状态Intermediate states :所有中间状态至少有两个箭头;一个指向外,另一个指向内(自己)。

最终状态Final state:如果成功解析输入字符串,则自动机应处于此状态。最终状态用双圆表示。它可能有任意奇数个指向它的箭头和偶数个指向它的箭头。奇数箭头的数目比偶数大一个,即奇数=偶数+1。

转换Transition:当在输入中找到所需的符号时,从一个状态转换到另一个状态。在转换时,自动机可以移动到下一个状态,也可以保持在相同的状态。从一个状态到另一个状态的移动显示为定向箭头,箭头指向目标状态。如果自动机保持在相同的状态,则会绘制一个从状态指向自身的箭头。

Example : We assume FA accepts any three digit binary value
ending in digit 1. FA = {Q(q0, qf), Σ(0,1), q0, qf, δ}

语法分析或分析是编译器的第二个阶段。在本章中,我们将学习构造解析器时使用的基本概念。

我们已经看到,词法分析器可以借助正则表达式和模式规则来识别标记。但是由于正则表达式的限制,词法分析器无法检查给定句子的语法。正则表达式无法检查平衡标记,如括号。因此,这个阶段使用上下文无关语法(CFG),这是由下推自动机识别的。

另一方面,CFG是正则语法的超集,如下所示:

这意味着每一种规则语法都是上下文无关的,但也存在一些超出规则语法范围的问题。CFG是描述编程语言语法的有用工具。

上下文无关语法Context-Free Grammar

在本节中,我们将首先看到上下文无关语法的定义,并介绍用于解析技术的术语。
上下文无关语法有四个组成部分:

一组非终端(V)。非终结符是表示字符串集的语法变量。非终端定义字符串集,帮助定义由语法生成的语言。

一组标记,称为终端符号(∑)。终端是构成字符串的基本符号。

一组产品(P)。语法的产生指定了终端和非终端可以组合成字符串的方式。每个产品都由一个称为产品左侧的非终端、一个箭头和一系列令牌和/或终端(称为产品右侧)组成。
其中一个非终端被指定为开始符号;从那里开始生产。

字符串是从开始符号派生的,方法是重复地将非终端(最初是开始符号)替换为生产的右侧(对于该非终端)。

例子

我们讨论回文语言的问题,它不能用正则表达式来描述。也就是说,L={w | w=wR}不是常规语言。但可以通过CFG来描述,如下所示:

G = ( V, Σ, P, S )

其中

V = { Q, Z, N }Σ = { 0, 1 }P = { Q → Z | Q → N | Q → ℇ | Z → 0Q0 | N → 1Q1 }S = { Q }

此语法描述回文语言,如:1001、11100111、00100、1010101、11111等。

语法分析器syntax analyzer

语法分析器或解析器以令牌流的形式接受词法分析器的输入。解析器根据生产规则分析源代码(令牌流),以检测代码中的任何错误。这个阶段的输出是一个解析树。

这样,解析器完成两个任务,即解析代码、查找错误和生成解析树作为阶段的输出。
即使程序中存在错误,解析器也需要解析整个代码。解析器使用错误恢复策略,我们将在本章后面学习。

派生Derivation

派生基本上是一系列产生式规则,以便获取输入字符串。在解析过程中,我们对某些句子形式的输入做出两个决定:

决定要更换的非终端。

决定生产规则,用它来代替非终端。

要决定用生产规则替换哪个非终端,我们可以有两个选择。

最左端派生 Left-most Derivation

如果从左到右扫描并替换输入的句子形式,则称之为最左派生。由最左边派生出来的句子式叫做左边的句子形式。

最右派生

如果我们Right-most Derivation

从右到左扫描并用产生式规则替换输入,则称为最右派生。从最右边派生出来的句子形式叫做右边的句子形式。

例子

生产规则

E → E + EE → E * EE → id

Input string: id + id * id

The left-most derivation is:

E → E * EE → E + E * EE → id + E * EE → id + id * EE → id + id * id

请注意,最左边的非终端总是先处理。

最正确的推导是:

E → E + EE → E + E * EE → E + E * idE → E + id * idE → id + id * id

Parse Tree

请注意,最左边的非终端总是先处理。

解析树

解析树是派生的图形描述。可以方便地看到字符串是如何从开始符号派生的。派生的开始符号将成为解析树的根。让我们从上一个主题的一个例子来看这个问题。

我们取a+b*c的最左边的导出

最左边的推导是:

E → E * EE → E + E * EE → id + E * EE → id + id * EE → id + id * id




在解析树中

All
leaf nodes are terminals.
All
interior nodes are non-terminals.
In-order
traversal gives original input string.

所有叶节点都是终端。

所有内部节点都不是终端。

按顺序遍历给出原始输入字符串。

按顺序遍历给出原始输入字符串。解析树描述运算符的关联性和优先级。最深的子树首先遍历,因此该子树中的运算符优先于父节点中的运算符。

模棱两可

如果语法G对于至少一个字符串有多个解析树(左派生或右派生),则称它是不明确的。

Example

E → E + EE → E – EE → id

对于字符串id+id–id,上面的语法生成两个解析树:

由歧义语法生成的语言被称为天生的歧义。语法中的歧义不利于编译器构造。没有一种方法能够自动检测和消除歧义,但是可以通过重新编写整个语法而不产生歧义,或者通过设置和遵循关联性和优先约束来消除歧义。

关联性Associativity

如果一个操作数的两边都有运算符,则运算符接受此操作数的那一边由这些运算符的关联性决定。如果操作是左关联的,则操作数将由左运算符执行;如果操作是右关联的,则右运算符将执行操作数。

例子

加法、乘法、减法和除法等运算是左关联的。如果表达式包含:

id op id op id

it will be evaluated as:

(id op id) op id

例如,(id+id)+id

指数运算之类的运算是右关联的,即同一表达式中的求值顺序为:

id op (id op id)

For example, id ^ (id ^ id)

优先Presedence

如果两个不同的运算符共享同一个操作数,则由运算符的优先级决定哪个将成为该操作数。也就是说,2+34可以有两个不同的解析树,一个对应于(2+3)4,另一个对应于2+(34)。通过设置运算符之间的优先级,可以很容易地解决此问题。如上例所示,数学上(乘法)优先于+(加法),因此表达式2+3*4将始终解释为:

2 + (3 * 4)

这些方法减少了语言或语法中的歧义。

左递归 Left Recursion

如果语法有任何非终端“A”,其派生包含“A”本身作为最左边的符号,则语法将变为左递归。对于自顶向下的解析器来说,左递归语法被认为是一个有问题的情况。自上而下的解析器从开始符号开始解析,开始符号本身是非终端的。因此,当解析器在派生过程中遇到同一个非终端时,就很难判断何时停止解析左边的非终端,从而进入无限循环。

Example:

(1) A => Aα | β (2) S => Aα | β A => Sd

(1) 是立即左递归的一个例子,其中A是任何非终端符号,α表示一个非终端字符串。
(2) 是间接左递归的一个例子。

自上而下的解析器将首先解析A,然后A将产生一个由A本身组成的字符串,解析器可能永远进入一个循环。

删除左递归

删除左递归的一种方法是使用以下技术:

生产

A => Aα | β

is converted into following productions

A => βA’A’=> αA’ | ε这不会影响从语法派生的字符串,但会删除立即左递归。
第二种方法是使用下面的算法,它应该消除所有直接和间接的左递归。START Arrange non-terminals in some order like A1, A2, A3,…, An for each i from 1 to n
{ for each j from 1 to i-1
{
replace each production of form Ai ⟹Aj

编译器设计-有限自动机相关推荐

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

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

  2. 编译器设计-代码生成

    编译器设计-代码生成 Compiler Design - Code Generation 代码生成可以看作是编译的最后阶段.通过后代码生成,优化过程可以应用到代码上,但这可以看作是代码生成阶段本身的一 ...

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

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

  4. 编译器设计-RunTime运行时环境

    编译器设计-RunTime运行时环境 Compiler Design - Run-Time Environment 作为源代码的程序仅仅是文本(代码.语句等)的集合,要使其活动,它需要在目标计算机上执 ...

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

    编译器设计-自下而上分析器-误差恢复-语义分析 Compiler Design - Bottom-Up Parser Compiler Design - Error Recovery Compiler ...

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

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

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

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

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

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

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

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

最新文章

  1. 设计模式-扩展-父类对子类的要求
  2. C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻
  3. Apache优化——日志管理
  4. QPW 行政区划字典表(td_area)
  5. 联想340c笔记本cpu能升级吗_联想扬天威6 2021款酷睿版怎么样?评测值得买吗?从价格和配置看就知道了...
  6. Apache Log4j2远程JNDI代码执行漏洞修复
  7. TARS 微服务开源生态
  8. 拓端tecdat|Stata 中Mata的st_view函数 - 小心使用!
  9. call及apply的用法理解
  10. linux mongo 添加用户名和密码,mongodb3.4 安装及用户名密码设置
  11. linux I2C读写应用程序
  12. ImageAI (一) 使用Python快速简单实现图像内容预测 Image Prediction
  13. gbk与gb2312并不一样
  14. win10记得pin码 重置密码登录
  15. 这次,多地消防控制室双人值守可变单人值守
  16. “新元宇宙”奇科幻小说原创作品系列连载《地球人奇游天球记》第三回零点惊魂
  17. 【经典】对static关键字深入理解
  18. BPR: Bayesian Personalized Ranking from Implicit Feedback 论文笔记
  19. 花了5000元改了一个带触摸板的小红点键盘
  20. Motorola S19(S-record)格式解析

热门文章

  1. Myeclipse中修改项目默认编码还是乱码?一步永久解决!
  2. 【Docker】容器的几种网络模式
  3. 2021-2027年中国涂装行业市场需求预测与投资战略规划分析报告
  4. mysql64如何配置_win7 64位下如何安装配置mysql-winx64(安装记录)
  5. 2022-2028年中国玫瑰花行业市场研究及前瞻分析报告
  6. LeetCode简单题之判断句子是否为全字母句
  7. TensorRT-8量化分析
  8. 智能驾驶操作系统OS
  9. OpenCV读写图像文件解析
  10. 多实例gpu_MIG技术快速提高AI生产率