从Earley解析器恢复解析森林?


25

我最近在阅读Earley解析器,并认为它是迄今为止我见过的最优雅的算法之一。但是,从传统意义上讲,该算法是识别器,而不是解析器,这意味着它可以检测字符串是否与特定的CFG匹配,但不会为其生成解析树。我的问题是如何不恢复解析,而是恢复给定输入字符串的所有可能解析的解析

在Grune和Jacob的“解析技术:实用指南”中,他们说明了可用于从Earley识别器的结果中恢复解析森林的算法,但是该算法基于Unger的解析方法,其运行时间为O(n k + 1),其中k是语法中最长产生式的长度。这意味着运行时不是语法大小的多项式。此外,Earley关于该算法的原始论文提出了一种用于恢复解析森林的算法,该建议是不正确的(例如,参见Tomita的本文的第762页),尽管许多消息来源仍将其作为恢复解析森林的适当方法。 。

我的问题是,是否可以在多项式时间内为给定的输入字符串恢复一个解析森林。我在这里找到了一篇论文,该论文提供了一种使用PDA模拟为任何解析生成立方大小的解析森林表示形式的算法,因此这似乎应该可行,但是我还没有找到任何方法来做到这一点。理想情况下,我希望不将输入语法转换为CNF(确实可以解决问题),因为生成的解析林将非常混乱。

谢谢你尽你所能的帮助!


它是否必须是基于Earley解析的算法,还是您不介意使用其他通用CFG解析器?
Alex 10 Brink

1
我希望基于Earley解析器的算法。我一直在教编译器课程,花了几天的时间来寻找该问题的答案,这确实让我很烦。
templatetypedef

指数运行时不足为奇,因为单词可以具有成倍增长的解析树。实际上,如果允许任意CFG,它们甚至可以无限多个。
拉斐尔

3
@Raphael解析森林的作用恰恰是具有一种共享机制,该机制将允许以有限的结构表示所有树木,甚至无限多的树木,而且空间复杂度很小。当然,这可能会给伐木工人留下一些工作。
babou 2013年

您可能想看看Marpa。这是一个Perl模块和C库,实现了Earley解析器并具有完整的解析林支持。
hippietrail

Answers:


14

这样做当然取决于“打包森林”的正确表示,该打包森林表示给定句子的所有解析树。

我认为您想开始寻找的地方是约书亚·古德曼(Joshua Goodman)的论文(由内而外解析,哈佛大学,1999年)。基本上,您的想法是可以在特定的半环下定义解析算法。取决于半环,您将能够计算所有种类的数量和结构,而不是计算裸解析树(作为识别器或解析器)。您可以定义的一个半环(古德曼在论文中所做的工作)是一个半环,其中值是一组分析。当您最终完成一个句子的解析时,您将在主解析节点中获得所有解析树。

同样,您必须小心以正确的表示方式使其成为可能。


感谢您的参考!这看起来是一个很好的资源,我将花一些时间来研究它。
templatetypedef

8

有一篇文章介绍了如何执行此操作:

伊丽莎白·斯科特( Erisabeth Scott)从Earley Recognisers中进行 SPPF样式的解析

它描述了如何在立方时间内构建二值化的解析森林。


2
该链接现在似乎已断开。您是否有参考资料(论文标题,出版地点,作者列表)和/或更新的链接?
2013年

1
参见web.archive.org/web/20130508170633/http://thor.info.uaic.ro/…:“来自Earley识别器的SPPF样式解析”,Elizabeth Scott。另一个链接:dinhe.net/~aredridel/.notmine/PDFs/…
2014年

这是对“如何从Earley识别器获取解析森林”这一问题的正确答案。
tjvr

这在JS中有一个很好的实现:joshuagrams.github.io/pep
tjvr

在这种情况下,二值化是什么意思?
布鲁斯·亚当斯

6

