今天讲解LR(0)SLR(1)LR(1)
伪代码
rust实现LALR(1) 我觉得实现LR(1)就够了, lalr(1)反而是负担
- 首先是
自底向上
分析过程:为一个输入串构造语法分析树的过程
- LR(k)分析技术:
- L:从左向右
- R: 反向构造一个最右推导序列
- k: 做出语法分析决定时向前看k个输入符号
- 当然在实践中我们只考虑
k=0或k=1
的情况
为啥要用LR语法分析器呢? LL不香吗?
- 几乎所有的程序语言, 只要能写出改语言的
上下文无关文法
, 就可以构造出相应的LR语法分析器. - LR无回溯, 很高效. @算符优先
- LR(k)分析能力强于LL(k)
- 总结一下. LR分析的优点
- 高性能
- 高能力
- 使用范围广
- 可自动生成
当然LR的缺点也是有的.
是时候拿出万年老二if c1 then if c2 then e2 else e3
来抬杠了.
但我们可以稍微改写成if c1 { if c2 {e2 } else {e3}}
.
还有手写LR分析是火葬场. 就比如我写的一个lalr分析器.
既然LR是移近归约
分析器. 那何时移近, 何时归约?
移近&归约
我们通过维护一些状态
, 来指导我们做出移近或归约的决定.
哦? 状态???
我们通过 A → X . Y Z A \rightarrow X.YZ A→X.YZ中点
的位置来表示当下状态.
点左边的是可以由 X X X推导得到的串, 点右边是接下来想看到一个能从 Y Z YZ YZ推导得到的串.
用状态的思想我们可以得出LR(0)自动机, 如图所示的例子
图并没有画完, 领会意思即可
这是一个自动机呀!
为啥可以使用LR(0)自动机来做出移近/归约
决定?
因为LR(0)自动机可以刻画出可能出现在分析器栈中的文法符号串.
即LR(0)自动机能识别可行前缀
对于一个可行前缀, 但前面有多条路怎么选?
可以查看下一个输入符号来解决.
SLR(1)
出现了!
SLR(1)与LR(0)的不同在于:
-
LR(0)
- if A → α . A \rightarrow \alpha.