【问题标题】:Unambiguous Grammar明确的语法
【发布时间】:2023-11-09 17:06:01
【问题描述】:

我想为算术表达式创建一个明确的语法。现在求幂应该具有更高的优先级并与右侧相关联。所有其他操作都关联到左侧。这是我目前所拥有的,但我不知道求幂是否正确

E -> E+T | E-T | T
T -> T*F | T/F | L
L ->  F^ L|F
F -> i | (E)

【问题讨论】:

  • 是的。我不认为这有什么区别,但我更新了标题。
  • @user1072706 :这很重要,因为我们尝试不破坏作业问题(请参阅meta.stackexchange.com/questions/10811/…)。另外,我们要求您向我们展示您尝试过的(您已经完成的)。
  • 我建议您在1-2-3/4/5^6^7-8-9 上手动模拟您的解析器。这很好地锻炼了您的优先规则并暴露了关联性问题。

标签: parsing recursive-descent


【解决方案1】:

我很好奇,因为这被标记为递归下降,这让我想到了 LL。

为 LL 解析器创建语法时,请记住这些规则。

重复用于左结合:

Foo -> Bar (op Bar)*

尾递归用于右结合:

Foo -> Bar (op Foo)?

现在,您没有对 LL 解析器友好的语法,因为您已经离开递归:

E -> E+T

另一方面,如果它是 LL,则您的幂运算使用尾递归,这样就可以了。

我推荐*的 Top Down ParsingLeft-Recursion 文章(这些文章比 LL parser 文章更容易阅读)。请注意,LR parsers 的工作方式不同,导致左右关联的语法不同。

哦,您的规则顺序对于 LL 解析器需要的优先级是正确的。您的低优先级运算符规则位于生产规则链中。

【讨论】:

    【解决方案2】:

    根据您的语法,这里是您想要的更具可读性的版本。它是明确的并且正确地捕获了关联性。

    expr -> term | expr add term
    term -> factor | term mult factor
    factor -> number | - factor | ( expr )
    add -> + | -
    mult -> * | /
    

    这个例子应该更易读,这样你就可以把它应用到你的家庭作业中。我确实省略了 ^ 运算符,但您应该能够从示例中弄清楚。如果您想购买 [另一本] 教科书,Programming Language Pragmatics 将有很大帮助。

    【讨论】: