无法在grako语法中定义规则优先级来处理特殊令牌

时间:2016-12-22 10:47:46

标签: python grammar grako tatsu

我试图通过Grako生成的语法分析一些文档,该语法应该解析简单的句子以进行进一步的分析,但是在使用某些特殊标记时会遇到一些困难。

(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规则比单词规则具有更高的优先级,但我不知道如何实现这一点。我玩弄了消极和积极的前瞻而没有成功。我知道如何使用正则表达式实现我的预期结果,但是进一步分析需要无上下文语法,因此为了便于阅读,我想将所有内容都放在一个语法中。自从我上次使用语法以来已经有一段时间了,但我不记得遇到过那种问题。我通过谷歌搜索了一段时间没有成功,所以也许社区可能会分享一些见解。

提前致谢。

我用于测试的代码,如果需要:

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 个答案:

答案 0 :(得分:2)

问题在于您用于word规则的正则表达式。正则表达式将解析你告诉他们的任何内容,并且正则表达式正在吃空白。

这个修改后的语法可以达到你想要的效果:

@@grammar:: Pages

abbr::str = "etc." | "feat.";
word::str = /[^.\s]+/;
sentence::Sentence = content:{abbr | word} ".";
page::Page = content:{sentence};

start = page ;

--trace运行立即显示问题。