Я пытался написать CFG для использования с реализацией парсера Shift-Reduce NLTK.
Для простого примера, скажем, я хочу разобрать эти два предложения: «Она любит Джона» «Джон любит ее»
Грамматика будет довольно простой - Джон может быть первымили последнее слово, но «Она» может быть только первой, а «она» может быть только последней.(Очевидно, «Она любит ее» имеет смысл, но «ее любит Она» не имеет. Так что это грамматика (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.
Как мне обойти это? Как написать грамматику, которая могла бы принять обапредложения?
Спасибо!