Python 如何编写一个PEG解析器,它完全使用任何和所有文本,同时仍然匹配其他给定规则?

Python 如何编写一个PEG解析器,它完全使用任何和所有文本,同时仍然匹配其他给定规则?,python,parsing,peg,parsimonious,Python,Parsing,Peg,Parsimonious,我正在制作一个应用程序,使编写(PEG)解析器对于没有经验的人来说更容易理解和使用。是的,以前也做过,但对于我来说,这是一次很好的关于GUI的学习经历 部分原因是用户不必担心语法必须与整个文本匹配,他们应该能够在没有所有“样板文件”的情况下提取有意义的数据 你会怎么做?请看下面我的答案。或者提供你自己的。这个问题困扰了我一个晚上,在网上找不到答案,所以我想与大家分享 我使用图书馆所拥有的东西的MRE。它之所以有效,是因为match将匹配任何顶级用户定义的表达式,而且还有一个回退,可以匹配任何其他

我正在制作一个应用程序,使编写(PEG)解析器对于没有经验的人来说更容易理解和使用。是的,以前也做过,但对于我来说,这是一次很好的关于GUI的学习经历

部分原因是用户不必担心语法必须与整个文本匹配,他们应该能够在没有所有“样板文件”的情况下提取有意义的数据


你会怎么做?请看下面我的答案。或者提供你自己的。

这个问题困扰了我一个晚上,在网上找不到答案,所以我想与大家分享

我使用图书馆所拥有的东西的MRE。它之所以有效,是因为match将匹配任何顶级用户定义的表达式,而且还有一个回退,可以匹配任何其他内容,遗憾的是,一次只匹配一个字符

from parsimonious.grammar import Grammar

grammar = Grammar("""
root = (match / any)*
match = foo / bar # must include all top level user defined rules, but not their children (if any)
any = ~"."
foo = "foo expression" # user defined
bar = "bar expression" # user defined
""")

print(grammar.match("1 foo expression 2 bar expression 3"))
打印出来的是正确的

<Node called "root" matching "1 foo expression 2 bar expression 3">
    <Node matching "1">
        <RegexNode called "any" matching "1">
    <Node matching " ">
        <RegexNode called "any" matching " ">
    <Node matching "foo expression">
        <Node called "match" matching "foo expression">
            <Node called "foo" matching "foo expression">
    <Node matching " ">
        <RegexNode called "any" matching " ">
    <Node matching "2">
        <RegexNode called "any" matching "2">
    <Node matching " ">
        <RegexNode called "any" matching " ">
    <Node matching "bar expression">
        <Node called "match" matching "bar expression">
            <Node called "bar" matching "bar expression">
    <Node matching " ">
        <RegexNode called "any" matching " ">
    <Node matching "3">
        <RegexNode called "any" matching "3">
这对我来说意味着有一种方法可以在我不知道的更大的文本体(其中包含的文本既不是粗体也不是斜体)上使用它。除了在文档的每个位置上使用可选的“pos”(position)参数进行解析/匹配之外,这也是不优雅的

从自述中我看不出是怎么回事,如果有人知道“正确”的方法,请分享

my_grammar = Grammar(r"""
    styled_text = bold_text / italic_text
    bold_text   = "((" text "))"
    italic_text = "''" text "''"
    text        = ~"[A-Z 0-9]*"i
    """)