【问题标题】:Manipulate following grammar to be LL(1)将以下语法操作为 LL(1)
【发布时间】: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

标签: parsing grammar ll


【解决方案1】:

上面的语法对于任何 k 都不是真正的 LL(k),但是我们可以为同一种语言构建 LL(1) 语法:

start -> statement // cannot change

statement -> IDENTIFIER statement0 SEMICOLON

statement0 ->  EQUAL expression

statement0 ->  LPAREN parameters RPAREN SEMICOLON

当然,在问题描述中,我们没有看到表达式和参数的定义,所以我们假设我们也可以为它们构建 LL(1) 规则(在我们看到规则之前不能保证)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多