Parsing LL(1)解析——使用递归优先选项的优先(A)
如何将FIRST()规则应用于产品,例如: A->AAb | Ab | s 其中A为非端子,b、s为端子Parsing LL(1)解析——使用递归优先选项的优先(A),parsing,compiler-construction,grammar,context-free-grammar,ll,Parsing,Compiler Construction,Grammar,Context Free Grammar,Ll,如何将FIRST()规则应用于产品,例如: A->AAb | Ab | s 其中A为非端子,b、s为端子 备选方案1和2的第一(A)也是A,但这将在FIRST的无限应用中结束,因为我需要一个终端来获取第一个集合?要计算第一个集合,通常需要执行定点迭代。也就是说,您从一个小的值集开始,然后迭代地重新计算第一个值集,直到这些值集收敛 在本例中,您将首先注意到生产→ s表示第一个(A)必须包含{s}。因此,首先设置(A)={s} 现在,您将遍历A的每个产品,并根据到目前为止计算的第一个集合的知识首先更
备选方案1和2的第一(A)也是A,但这将在FIRST的无限应用中结束,因为我需要一个终端来获取第一个集合?要计算第一个集合,通常需要执行定点迭代。也就是说,您从一个小的值集开始,然后迭代地重新计算第一个值集,直到这些值集收敛 在本例中,您将首先注意到生产→ s表示第一个(A)必须包含{s}。因此,首先设置(A)={s} 现在,您将遍历A的每个产品,并根据到目前为止计算的第一个集合的知识首先更新。例如,规则 A→ AAb 意味着您应该更新FIRST(A)以包含FIRST(AAb)的所有元素。这不会导致对第一个(A)的更改。然后你去 A→ Ab 您再次更新FIRST(A)以包含FIRST(Ab),这也是一个禁止操作。最后,您访问 A→ 因为第一个(A)已经包含s,所以这不会引起任何变化 因为在这个迭代中没有任何变化,所以最终会得到FIRST(A)={s},这确实是正确的,因为从A开始的任何派生最终都会产生一个
s
作为它的第一个字符
要了解更多信息,您可能会发现有用的(这里是)。它们详细描述了自顶向下的解析是如何工作的,以及如何迭代地计算第一个集合
希望这有帮助 您的语法规则与您已经意识到的语法规则相同,并且将使用LL解析器
因此,您需要先摆脱左递归,然后才能计算规则的第一个集合。我的是西班牙语,但算法是英语的。这是一种先计算的方法:
是字母表(终端),N
是非终端集,p
是产品集(规则),ε
是空字符串,⋅k
被连接修剪为k
位置。请注意∅ ⋅kx=∅代码>,将两个集合串联在一起会产生笛卡尔乘积中元素的串联
手工计算第一组的最简单方法是每次算法迭代使用一个表
F(A) = ∅
F'(A) = F(A) ⋅1 F(A) .1 F(b) U F(A) .1 F(b) U F(s)
F'(A) = ∅ ⋅1 ∅ ⋅1 {b} U ∅ ⋅1 {b} U {s}
F'(A) = ∅ U ∅ U {s}
F'(A) = {s}
F''(A) = F'(A) ⋅1 F'(A) .1 F'(b) U F'(A) .1 F'(b) U F'(s)
F''(A) = {s} ⋅1 {s} ⋅1 {b} U {s} ⋅1 {b} U {s}
F''(A) = {s} U {s} U {s}
F''(A) = {s}
我们完成了,因为F'=F'
,所以FIRST=F'
,和FIRST(A)={s}
,虽然这是真的,但我认为OP的问题是关于计算第一组,即使语法是左递归的,这也是可能的。问题是关于计算第一组,对于左递归语法也可以这样做。@Apalala-你确定吗?符号b
肯定不在第一个(A)中。我所知道的计算第一个集合的算法是,在第一个集合中播种所有的结果,从一个终端开始,然后从那里开始。@Apalala-或者,如果你不以这种方式播种所有东西,你就不会通过查看非终端的第一个集合来计算第一个集合,除非非终端可以产生ε。这意味着更新规则会将FIRST(A)添加到FIRST(A)中,这会将空集添加到自身中。您可以首先使用A->b
形式的规则的终端进行种子设定,但这还不够通用。但我投反对票的原因是,你建议当从A->AAb
计算第一个时,只需查看第一个A
,这是错误的,因为,尽管不是在这种情况下,可能是A=*=>ε
,这将使第一个(A)
包含b
。请参阅我关于第一个的一般解决方案的答案。@Apalala-我已经教了两次编译器课程,我很有信心在进行第一个集合计算时不会忽略非终结符,除非您明确发现该非终结符的第一个集合包含ε。你不会乐观地看过去的非终端。这有意义吗?你是对的,第一个[1],但不是第一个[k]。我对你的答案进行了编辑,使之更一般、更正确。我希望你不介意。
F(A) = ∅
F'(A) = F(A) ⋅1 F(A) .1 F(b) U F(A) .1 F(b) U F(s)
F'(A) = ∅ ⋅1 ∅ ⋅1 {b} U ∅ ⋅1 {b} U {s}
F'(A) = ∅ U ∅ U {s}
F'(A) = {s}
F''(A) = F'(A) ⋅1 F'(A) .1 F'(b) U F'(A) .1 F'(b) U F'(s)
F''(A) = {s} ⋅1 {s} ⋅1 {b} U {s} ⋅1 {b} U {s}
F''(A) = {s} U {s} U {s}
F''(A) = {s}