您永远不需要CNF。它具有改变语法结构的缺点。但是您确实需要引入中间非终结符,以使右侧不超过2(2形式),因为RHS的长度决定了复杂度。直观地解释这一点的最佳尝试是,如果有记忆的话,Beau Shiel于1976年在计算语言学会议上发表的论文“上下文自由解析观察”。Earley的算法隐式使用2形式。它只是隐藏在算法中。关于解析森林的恢复和处理,您应该在网络上查看“解析交叉森林”。实际上非常简单。如果您(从引文或目录中)获得标题或作者以直接进行搜索,则网络上有许多论文。

实际上,您可以做的比CF还要多,并且仍然可以在多项式时间内获得解析森林。有时,问题是:一旦拥有它该怎么办?

您提到的上一篇文章的目的是表明,复杂的算法(例如GLR)不一定会在时间或空间上购买任何东西,并且可能会改变您的解析森林。

关于教学的一句话。我认为,Earley虽然开创性的,但对于教学来说太复杂了,可以用基本具有相同教育内容的简单算法代替。教学涉及概念或技术。在Earley的算法中,基本概念隐藏在细节的复杂性中,并且从技术角度来看已经过时了。这是一篇很棒的论文,但这并不意味着它是最好的教学方法。

计算语言学文献中的信息可能比通常的计算机科学渠道中的信息更多。我没有Ceriel-Grune-Jacobs的书,但是如果他们没有所有正确的参考文献,我会感到惊讶(尽管我不确定他们的选择标准)。


根据评论中的要求进行补充(2013年7月7日)

这种补充使得存在比Earley算法更简单的算法。

就像我说的那样,在“解析交叉林”处搜索网络应该很快为您提供参考,您可以从中进行进一步的挖掘。

基本思想是,所有解析共享森林的路径都不过是Bar Hillel,Perles和Shamir的旧交集结构,即使用有限自动机和上下文无关语法的常规语言和上下文无关语言。给定CF语法,您可以将构造应用于仅识别输入字符串的简单自动机。就这些。共享林只是交集的语法。它通过同态与原始语法相关,仅识别给定的字符串,但具有直到该同态的原始语法的所有解析树(即,简单地重命名非终结点)。

生成的语法包含许多无用的东西,非终结符和规则,它们要么从公理无法到达(无法在从初始符号派生的字符串中找到),要么是非生产性的(无法推导到终结符中)串)。

然后,要么必须最后用一个好的刷子清洁它(可能很长,但是算法上很简单),要么可以尝试改进结构,以使最后要刷掉的无用绒毛更少。

例如,CYK的构造就是这样,但是组织起来使得所有规则和创建的非终结符都是有效的,尽管许多规则可能无法实现。这是自下而上的技术所期望的。

自上而下的技术(例如基于LR(k)的技术)将避免不可达的规则和非终结符,但会产生无效的规则。

我认为,实际上可以通过适当使用指针来完成很多刷牙工作,但是我已经很长时间没有对此进行研究了。

实际上,所有现有算法实际上都遵循该模型。因此,这确实是问题的核心,而且非常简单。那为什么要把它埋在复杂中呢?

在文献中经常基于解析器构造的LR(k),LL(k)系列提出许多“优化”,可能对这些构造有一些静态分解(Earley没有静态分解)。它实际上可以应用于所有已知的技术,包括旧的优先级解析器。我将“优化”放在引号之间,是因为它通常不清楚您要优化的内容,甚至您实际上是否在优化它,或者改进的好处是否值得解析器增加复杂性。您会发现很少有正式或实验性的客观数据(有一些),但还有更多主张。我并不是说没有兴趣。有一些聪明的主意。

现在,一旦您了解了基本概念,通常可以通过从语法构造下推自动机,遵循您感兴趣的解析器构造技术,然后静态地(可能以增量方式)引入“优化”或改进。与该自动机相交的叉积构造(几乎与对语法执行此操作相同)或对该自动机派生的语法相交。

然后,您可以介绍钟声和口哨声,但这主要是技术细节。

