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