消除左递归
快速消除左递归
原文法(保证 β \beta β不含 P P P): P → P α 1 ∣ P α 2 ∣ P α 3 ∣ . . . ∣ P α n ∣ β 1 ∣ β 2 ∣ β 3 ∣ . . . ∣ β n P \rightarrow P\alpha_1|P\alpha_2|P\alpha_3|...|P\alpha_n|\beta_1|\beta_2|\beta_3|...|\beta_n P→Pα1∣Pα2∣Pα3∣...∣Pαn∣β1∣β2∣β3∣...∣βn
消除后文法: P → β 1 P ′ ∣ β 2 P ∣ β 3 P ′ ∣ . . . ∣ β n P ′ P \rightarrow \beta_1P'|\beta_2P |\beta_3P'|...|\beta_nP' P→β1P′∣β2P∣β3P′∣...∣βnP′ P ′ → α 1 P ′ ∣ α 2 P ′ ∣ α 3 P ′ ∣ . . . ∣ α n P ′ ∣ ϵ P' \rightarrow \alpha_1P'|\alpha_2P'|\alpha_3P'|...|\alpha_nP'|\epsilon P′→α1P′∣α2P′∣α3P′∣...∣αnP′∣ϵ
一般方法
example: S → Q c ∣ c S\rightarrow Qc|c S→Qc∣c Q → R b ∣ b Q\rightarrow Rb|b Q→Rb∣b R → S a ∣ a R\rightarrow Sa|a R→Sa∣a
step1: 把文法右侧换为一个变量(符号)
S
→
S
a
b
c
∣
a
b
c
∣
b
c
∣
c
S\rightarrow Sabc|abc|bc|c
S→Sabc∣abc∣bc∣c
Q
→
S
a
b
∣
a
b
∣
b
Q \rightarrow Sab|ab|b
Q→Sab∣ab∣b
R
→
S
a
∣
a
R \rightarrow Sa|a
R→Sa∣a
step2: 使用快速消除左递归转换带有公共符号的行
S
→
a
b
c
S
′
∣
b
c
S
′
∣
c
S
′
S\rightarrow abcS'|bcS'|cS'
S→abcS′∣bcS′∣cS′
S
′
→
a
b
c
S
′
∣
ϵ
S'\rightarrow abcS'|\epsilon
S′→abcS′∣ϵ
Q
→
S
a
b
∣
a
b
∣
b
Q \rightarrow Sab|ab|b
Q→Sab∣ab∣b
R
→
S
a
∣
a
R \rightarrow Sa|a
R→Sa∣a
step3: 去掉无用的变量
S
→
a
b
c
S
′
∣
b
c
S
′
∣
c
S
′
S\rightarrow abcS'|bcS'|cS'
S→abcS′∣bcS′∣cS′
S
′
→
a
b
c
S
′
∣
ϵ
S'\rightarrow abcS'|\epsilon
S′→abcS′∣ϵ
消除左因子
一般方法
原始文法:
A
→
s
α
1
∣
s
α
2
∣
.
.
.
∣
s
α
n
∣
β
1
∣
β
2
∣
.
.
.
∣
β
n
A\rightarrow s\alpha_1|s\alpha_2|...|s\alpha_n|\beta_1|\beta_2|...|\beta_n
A→sα1∣sα2∣...∣sαn∣β1∣β2∣...∣βn
处理后文法:
A
→
s
A
′
∣
β
1
∣
β
2
∣
.
.
.
∣
β
n
A\rightarrow sA'|\beta_1|\beta_2|...|\beta_n
A→sA′∣β1∣β2∣...∣βn
A
′
→
α
1
∣
α
2
∣
.
.
.
∣
α
n
A' \rightarrow \alpha_1|\alpha_2|...|\alpha_n
A′→α1∣α2∣...∣αn
First Set and Follow Set
First Set
找文法的左面,看右面。右面是终结符就append,不是就append这个非终结符的FirstSet。
Follow Set
找文法的右面谁出现要求的非终结符。看要求的符号右侧是谁,是终结符就append,非终结符append其去空的FirstSet,在末尾就append左边的终结符。(此处因为已经提前去除了左递归因此不会出现问题)