语法分析相关知识集合
一、自上而下的分析(LL(1)文法)
主要面临的的两个问题:
1.左递归
2.回溯
问题解决:
1.左递归
a.直接左递归
例子:P->Pa|b (将左递归变为右递归)
改写后的文法:P->bP',P'->aP'|ε
小练习:给定文法G(E):
E->E+T|T
T->T*F|F
F->(E)|i
答案见最后
b. 间接左递归
例子:给定文法G(S):
S->Qc|c
Q->Rb|b
R->Sa|a
消除左递归的条件:
·不含以ε为右部的产生式
·不含回路(P-+>P,P经过若干步推导,回到自身)
改写后的文法:
第一次:
S->Qc|c
Q->Sab|ab|b
R->Sa|b
第二次:
S->Sabc|abc|bc|c
Q->Sab|ab|b
R->Sa|b
第三次:
S->abcS'|bcS'|cS'
S'->abcS'|ε
Q->Sab|ab|b
R->Sa|b
第四次(去掉多余的表达式):
S->abcS'|bcS'|cS'
S'->abcS'|ε
2.回溯(略)
3.First集合和Follow集合
例:
对于文法G(E)
E->TE'
E'->+TE'|ε
T->FT'
T'->*FT'|ε
F->(E)|i
a.First集合
第一次遍历:
first(E)={}
first(E')={+,ε}
first(T)={}
first(T')={*,ε}
first(F)={(,i}
第二次遍历:
first(E)={}
first(E')={+,ε}
first(T)={(,i}
first(T')={*,ε}
first(F)={(,i}
第三次遍历:
first(E)={(,i}
first(E')={+,ε}
first(T)={(,i}
first(T')={*,ε}
first(F)={(,i}
第四次遍历:
不变,结束
b.Follow集合
规则:
①. 设S为文法中开始符号,把{#}加入FOLLOW(S)中(这里“#” 为句子括号)。
②. 若A→αBβ是一个产生式,则把FIRST(β)的非空元素加入
FOLLOW(B)中。如果β能够推导出ε则把FOLLOW(A)也加入FOLLOW(B)中。
文法G(E)
E->TE'
E'->+TE'|ε
T->FT'
T'->*FT'|ε
F->(E)|i
first(E)={(,i}
first(E')={+,ε}
first(T)={(,i}
first(T')={*,ε}
first(F)={(,i}
Follow(E)={#,)}
Follow(E')={#,)}
Follow(T)={+,#,)}
Follow(T')={+,#,)}
Follow(F)={*,+,#,)}
网上答案详解:
FOLLOW集的求解:
因为E是文法的识别符所以把#加入FOLLOW(E),又由规则F → (E) | i 得E的后跟符号),所以,FOLLOW(E)={ #,) };
FOLLOW(E’)={ #,) } ∵E → TE’ ∴FOLLOW(E)加入 FOLLOW(E’)
FOLLOW(T)={+,),#} ∵E'→ +TE’ ∴FIRST(E’)-{ε}加入FOLLOW(T); 又E’→ε, ∴ FOLLOW(E’)加入FOLLOW(T)
FOLLOW(T’)= FOLLOW(T)= {+,),#} ∵T → FT’ ∴ FOLLOW(T)加入FOLLOW(T’)
FOLLOW(F)={*,+,),#} ∵T → FT’ ∴ FOLLOW(F)=FIRST(T’)-{ε} ; 又T’→ε ∴ FOLLOW(T)加入FOLLOW(F)
4.select集合求解
对于文法G(E)
E->TE'
E'->+TE'|ε
T->FT'
T'->*FT'|ε
F->(E)|i
First集合: Follow集合:
first(E)={(,i} Follow(E)={#,)}
first(E')={+,ε} Follow(E')={#,)}
first(T)={(,i} Follow(T)={+,#,)}
first(T')={*,ε} Follow(T')={+,#,)}
first(F)={(,i} Follow(F)={*,+,#,)}
select集合:
select(E->TE')=(first(TE')-{ε})U(Follow(E))={+,(,i,#,)}
select(E'->+TE')=first(+TE')={+}
select(E'->ε)=(first(ε)-{ε})U(follow(E'))={#,)}
select(T->FT')=(first(FT')-{ε})U(follow(T))={(,i,*,+,#,)}
select(T'->*FT')=first(*FT')={*}
select(T'->ε)=follow(T')={+,#,)}
select(F->(E))=first((E))={(}
select(F->i)=first(i)={i}
LL(1)文法判断:
∵select(E'->+TE') ∩ select(E'->ε)=ф
select(T'->*FT') ∩ select(T'->ε)=ф
select(F->(E)) ∩ select(F->i)=ф
∴此文法为LL(1)文法
5.LL(1)分析表的构造 (根据select集进行构造)
( | ) | + | * | i | # | |
---|---|---|---|---|---|---|
E | ->TE’ | ->TE’ | ->TE’ | ->TE’ | ->TE’ | |
E’ | ->ε | ->+TE’ | ->ε | |||
T | ->FT’ | ->FT’ | ->FT’ | ->FT’ | ->FT’ | ->FT’ |
T’ | ->*FT’ | |||||
F | ->(E) | i |
二、自下而上的分析(LR分析法,以LR(0)为例)
例:
S->A
A->Ab|bBa
B->aAc|a|aAb
写出增广文法:
S’->S
S->A
A->Ab|bBa
B->aAc|a|aAb
写LR(0)的项
S->A | A->Ab | A->bBa | B->aAc | B->a | B->aAb |
---|---|---|---|---|---|
S->·A | A->·Ab | A->·bBa | B->·aAc | B->·a | B->·aAb |
S->A· | A->A·b | A->b·Ba | B->a·Ac | B->a· | B->a·Ab |
A->Ab· | A->bB·a | B->aA·c | B->aA·b | ||
A->bBa· | B->aAc· | B->aAb· |
画出LR(0)项目集规范族
S’->S(r1)
S->A(r2)
A->Ab(r3)
A->bBa(r4)
B->aAc(r5)
B->a(r6)
B->aAb(r7)