语法分析之自顶向下语法分析概述与三个重要概念的集合
自顶向下语法分析概述:
基本思想
-
检查程序是否为文法的句子
-
按定义从开始符号出发能推导出程序 一个一个尝试,选择规则没有依据。
例子:
Z→aBb[1]|aD[2]
B→b[3]|bB[4]
D→d[5]|bD[6]
分析一个串abbd,穷举过程如下
Z# abbd#
aBb# abbd# (a匹配)
Bb# bbd#
bb# bbd#( B→b,两个b匹配)
# d#(匹配失败,回溯)
bBb# bbd#(匹配成功,b)
Bb# bd#
bb# bd#(B→b,b匹配成功)
b# d#(匹配失败,回溯)
bBb# bd#(b匹配)
Bb# d#(匹配失败)继续回溯(这里省略几步,直接回溯到了Z的另一条路径Z→aD)
aD# abbd#
D# bbd#
d# bbd#(匹配失败,回溯使用D的另外一条路径)
bD# bbd#
D# bd#
d# bd#(匹配失败,使用D的另外一条路径)
bD# bd#
D# d#
d# d#
# #
匹配成功。
选择规则的策略:
-
穷举方法效率非常的差,从上面的过程,可以看出来
-
考虑更过的信息,如输入流
-
根据输入流选取规则
-
考察输入流的几个符号,比如头符
First集的定义
设G = (Vt, Vn, S, P)是上下文无关文法,2型文法。
β ∈(Vt ∪ Vn)*
First(β) = {a属于Vt|β =>*a……}∪(if β=>*空 then {空} else 空集)
首先我们要理解β它是一个串,这个串的组成是由终极符和非终极符的星闭包。它是针对于一个串而言的。
aD能推出若干个字符串,最后退出来的每个串的头一个终极符所组成的集合。就是first集了。
First(aD) = {a}
串经过若干部推导,推导出若干串,所有这些串以终极符开头的,这些终极符都属于First(β)
Follow集的定义
设G = (Vt, Vn, S, P)是上下文无关文法,2型文法,A∈Vn,S是开始符号
Follow(A) = {a∈Vt | S=>+……Aa……} U (if S => *……A then {#} else 空集)
注意:我们需要注意到从开始符号推出的所有举行中有A的并且紧跟A的终极符的集合。
从开始符号出发,推出一个句型,这个句型中有A,所有跟在A后面的非终极符的集合,如果次句型中A位于最后一个符号,则Follow(A)包括{#}
Predict集的定义
Predict(A→β) =
-
= First(β) 当First(β)不包含空
-
= First(β) – 空 ∪ Follow(A) 当First(β)包含空
注:Predict集是针对于一条规则而言的。而且我们的最终目的是为了求出Predict帮我们判断要选择那一条规则进行推导的。求出first和follow只是我们的手段而已。
计算first(X) 集(X是一个长度为1的符号,也就是分为终极符和非终极符)
若X∈Vt,(即暗示长度为1且为终极符),则First(X) = {X}
若X∈Vn,(即暗示长度为1且是非终极符),则First(X) = {a|X→a……属于产生式P, a∈Vt}
若X属于Vn,且有产生式X→空,则空∈First(X)。
若X属于Vn,有产生式X→Y1Y2Y3……Yn,且Y1Y2……Yi∈Vn
当Y1,Y2,Y3,……Yi=>*空(也就是隐含了Yi+1经过星闭包推不出空)
则First(Y1) – {空},First(Y2) – {空},……, First(Yi) – {空}都包含在First(X)中
当Yi=>*空(i=1, 2, 3, ……, n),将空也并入First(X)中。(也就是从X推出的产生式规则右侧只有非终极符的序列,而且每个非终极符都可以推出空,则空包含在First(X))
设符号串α = X1X2X3……Xn
若α=空,则空属于First(α)
求First(Xi),i=1,2,……,n
若n = 1则First(X1) = First(α)
若n>=2,且j=1, 2, 3, ……, i-1,都有空属于First(Xj)则令所有(Xj)-{空} 都是First(α)的子集
若所有的X都能推出空,即都有空∈First(Xi),则空属于First(α)
计算Follow集(找出含有规则友部含有A的全部规则)
-
对开始符号S,{#}∈Follow(S)
-
有规则B→α1Abα2,b∈Vt,则b属于Fololow(A)(α1可空可不空,关键是A后main的额东西,这一种情况是说A后面是一个非终极符。)
-
对于一般情形,有规则B→α1Aα2 First(α2)-{空}是Follow(A)的子集
-
若B→Aα或者是B→βAα,且α=>*空 Follow(B)是Follow(A)的子集。
注:我们可以看出求Follow集合的时候我们是基于规则而言的,这是因为我们不可能找出所有举行来判断A后面的非终极符。而且对于规则B→α1Aα2而言,α1Aα2一定是在某一个句型中。只要使用B→α1Aα2规则,即α2的first集一定是Follow(B)的子集。
而Predict(A→β)的计算在求出First和Follow之后也就迎刃而解了。在此不赘述
时间: 2024-10-28 13:18:38