如何将Earley识别器转换为Earley Parser

时间:2016-10-25 18:31:16

标签: parsing nlp

我已经实现了Earley Recognizer算法。我无法弄清楚如何从图表中获取解析树。我有指向“生成”添加到图表中的规则的规则的后向指针,但我完全按照字面意思,对于当前规则R1

1)如果点后面有一个终端,请根据输入句子检查终端,将规则R2添加到R2R1相同的下一列但是点移了。 R2的后向指针= R1的后向指针。

2)如果点后面有一个非终端,则向当前列添加新规则,每个新规则的后向指针指向R1

3)如果点(完成的规则​​)之后没有任何内容,则R1完成,因此我们扫描与R1关联的列(小于curr列),找到所有规则{在点后面有Rj左侧的{1}},将R1添加到当前列但移动点,使Rj的后向指针指向Rj }。

我认为我没有得到正确的输出,所以我想知道这是否是我的逻辑问题。需要对Earley识别器进行哪些操作才能将其转换为Earley解析器?

我有一个R1方法可以对规则的后向指针进行递归,但我认为它不会产生正确的输出。对于句子

print_parse

with(忽略概率)语法

Papa ate the caviar

它生成:

1   ROOT    S
1   S   NP VP
0.8 NP  Det N
0.1 NP  NP PP
0.7 VP  V NP
0.3 VP  VP PP
1   PP  P NP
0.1 NP  Papa
0.5 N   caviar
0.5 N   spoon
1   V   ate
1   P   with
0.5 Det the
0.5 Det a

我知道解析图表是正确的,但是我已经检查了它,而不是手动(手动)执行解析表。 我知道有关此问题的其他问题,但他们都指向文件,坦率地说,他们很难。我真的很感激一些帮助。

1 个答案:

答案 0 :(得分:1)

Elizabeth Scott发表了一篇关于如何在最坏情况下形成解析森林的论文O(n ^ 3)时间。以下是纸质链接:http://www.sciencedirect.com/science/article/pii/S1571066108001497/pdf?md5=0cbf8671559f121c5d4e612cc392604f&pid=1-s2.0-S1571066108001497-main.pdf。集成算法在第63页,我将在下面简要介绍它。

我认为她在后端指针中发现了一个错误建议实现,不确定您是否遇到了同样的问题。从第55页开始的第2节和第3节概述了它。基本上,当向项添加多个后向指针时可能会失败。

我说解析森林因为earley解析器可以很好地处理歧义,而解析林通过“或”节点表示这种歧义。 “或”节点表示解析林中的备用路径。

我在我的earley解析库中用c#实现了它: https://github.com/patrickhuber/pliant

基本上,您可以创建四种类型的节点:

  1. 中间节点 - 仅用作传递节点以保持树二进制。如果没有它们,树将不是二进制的,并且具有大于O(n ^ 3)的更坏的情况时间复杂度。
  2. 符号节点 - 是解析林的实际节点,代表语法中的非终端。
  3. 终端节点 - 是运行解析时在输入字符串中找到的数据。
  4. 或节点 - 表示语法中的歧义选择。
  5. 算法的粗略描述:

    您需要跟踪当前earley传递期间添加的节点。如果您需要同一节点,则可以从节点集中重用它。每次通过后都清除此设置。最好将其包装在“创建节点”函数中,并将方法放在名为AddOrGetExistingNode的节点集上。斯科特在她的论文中有一个“MAKE_NODE”功能。

    在扫描期间,非常简单,只需创建/重用令牌节点并将其附加到扫描内容项。

    在预测期间,如果当前非终端在语法中可以为空,则只创建一个解析节点。这是Aycock和Horspool在他们的论文“Practical Earley Parsing”中找到的错误修复。在这个场景中,你正在完成和预测。我在这里回答了一个问题:Earley cannot handle epsilon-states already contained in chart并展示了一些例子。

    在完成期间,您将为新状态创建一个解析节点,并添加附加到已完成项目的节点和预测项目节点的节点。

    创建节点时,如果虚线规则的位置位于生产中间,则创建中间节点。如果它位于规则的末尾,则创建符号节点。