据报道,艾萨克·牛顿(Isaac Newton)的《自然哲学原理》是一门重要的物理和数学课程。我认为这并不是很多学生的阅读清单。在其他所有条件都相同的情况下,尽管这是一个重要的历史著作,但我认为教授Earley的算法并不是很有用。学生有足够的学习空间。对于Knuth LR(k)论文,我认为有被许多人击落的风险,这几乎是一样的。这是一篇出色的理论分析文章,对于理论家来说可能是重要的一本著作。我强烈怀疑,鉴于硬件和软件的当前技术水平,对于构建解析器是否如此重要。解析是编译时间的重要部分,现在已经过去了,或当编译器的速度是一个关键问题时(我知道一家公司在30年前因编译成本而丧命)。解析专家可能希望在某个时候学习该专业知识,但是计算机科学,编程或工程学的普通学生不需要它。

如果学生必须花更多的时间进行解析,那么还有其他一些扩展可能会更有用和更具格式性,例如在计算语言学中使用的那些扩展。教学的首要作用是提取构成科学知识的简单思想,而不是强迫学生遭受研究科学家必须遭受的苦难(博士生除外:这是一种通过仪式:-)。

作者许可CC BY-SA 3.0


2
“ Earley ...对于教学来说太复杂了,可以用更简单的算法代替...”。您能否提供这种更简单算法的示例?
wjl

@wjl我在上述答案的附录中回复了您。我没有指出特定的算法,但是如果您按照我的建议进行搜索,可能会在文献中找到一些算法。我宁愿尝试解释为什么制作简单但有效的算法非常容易。Earley的眼镜可能是其中最复杂的。解释Bar Hillel等。构造大约是教科书的一半页面,例如带有证明的页面。
babou

@wjl回答您的请求确实花了我一些时间。对您有帮助吗?。。。。。如果您想要一种实际的算法,则初始问题的最后一个链接中将包含一个
babou

是的,谢谢; 我感谢额外的细节。我正在为一个通用的解析器库工作,正在做一些工作,并且已经对各种算法进行了大量研究。我目前倾向于早期风格的实现,因为对我来说,这似乎是一种非常容易理解的算法,并且很容易扩展到连接语法和“黑盒”(可能是上下文相关)终端。我浏览并打印了您所指的一些论文。但是我还没有认真阅读它们。
wjl

@wjl如果正在执行此操作,则应查看以下主题:上下文敏感语言,线性无上下文重写系统(LCFRS)和范围连接语法。不确定我了解什么是“黑匣子”终端。--电子邮件:inbox.com上的babou。---
babou

5

描述如何在立方时间内建立二值化分析森林的论文(在Angelo Borsotti的帖子中提到)是:伊丽莎白·斯科特(Elizabeth Scott)的“从Earley Recognizers解析SPPF样式”。您可以在这里找到它:http : //dx.doi.org/10.1016/j.entcs.2008.03.044

在本文中,描述了表示所有可能的解析树的共享打包解析森林(SPPF)的构造。子树在任何可能的情况下都是共享的,并且对应于来自同一非终端的同一子串的不同派生的节点被合并。


感谢您的指导。在立方时间内建立二元化的解析森林是标准做法。二进制化是获取立方时间的唯一方法,因此OP对语法大小的复杂性的评论是无关紧要的。另一个问题是要了解解析林如何以二进制方式进行二进制化。那可能取决于算法。其他问题包括共享林中的共享量以及解析策略的实际效率(Earley可能不是一个好主意)。所有这些都是在OP的最后参考中开发的。我在回答中概述了对该问题的一般正式看法。
2014年

1

我想通过建议您阅读这篇文章来回应上面的答案:

http://dx.doi.org/10.1016/j.entcs.2008.03.044

尽管我想在本文中已经实现了该算法,但我想证明自己的资格,但是我认为这是错误的。特别是第4节第二段的第一句话。您为Earley称为“扫描”阶段的名称所做的标记应指向p到q,而不是相反。

特别是以下几行:

将E0设置为项(S :: =·α,0)。对于i> 0,通过为每个q =(A :: =α·aiβ,j)∈Ei-1加p =(A :: =αai·β,j)项来初始化Ei,如果α=,则创建一个从q到p标记为i − 1的前任指针

应该读为“从p到q”,而不是“从q到p”

我实现了最初说明的算法,这给了我一些手工构建的测试用例的错误,这些错误在我更改了指针的方向后就得到了修复。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.