【问题标题】:What are the differences between PEGs and CFGs?PEG和CFG有什么区别?
【发布时间】:2011-07-26 22:38:05
【问题描述】:

来自这个wikipedia页面:

两者的根本区别 上下文无关语法和解析 表达式语法是 PEG 的 选择运算符是有序的。如果 第一个选择成功,第二个 替代被忽略。如此下令 选择不是可交换的,不像 与上下文无关的无序选择 语法和正则表达式。 有序选择类似于软 某些逻辑中可用的剪切运算符 编程语言。

为什么 PEG 的选择算子会短路匹配?是因为要尽量减少内存使用(由于 memoization)吗?

我不确定正则表达式中的选择运算符是什么,但我们假设它是这样的:/[aeiou]/ 匹配元音。所以这个正则表达式是可交换的,因为我可以用 5 个中的任何一个来写它! (五个阶乘)元音字符的排列?即/[aeiou]/ 的行为与/[eiaou]/ 相同。它是可交换的有什么好处? (c.f. PEG 的不可交换性)

结果是,如果 CFG 是 直接音译为 PEG,任何 前者的歧义通过以下方式解决 确定性地选择一个解析 从可能的解析树。经过 仔细选择其中的顺序 语法选择是 指定,程序员有一个伟大的 处理对哪个解析树的控制 被选中。

这是说PEG的语法优于CFG的吗?

【问题讨论】:

  • “高级”?你的“优秀”标准是什么?
  • 对于可交换性,想想(air|airplane) 试图匹配单词飞机。
  • 您似乎混淆了选择运算符和字符类的概念。在正则表达式中,字符类用方括号[aeiou] 分隔,而选择运算符是管道字符|。在 PEG 中,选择运算符是斜杠字符 /

标签: regex parsing language-agnostic context-free-grammar peg


【解决方案1】:

CFG 语法是不确定的,这意味着某些输入可能会导致两个或多个可能的分析树。尽管大多数基于 CFG 的解析器生成器对语法的可确定性都有限制。如果它有两个或多个选择,它将给出警告或错误。

PEG 语法是确定性的,这意味着任何输入只能以一种方式解析。

举一个经典的例子;语法

if_statement := "if" "(" expr ")" statement "else" statement
              | "if" "(" expr ")" statement;

应用于输入

if (x1) if (x2) y1 else y2

可以被解析为

if_statement(x1, if_statement(x2, y1, y2))

if_statement(x1, if_statement(x2, y1), y2)

CFG 解析器会产生 Shift/Reduce 冲突,因为当到达“else”关键字时,它无法决定是应该移位(读取另一个标记)还是减少(完成节点)。当然,有办法解决这个问题。

PEG 解析器总是会选择第一选择。

哪个更好由您决定。我的看法是,通常 PEG 语法更容易编写,而 CFG 语法更容易分析。

【讨论】:

  • 你能提供一个这样的CFG语法的例子吗(有2个分析树)?
【解决方案2】:

我认为您将 CFG 与 LR 和歧义混淆了。语法不是确定性/非确定性的,尽管它们的解析器可能是。如果符合定义,歧义语法仍然是 CFG,并且可以为它构建一个确定性解析器来做 PEG 所做的事情。

【讨论】:

  • 不,CFG 有时是模棱两可的,因为它们的“选择”运算符没有优先级,所以如果给定的字符串与“选择”中的两个选项都匹配,那么你就有歧义了。 PEG 中的“选择”具有首场比赛获胜优先权,因此没有歧义,因为最左边的选项必然获胜。
  • 没有。 CFG 可能是模棱两可的,因为所有选项都同样有效。当相同的短语可以由不同的产生序列生成时,CFG 是模棱两可的。在 LL 和 LR 中,歧义意味着解析器/识别器无法知道哪个产生式序列(哪个语法树)对应于给定的短语。 PEG 通过根据声明的顺序对产生进行排序来解决歧义问题。它告诉 parses 正确的语法树是第一个语法树。
猜你喜欢
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 2010-10-02
  • 2011-12-12
  • 2010-09-16
  • 2012-03-14
  • 2012-02-06
  • 2011-02-25
相关资源
最近更新 更多