我想知道将内部解析算法呈现为“LL(*)”的ANTLR v3是否完全代表PEG(解析表达式语法)解析器。
有区别吗?
答案 0 :(得分:4)
在ANTLR中,您可以对语法中的所有生产规则启用全局回溯,因此对于k >= 1
,您可以解析几乎与PEG相同的内容。当然,由于所有潜在的回溯,解析器的运行时间会降低。以(某些)内存为代价,您还可以启用memoization,使其行为类似于Packrat-parser,能够以线性时间解析输入。
所以不,在ANTLR和PEG / Packrat(启用了正确的选项!)之间没有太大区别。
答案 1 :(得分:4)
ANTLR article关于PEG是错误的。
LL(*)是DCFG(确定性上下文无关语法)的子集,它是CFG(Context Free Grammar)的子集。
PEG可以表达像A{n}B{n}C{n}
这样的上下文敏感语法,其中A
和B
以及C
都出现n
次。这是定义:
s := &(x C) A+ y / ε
x := A x B / A B
y := B y C / B C
但是没有办法在CFG中定义这样的语法(证明涉及泵引理)。因此PEG不是CFG的子集。 PEG是否是CFG的超集?我不知道。
LL(*)和PEG之间的两个关键差异:
LL(*)只能预测DFA模式,而PEG可以预测递归模式。例如,在PEG中,您可以查找嵌套的parens,而LL(*)则不能。
PEG中的选择运算符/
是优先选择(或“占有”),这意味着如果您有规则A / AB
,它永远不会到达右侧AB
。在规则A | AB
的LL(*)中,可以匹配AB
。
如果您的PEG语法没有前瞻,或者您的前瞻模式可以缩减为DFA,那么它可以转换为LL(*)。如果没有,那是不可能的。
答案 2 :(得分:3)
ANTLR和PEG不一样。这是一个非常理论化的问题,我认为最好是参考Terrence Parr撰写的this论文,他准确地指出了ANTLR和PEG之间的差异以及ANTLR LL(*)解析策略的一些优点。我不想让自己自由地解释他在那里写的东西,但你最好阅读全文。
答案 3 :(得分:1)
根据列出的工具here ANTLR是PEG解析器的完整代表:
ANTLR是Terence Parr成熟的解析器生成器,支持广泛的PEG功能,并将packrat解析与LL解析技术相结合。