FIRST和FOLLOW设置它们在解析时使用了什么?

时间:2010-09-29 02:24:47

标签: parsing parser-generator ll

什么是FIRST和FOLLOW集?它们在解析时使用了什么? 它们是用于自上而下还是自下而上的解析器?

任何人都可以先解释我的第一套并遵循以下一套语法规则:

> E := E+T | T
> 
> T := T*V | T
> 
> V := <id>

3 个答案:

答案 0 :(得分:3)

它们通常用于LL(自上而下)解析器,以检查正在运行的解析器是否会遇到有多种方法可以继续解析的情况。

如果你有替代A | B并且还有FIRST(A) = {"a"}FIRST(B) = {"b", "a"}那么你会有第一次/第一次冲突,因为当输入中的“a”出现时你不会知道是否扩展A或B.(假设前瞻是1)。

另一方面,如果你有一个像AOpt: ("a")?这样可以为空的非终结者,那么你必须确保FOLLOW(AOpt)不包含“a”,否则你不知道是否要扩展AOpt或不喜欢这里:S: AOpt "a" S或AOpt可能会消耗“a”,这会给我们带来FIRST / FOLLOW冲突。

出于性能原因,在解析过程中也可以使用FIRST集。如果你有一个可空的非终结NullableNt你可以扩展它以查看它是否可以消耗任何东西,或者检查FIRST(NullableNt)是否包含下一个标记可能更快,如果不是简单地忽略它(回溯与预测解析) 。另一个性能改进是另外为词法扫描器提供当前的FIRST集,因此扫描器不会尝试所有可能的终端,而只会尝试上下文当前允许的终端。这与保留的终端冲突,但并不总是需要它们。

自下而上的解析器有不同类型的冲突,即Reduce / Reduce和Shift / Reduce。他们还使用项目集来检测冲突,而不是FIRST,FOLLOW。

你的语法不适用于LL解析器,因为它包含左递归。但E,T和V的FIRST集合将为{id}(假设您的T := T*V | T应为T := T*V | V)。

答案 1 :(得分:1)

答案:

E-&GT,E + T | T

左递归

E-&GT; TE'

E ' - &GT; + TE' | eipsilon

T-&GT;吨* V | T

左递归

T-&GT; VT'

T ' - &GT * VT' |的ε-

中没有左递归

V-&GT;(ID)

因此语法是:

E-&GT; TE'

E ' - &GT; + TE' |的ε-

T-&GT; VT'

T ' - &GT * VT' |的ε-

V-&GT; (ID)

FIRST(E)= {(}

FIRST(E')= {+,ε}

FIRST(T)= {(}

FIRST(T')= {*,ε}

FIRST(V)=​​ {(}

开始符号=跟随(E)= {$}

E-&GT; TE 'E ' - &GT; TE' |的ε-:按照(E')= FOLLOW(E)= {$}

E-&GT; TE 'E ' - &GT; + TE' |的ε-:按照(T)= FIRST(E')= {+,$}

T-&GT; VT 'T ' - &GT * VT' |的ε-:按照(T')= FOLLOW(T)= {+,$}

T-> VT',T-> * VT'| epsilon:FOLLOW(V)= FIRST(T)= {*,epsilon}

首套规则

If X is a terminal then First(X) is just X!
If there is a Production X → ε then add ε to first(X)
If there is a Production X → Y1Y2..Yk then add first(Y1Y2..Yk) to first(X)
First(Y1Y2..Yk) is either
    First(Y1) (if First(Y1) doesn't contain ε)
    OR (if First(Y1) does contain ε) then First (Y1Y2..Yk) is everything in First(Y1) except for ε  as well as everything in First(Y2..Yk)
    If First(Y1) First(Y2)..First(Yk) all contain ε then add ε to First(Y1Y2..Yk) as well.

关注集规则

First put $ (the end of input marker) in Follow(S) (S is the start symbol)
If there is a production A → aBb, (where a can be a whole string) then everything in FIRST(b) except for ε is placed in FOLLOW(B).
If there is a production A → aB, then everything in FOLLOW(A) is in FOLLOW(B)
If there is a production A → aBb, where FIRST(b) contains ε, then everything in FOLLOW(A) is in FOLLOW(B)

答案 2 :(得分:0)

维基百科是你的朋友。请参阅discussion of LL parsers和第一个/关注集。

从根本上说,它们被用作解析器构造的基础,例如,作为解析器生成器的一部分。您也可以使用它们来推理语法的属性,但大多数人并不需要这么做。