我一直在尝试编写CFG以与NLTK的Shift-Reduce Parser实现结合使用。
举一个简单的例子,假设我要解析这两个句子: “她爱约翰” “约翰爱她”
语法很容易-约翰可以是第一个或最后一个词,但是“她”只能是第一个单词,“她”只能是最后一个单词。 (显然“她爱她”是有意义的,但是“她爱她”没有意义。所以这就是语法(ST代表“开始”):
S -> NP_ST V NP_END
NP_ST -> NP | ST
NP_END -> NP | END
NP -> 'John'
V -> 'loves'
ST -> 'She'
END -> 'her'
听起来很简单,那是什么问题呢? 好吧,如果出现歧义,SR解析器将只选择第一个选项(如果失败,他将不会回溯到第二个选项)。
因此,在这种情况下,“约翰爱她”效果很好,但“她爱约翰”失败了-因为“约翰”被认为是NP_ST而不是NP_END。
Parsing 'She loves John'
[ * She loves John]
S [ 'She' * loves John]
R [ ST * loves John]
R [ NPST * loves John]
S [ NPST 'loves' * John]
R [ NPST V * John]
S [ NPST V 'John' * ]
R [ NPST V NP * ]
R [ NPST V NPST * ]
如果我在语法中切换第2行和第3行,则会发生相反的情况-“她爱约翰”有效,但“约翰爱她”无效,因为“约翰”被识别为NP_END而不是NP_ST。
我该如何解决?如何编写可以接受两个句子的语法?
谢谢!