【编译原理】语法分析之预测分析法

构造文法

① E → TE’
② E’ → +TE’ |ε
③ T → FT ’
④ T’ → *FT ’ |ε
⑤ F → (E)|id

消除左递归

左递归:同一非终结符的候选式存在共同前缀
消除:引入非终结符和ε_产生式
e.g.原表达式:

A → A α1 | A α2 | … | A αn | β1 | β2 | … | βm

消除左递归后:

A → β1 A′ | β2 A′ | … | βm A′
A′ → α1 A′ | α2 A′ | … | αnA′ | ε

上述文法不含左递归,此步骤省略。

求FIRST集和FOLLOW集,从而求得SELECT集

FIRST

① E → TE’
② E’ → +TE’ |ε
③ T → FT ’
④ T’ → *FT ’ |ε
⑤ F → (E)|id

FIRST(X):可从X推导出的所有串首终结符构成的集合
1.先看可以直接推到出终结符的
2.再找推导为非终结符的依赖关系
对上述例子,有:

FIRST(E)={(,id}
FIRST(E’)={+,ε}
FIRST(T)={(,id}
FIRST(T’)={*,ε}
FIRST(F)={(,id}

FOLLOW

FOLLOW(X):紧跟在X后面的终结符的集合

① E → TE’
② E’ → +TE’ |ε
③ T → FT ’
④ T’ → *FT ’ |ε
⑤ F → (E)|id

1.E是最右符号

FOLLOW(E)={#}

对于T,紧跟在后面的是E’

FOLLOW(T)=FIRST(E’)={+}

由于E’可导出空串,能跟在E后的符号也能跟在T后

FOLLOW(T)={+,#}

E’是产生式①右侧最后一个符号,故跟在E后的符号也能跟在E’后

FOLLOW(E’)={#}

2.产生式②与①结构类似,所得FOLLOW集相同。
3.分析产生式③

FOLLOW(T)={+,#}
FOLLOW(F)=FIRST(T’)={※}
FOLLOW(F)={※,+,#}
FOLLOW(T’)={+,#}

4.④与③分析结果相同
5.分析产生式⑤

FOLLOW(F)={※,+,#}
FOLLOW(E)={#,)}

由①,将FOLLOW(E)中元素填入FOLLOW(T)和FOLLOW(E’):

FOLLOW(T)={+,#,)}
FOLLOW(E’)={#,)}

由③,将FOLLOW(T)中元素填入FOLLOW(F)和FOLLOW(T’):

FOLLOW(F)={※,+,#,)}
FOLLOW(T’)={+,#,)}

综上:

FOLLOW( E ) = {#,)}
FOLLOW( E’ ) = {#,)}
FOLLOW( T ) = {+,#,)}
FOLLOW( T’ ) = {+,#,)}
FOLLOW( F ) = {※,+,#,)}

SELECT

① E → TE’
② E’ → +TE’ |ε
③ T → FT ’
④ T’ → *FT ’ |ε
⑤ F → (E)|id

  1. 产生式右部以非终结符开头:
    SELECT为该非终结符的FIRST

  2. 产生式右部以终结符开头:
    SELECT为该终结符的集合

  3. 产生式右部为ε:
    SELECT为左部的FOLLOW

SELECT (1)= { (, id }
SELECT (2)= { + }
SELECT (3)= { #, ) }
SELECT (4)= { ( ,id }
SELECT (5)= { * }
SELECT (6)= { +, ) ,# }
SELECT (7)= { ( }
SELECT (8)= { id }

FOLLOW(X)∩FIRST(X)=空集
∴文法是LL(1)文法

构造预测分析表

根据SELECT将产生式填入

递归的预测分析

根据预测分析表为每一个非终结符编写一个过程

非递归的预测分析

表驱动的预测分析算法

栈 剩余输入 输出
E# id+idid#
TE’# id+id
id# E→TE’
FT’E’# id+idid# T→FT’
idT’E’# id+id
id# F→id
T’E’# +idid#
E’# +id
id# T’→ε
+TE’# +idid# E’→+TE’
TE’# id
id#
FT’E’# idid# T→FT’
idT’E’# id
id# F→id
T’E’# *id#
*FT’E’# id# T’→FT’
FT’E’# id#
idT’E’# id# F→id
T’E’# #
E’# # T’→ε

你可能感兴趣的:(编译原理,学习)