Невозможно определить приоритет правила в грамматике грако для обработки специальных токенов
Я пытаюсь проанализировать некоторые документы с помощью грамматики, сгенерированной с помощью Grako, которая должна анализировать простые предложения для дальнейшего анализа, но сталкивается с некоторыми трудностями с некоторыми специальными токенами.
(Грако-стиль) EBNF выглядит так:
abbr::str = "etc." | "feat.";
word::str = /[^.]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
Я использовал верхнюю грамматику для следующего содержания:
Это предложение. Это подвиг предложения. сокращение. Теперь я не подвиг. и т. д. знать английский.
Результат с использованием простого NodeWalker:
[
'This is a sentence.',
'This is a sentence feat.',
'an abbrevation.',
"I don't know feat.",
'etc. feat. know English.'
]
Мое ожидание:
[
'This is a sentence.',
'This is a sentence feat. an abbrevation.',
"I don't know feat. etc. feat. know English."
]
Я понятия не имею, почему это происходит, особенно в последнем предложении, где сокращения являются частью предложения, а не в предыдущих предложениях. Чтобы было ясно, я хочу, чтобы правило abbr в определении предложения имело более высокий приоритет, чем слово rule, но я не знаю, как этого добиться. Я играл с негативным и позитивным взглядом без успеха. Я знаю, как добиться ожидаемых результатов с помощью регулярных выражений, но для дальнейшего анализа требуется не зависящая от контекста грамматика, поэтому я хочу поместить все в одну грамматику для удобства чтения. Прошло много времени с тех пор, как я последний раз использовал грамматики таким образом, но я не помню, чтобы я сталкивался с подобными проблемами. Некоторое время я искал через Google, но безуспешно, поэтому, возможно, сообщество может поделиться своим пониманием.
Заранее спасибо.
Код, который я использовал для тестирования, если требуется:
from grako.model import NodeWalker, ModelBuilderSemantics
from parser import MyParser
class MyWalker(NodeWalker):
def walk_Page(self, node):
content = [self.walk(c) for c in node.content]
print(content)
def walk_Sentence(self, node):
return ' '.join(node.content) + "."
def walk_str(self, node):
return node
def main(filename: str):
parser = MyParser(semantics=ModelBuilderSemantics())
with open(filename, 'r', encoding='utf-8') as src:
result = parser.parse(src.read(), 'page')
walker = HRBWalker()
walker.walk(result)
Используемые пакеты: Python 3.5.2 Grako 3.16.5
1 ответ
Проблема с регулярным выражением, которое вы используете для word
править. Регулярные выражения будут анализировать все, что вы им скажете, и это регулярное выражение поглощает пробелы.
Эта измененная грамматика делает то, что вы хотите:
@@grammar:: Pages
abbr::str = "etc." | "feat.";
word::str = /[^.\s]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
start = page ;
--trace
бежать сразу же обнаружил проблему.