Parsing 如何重写上下文无关语法,使其成为LR(1)?

Parsing 如何重写上下文无关语法,使其成为LR(1)?,parsing,context-free-grammar,shift-reduce-conflict,kleene-star,lr1,Parsing,Context Free Grammar,Shift Reduce Conflict,Kleene Star,Lr1,对于给定的上下文无关语法: S -> G $ G -> PG | P P -> id : R R -> id R | epsilon S → id G $ G → P G | P' P' → : R' P → : R R' → ε | id R' R → ε | id R 如何重写语法,使之成为LR(1) 当前语法在分析输入“id:.id”时存在shift/reduce冲突,其中“.”是分析器的输入指针。 该语法生成满足正则表达式(id:(id)*)的语言+

对于给定的上下文无关语法:

S -> G $
G -> PG | P
P -> id : R
R -> id R | epsilon
S  → id G $ 
G  → P G | P'
P' → : R'
P  → : R
R' → ε | id R'
R  → ε | id R
如何重写语法,使之成为LR(1)
当前语法在分析输入“id:.id”时存在shift/reduce冲突,其中“.”是分析器的输入指针。

该语法生成满足正则表达式(id:(id)*)的语言+

为同一种语言生成LR(1)语法非常容易。诀窍在于找到一个具有相似解析树的解析树,或者至少可以从中轻松恢复原始解析树

这是一个手动生成的语法,它比一般算法稍微简化。实际上,我们重写了正则表达式:

(id:id*)+
这就是LALR(1)

实际上,我们只是将所有的产品向右移动了一个标记,并且有一个通用的算法,可以用于从
LR(k+1)
语法为任何
k创建
LR(1)
语法≥1
。(我使用的算法版本来自S.Sippu&E.Soisalon Soininen的解析理论,第二卷,第6.7节。)

新语法的非终结符将采用
(x,V,y)
的形式,其中
V
是原始语法的符号(一个终结符或一个非终结符),并且
x
y
是最大长度
k
的终结符序列:

y ∈ FOLLOWk(V)
x ∈ FIRSTk(Vy)
对于每个
x∈ FIRSTk(S)
。然后,对于每一个产品

T → V0 V1 … Vm
由于新语法中的结果与旧语法中的结果之间存在明显的同态,因此我们可以直接创建原始解析树,尽管我们需要对语义值进行一些处理,以便将它们正确地附加到解析树上

S' → x (x, S, ε)
T → V0 V1 … Vm
(x0,T,xm+1) → (x0,V0,x1) (x1,V1,x2) … (xm,Vm,xm+1)
(Ax,A,xB) → B    if |x| = k
(Ax,A,x) → ε     if |x| ≤ k