Compiler construction 如何将上下文无关语法左因子化?
据我所知,在以下情况下,构建自顶向下的解析器需要左因子分解。 但很难理解如何做到这一点?有人能帮我吗?谢谢Compiler construction 如何将上下文无关语法左因子化?,compiler-construction,grammar,ll,Compiler Construction,Grammar,Ll,据我所知,在以下情况下,构建自顶向下的解析器需要左因子分解。 但很难理解如何做到这一点?有人能帮我吗?谢谢 s = a | b b = c d c = (e | f) g e = a | h 每个非终结符在此仅引用一次,因此我们可以将整个语法放在一个表达式中: s = a | ((a | h | f) g d) 所以我们有两个基本的变化,端子a可以选择接g,然后接d,或者h或f中的一个总是接g,然后接d 所以我们有 s = b' | c' b' = a | a g d c' = (h |
s = a | b
b = c d
c = (e | f) g
e = a | h
每个非终结符在此仅引用一次,因此我们可以将整个语法放在一个表达式中:
s = a | ((a | h | f) g d)
所以我们有两个基本的变化,端子a可以选择接g,然后接d,或者h或f中的一个总是接g,然后接d
所以我们有
s = b' | c'
b' = a | a g d
c' = (h | f) g d
或者,将通用的gd序列拉入它自己的生产中
s = b' | c'
b' = a | a e'
c' = (h | f) e'
e' = g d
然后,我们可以通过引入E(空)选项,将a作为b'中的常用起始符号:
语法现在是明确的。好吧,这取决于作品
a
,d
,f
,g
和h
是什么。如果它们是“简单”的终端,那么就不需要左因子分解了。@BartKiers:你注意到了吗?在我的例子中,b在通过b->c->e->a时,它的左边也包含了a?这意味着它可能是s=a | a+something
。你还说不需要左因子分解吗?谢谢。@Bhathiya:Left factoring应用于转换语法,这样控件在不使用任何标记的情况下就不能循环,这将导致解析时出现无止境的循环。这里不是这样。这里的问题是无法使用LL(1)(单符号前瞻)解析器解析此语法。@500 InternalServerError:在这种情况下,您建议什么解决方案来避免循环场景?
s = b'' | c'
b'' = a (e' | E)
c' = (h | f) e'
e' = g d