无法在 grako 语法中定义用于处理特殊标记的规则优先级
Cannot define rule priority in grako grammar for handling special tokens
我正在尝试通过 Grako 生成的语法来分析一些文档,该语法应该解析简单的句子以进行进一步分析,但在使用某些特殊标记时会遇到一些困难。
(Grako 风格)EBNF 看起来像:
abbr::str = "etc." | "feat.";
word::str = /[^.]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
我在以下内容上使用了上文法:
This is a sentence. This is a sentence feat. an abbrevation. I don't
now feat. etc. feat. know English.
使用简单 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."
]
我不知道为什么会发生这种情况,尤其是在最后一句话中,缩写是句子的一部分,而它们不在前面的句子中。明确地说,我希望句子定义中的缩写规则比单词规则具有更高的优先级,但我不知道如何实现这一点。我玩弄了消极和积极的前瞻性,但没有成功。我知道如何用正则表达式达到我的预期结果,但进一步分析需要上下文无关语法,所以为了可读性,我想把所有东西都放在一个语法中。自从我上次以这种方式使用语法以来已经有一段时间了,但我不记得 运行 在那种问题中。我通过 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
问题出在您用于 word
规则的正则表达式上。正则表达式将解析您告诉它们的任何内容,并且该正则表达式会占用空格。
此修改后的语法可以满足您的需求:
@@grammar:: Pages
abbr::str = "etc." | "feat.";
word::str = /[^.\s]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
start = page ;
一个--trace
运行一下子就把问题暴露了。
我正在尝试通过 Grako 生成的语法来分析一些文档,该语法应该解析简单的句子以进行进一步分析,但在使用某些特殊标记时会遇到一些困难。
(Grako 风格)EBNF 看起来像:
abbr::str = "etc." | "feat.";
word::str = /[^.]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
我在以下内容上使用了上文法:
This is a sentence. This is a sentence feat. an abbrevation. I don't now feat. etc. feat. know English.
使用简单 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."
]
我不知道为什么会发生这种情况,尤其是在最后一句话中,缩写是句子的一部分,而它们不在前面的句子中。明确地说,我希望句子定义中的缩写规则比单词规则具有更高的优先级,但我不知道如何实现这一点。我玩弄了消极和积极的前瞻性,但没有成功。我知道如何用正则表达式达到我的预期结果,但进一步分析需要上下文无关语法,所以为了可读性,我想把所有东西都放在一个语法中。自从我上次以这种方式使用语法以来已经有一段时间了,但我不记得 运行 在那种问题中。我通过 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
问题出在您用于 word
规则的正则表达式上。正则表达式将解析您告诉它们的任何内容,并且该正则表达式会占用空格。
此修改后的语法可以满足您的需求:
@@grammar:: Pages
abbr::str = "etc." | "feat.";
word::str = /[^.\s]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};
start = page ;
一个--trace
运行一下子就把问题暴露了。