编译原理
  • 编译原理
  • 一些简答题
  • 绪论
    • 编译器简介
    • 程序设计语言
    • 静态与动态
    • 参数传递机制
  • 词法分析
    • 词法单元、模式、词素
    • 串和语言
    • 正则表达式
    • 状态转换图
    • 不确定有穷自动机NFA
    • 确定有穷自动机DFA
    • 算法:正则表达式转NFA
    • 自动机到词法分析器
  • 语法分析
    • 语法分析器
    • 上下文无关文法
    • 二义性和左递归
    • 递归下降语法分析
    • 算法:求解FIRST集和FOLLOW集
    • 算法:LL(1)
    • 自底向上语法分析
    • 移入-归约语法分析
    • 算法:LR(0)
    • 算法:SLR(1)
    • 算法:LR(1)
    • 算法:LALR
    • LR分析器和LALR分析器
  • 语法制导
    • 语法制导定义(SDD)
    • 综合属性和继承属性
    • 语法树上的SDD求值
    • 依赖图
    • L属性的SDD
    • 类型
    • SDD的应用
  • 中间代码生成
    • 三地址代码
    • SSA(静态单赋值)
    • 类型和声明
    • 表达式的翻译
    • 类型检查
    • 控制流
    • 回填
  • 运行时刻环境
    • 存储组织
    • 栈式分配
    • 栈中非局部数据的访问
    • 堆管理
    • 垃圾回收
  • 代码生成
    • 代码生成器的设计
    • 目标语言
    • 目标代码中的地址
    • 基本块和流图
    • 基本块的优化
Powered by GitBook
On this page
  • LR(0)
  • SLR(1)
  • LR(1)
  • LALR
  1. 语法分析

LR分析器和LALR分析器

Previous算法:LALRNext语法制导定义(SDD)

Last updated 4 months ago

LR(0)

不存在冲突项目(移入-归约冲突、归约-归约冲突),存在则不是LR(0)文法。

SLR(1)

存在冲突状态(移入-归约),通过求解follow集来缓解冲突的发生。如果移入项目点后的那个终结符和归约项目左部的终结符的follow集的交集不是空集,则存在冲突。

LR(1)

存在冲突项目(移入-归约,归约-归约),通过向前看符号来解决。如果移入项目点后的那个终结符和归约项目的向前看符号的交集不是空集,则存在冲突。

添加项时,将期望的向前看符号也加入项中,成为LR(1)项集,向前看符号串的长度即为LR(k)中的k,这个做法可以充分利用向前看符号,但是状态很多。LR(1)项中包含更多信息来消除一些归约动作,实际的做法相当于分裂一些LR(0)状态,精确指明应该何时归约。

LALR

SLR(1)语法分析表的分析能力较弱,LR(1)语法分析表的状态数量很大。LALR(1)是实践中常用的方法,状态数量和SLR(1)的状态数量相同,能够方便地处理大部分常见程序设计语言的构造。

LALR分析技术的基本思想是寻找具有相同核心的LR(1)项集,并将它们合并称为一个项集(项目的核心就是项的第一分量的集合),一个LR(1)项集的核心是一个LR(0)项集。

原来无冲突的LR(1)分析表在合并之后得到LALR(1)分析表,新表中可能存在冲突。合并不会导致移入-归约冲突,但是合并会引起归约-归约冲突,即不确定按照哪个产生式进行归约。

处理语法正确的输入时,LALR语法分析器和LR语法分析的动作序列完全相同。虽然栈中的状态名字不同,但是状态序列之间有对应关系。比如LR分析器压入状态I,那么LALR分析器压入I对应的合并项集。

LALR的技术本质:对LR(1)项集规范族中的同核心项集进行合并,这样使得分析表保持了LR(1)项中的向前看符号信息,又使得状态数减少到与SLR分析表一样多。

移入-归约冲突