【发布时间】:2017-03-03 00:48:49
【问题描述】:
假设给我以下语法:
start -> statement //cannot change
statement -> assignment SEMICOLON
statement -> function_call SEMICOLON
assignment -> IDENTIFIER EQUAL expression
function_call -> IDENTIFIER LPAREN parameters RPAREN SEMICOLON
现在的语法不能是 LL(1),因为语句(赋值和函数调用)的非终结符都将 IDENTIFIER 作为每个产生式的第一个终结符。只有通过使用 2 次前瞻,您才能决定解析器将采用哪条路径。
有什么方法可以将上面的语法操作为 LL(1)?还是不可能?
【问题讨论】:
-
左分解应该很容易搜索。提示:
statement: IDENTIFIER rest; rest: something | something-else -
@rici 我理解,但如果你有类似 [statement -> Compound_statement] 和 [compound_statement -> assignment | function_call] 是否仍被视为 LL(1)?
-
不,不会。要成为 LL(1),您需要通过查看接下来的 (1) 个令牌来了解哪个产品将被扩展。下一个标记将是 IDENTIFIER,它可以让您预测
statement -> compound_statement,但不能预测两个compound_statement产品中的哪一个。所以你需要left-factor或者选择像LR(1)这样更强大的解析算法。 -
@rici 我还有一个问题,请你回答一下。我的语法是 LL(K) 吗? LL(K) 语法是否适合 LL(1) 语法?如果 LL1() 属于 LL(K) 的子集,这让我困惑了一段时间
-
它是 LL(2),因为您可以根据下 (2) 个令牌做出决定。是的,如果 k