我知道这方面的问题很多,但我还是没能找到我要找的东西。
至于寻找给定语法的Follow集的程序,我看到了很多版本,但我们还是坚持使用给定语法的程序吧 此处 因为这是我见得最多的一个。我把它复制到这里,这样你就不用打开了。
- 首先在Follow(S)中输入$(输入标记的终点)(S是起始符号)
- 如果有一个生产A→aBb,(其中a可以是一个完整的字符串),那么FIRST(b)中除了ε之外的所有东西都放在FOLLOW(B)中。
- 如果有一个生产A→aB,那么FOLLOW(A)中的所有内容都在FOLLOW(B)中。
- 如果有一个生产A→aBb,其中FIRST(b)包含ε,那么FOLLOW(A)中的一切都在FOLLOW(B)中了
问题1: 规则2和4是相互排斥的,还是它们都可以在同一个 "迭代 "中应用(这样写是因为这实际上将是我的问题之一)?我这里的意思是,它们在第一部分是匹配的,也就是说,它们都是应用 "如果有一个生产A -> aBb"。
这是否意味着,如果我遇到一个生产A ->;aBb,使ε在First(b)中,我应该同时应用第二条和第四条规则,还是只应用第四条?
问题2:如果我遇到A-> aBb,使ε在First(b)中,我应该应用第二和第四条规则,还是只应用第四条规则?: a "和 "b "到底是什么?除了规则2的部分内容外,其他地方都没有正式规定,其中说 "a可以是一个完整的字符串"。那规则3和4呢?实际上,让我把这个问题再概括一下。如果我有一个形式为:A -> abcd......efgBxyzw......的生产,这些规则中的任何一条都可以应用吗?也就是说,这些规则是否要求生产的字面意义上只包含其右侧的三个元素?或者可以这样解释。
A -> abcd... ef [gBx] yzw.... ... ,其中gBx部分现在将对应于规则2和4中的aBb部分。还是说这只适用于规则2,而且只适用于'a'的部分,就像:
A -> abcd...ef[gBx] , 左边的部分可以是一个完整的字符串,而右边的部分必须是一个符号?
注意:方括号不是语法的一部分,我只是用它们来分隔东西,以便解释我的意思。
问题三: 这个程序是确定的吗?问题是,他们没有提到我们要做多久,以及以什么顺序做。事实上,我看到一些资料说 "只要还有东西要加"。那我们应该按照什么顺序来做呢?我想,我们只是随机抽取产物,只要能应用就可以了。我们是否应该尝试从我们所拥有的语法规则中推导出更多的产物?还是说这个程序是为了间接地 "抓 "那些东西?这里还有一个很让人困惑的事情。让我们看看下面的情况。
我在看一个产品,通过应用规则,我确定Follow(A)的所有东西都应该进入Follow(B)。我们把它非正式地写成
Follow(B) += Follow(A)
让Follow(A),目前(根据我最新的计算),包含一些元素,比如{x,y,z}。我应该立即写Follow(B) = {..., x, y, z}还是应该等到最后?为什么这么说呢?如果几个生产之后,我遇到了一个以任何方式修改Follow(A)的生产,比方说它增加了'w',所以现在Follow(A) = {x, y, z, w}。这是否意味着,假设我马上写了Follow(B) = {..., x, y, z},而不是等待,我现在需要回到那里并添加'w',还是说存储过程应该在后面的迭代中'捕获'这个'w'?
先谢谢你了。
问题1.为什么? 不,它们两个不能在同一个迭代中应用。这是因为 except for ε
中的一部分,意味着如果有 没有 ε.
问题2:'a'和'b'是什么? 'a'和'b'是 α
(α)和 β
(beta)。它们都代表多个符号。(像 A → Z b B n m
可能是 A → α B β
; Z b
缩短为 α
和 n m
到 β
). 所以不,并不限于rhs上只有3个符号。
问题3: 是的,这是detrministic。你要做的是,你有一张地图(如 std::unordered_map
来存储跟随集),然后你开始一个 while 循环--条件是在当前迭代期间对跟随集进行了修改。在循环体中,你放上规则。举个例子。
follow_sets = {} # map
changes = True
while changes:
changes = False
# follow set rules
# once a rule is applied, and things are added to the follow sets map, set changes to True
现在,你的规则集很好,但描述性不够。这就是我用来建立跟随集的规则集。
Follow(START) has $
If A → α B β (Provided β ≠ ε):
Follow(B) → First(β)
If A → α B:
Follow(B) → Follow(A)
If A → α B β (provided β → ε):
Follow(B) → { First(β) - ε } ∪ First(A)