gpt4 book ai didi

python - Pyparsing 中的递归语法

转载 作者:太空宇宙 更新时间:2023-11-03 16:01:31 25 4
gpt4 key购买 nike

我有以下类似 JSON 的递归语法:

aerof_bnf_spec = """
inputfile
block
block inputfile
block
under key { values }
values
key = value;
key = value; values
block
block values
key
string
value
string
real
int
"""

LBRACK, RBRACK, LBRACE, RBRACE, EQUAL, SEMICOLON = map(Suppress, "[]{}=;")
TAG = Suppress("under")
caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowers = caps.lower()
digits = "0123456789"

# define value
aerofNumber = pyparsing_common.number()
aerofFilePath = dblQuotedString().setParseAction(removeQuotes)
aerofString = Word(caps + lowers + digits)
aerofValue = (aerofNumber | aerofFilePath | aerofString)

# define key
aerofKey = Word(caps + lowers + digits)

# define key = value;
aerofPair = Group(aerofKey + EQUAL + aerofValue + SEMICOLON)

#define values and block recursively
aerofBlock = Forward()
aerofValues = Forward()
aerofBlock << Group(TAG + aerofKey + LBRACE + aerofValues + RBRACE)
aerofValues << Dict((aerofPair | aerofBlock) + ZeroOrMore(aerofValues) )

# define inputfile
aerofInputFile = Dict(OneOrMore(aerofBlock))

# remove comment
aerofComment = cppStyleComment
aerofInputFile.ignore(aerofComment)

一旦我改变

aerofValues << Dict((aerofPair | aerofBlock | (aerofPair + aerofValues)|(aerofBlock + aerofValues)) )

aerofValues << Dict((aerofPair | aerofBlock) + ZeroOrMore(aerofValues) )

代码运行良好。我的问题是:

  1. 它们看起来相等吗?
  2. 如果是这样,为什么第一个表单在 pyparsing 中不起作用?
  3. pyparsing 支持所有 BNF 语法吗?

最佳答案

aerofValues << Dict((aerofPair | aerofBlock | 
(aerofPair + aerofValues) | (aerofBlock + aerofValues)))

从“|”开始解析为 MatchFirst 表达式,第一个列出的匹配表达式将用于匹配。如果我将整数列表定义为:

integer_list <<= (integer | integer + integer_list)

并尝试解析“1 2 3 4”,我们的integer_list将通过仅匹配前导“1”来满足。更改为:

integer_list <<= (integer + integer_list | integer)

现在让我们首先尝试整数列表,如果没有找到多个整数,那么看看是否只存在一个整数。但我建议使用 pyparsing 来实现这一点:

integer_list = OneOrMore(integer)

所以你的陈述非常接近等价,我认为如果重新排序,第一个将起作用:

aerofValues << Dict(((aerofPair + aerofValues) | (aerofBlock + aerofValues) | aerofPair | aerofBlock) )

或者只是:

aerofValues << Dict(OneOrMore(aerofPair | aeroOfBlock))

Pyparsing 几乎支持任何 BNF 语法,只要不包含左递归。 Pyparsing 将在这个表达式上爆炸:

integer_list <<= (integer_list + integer | integer)

默认情况下,pyparsing 本身不会执行任何前瞻,但您可以使用 NotAny (或运算符 '~')和 FollowedBy 指定前瞻。

此外,pyparsing 不会像您在正则表达式中看到的那样进行回溯。

关于python - Pyparsing 中的递归语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40298186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com