在pyparsing的结果中,有一种方法可以获取嵌套字典吗?

3

我这里有代码:

#parser.py
import pyparsing as pp

class parser:
    def __init__(self):
        self.integer = pp.Word(pp.nums).set_results_name('int')
        self.string1 = pp.QuotedString(quoteChar='"')
        self.string2 = pp.QuotedString(quoteChar="'")
        self.string = pp.Or([self.string1, self.string2]).set_results_name('str')
        self.object = pp.Or([self.string, self.integer])
        self.tuple = '(' + pp.delimited_list(self.object, delim=',') + ')'
        self.tuple = self.tuple.set_results_name('tuple')
        self.object = pp.Or([self.string, self.integer, self.tuple])

        self.varname = pp.Word(pp.alphas + "_").set_results_name('varname')
        self.let_ = pp.Keyword('let')
        self.const_ = pp.Keyword('const')
        self.var_ = pp.Keyword('var')
        self.set_ = pp.one_of(": =")
        self.variable = pp.Or([pp.Or([self.let_, self.const_, self.var_]) + self.varname + self.set_ + self.object,
                               self.varname + self.set_ + self.object])

    def parseVar(self, string):
        return self.variable.parse_string(string)
#main.py

from parser import parser
parse = parser()
print(parse.parseVar('hi = ("hi", 2)').as_dict())

然后我得到:

{"varname":"hi', 'str': 'hi',int:"2', "tuple': ['(", 'hi', '2', ')']}

抱歉“和’交换了 - [编辑]已为您修正)但我想得到的是:

{"varname": "hi", "tuple": {"str":"hi", "int":"2"}}

有没有任何方式可以获得这个结果?


底部的引号不是Python通常使用的引号。预期输出中它们应该是这样吗? - BrokenBenchmark
@BrokenBenchmark 不,我只是无法在我的设备上关闭花式引号。 - thatrandomperson
1个回答

2
你已经非常接近正确答案了。你需要做的只是从解析结果中去掉开头和结尾的括号。
这在解析中标点符号很常见。标点符号在解析过程中非常重要,但在解析后它们只会妨碍你。对于你的解析器,我将“tuple”定义为以下内容:
        LPAR = pp.Suppress("(")
        RPAR = pp.Suppress(")")
        self.tuple = pp.Group(LPAR + pp.delimited_list(self.object, delim=',') + RPAR)

接着我得到了你想要的输出结果。

我也很好奇,为什么你使用 Or([expr1, expr2, expr3]) 的方式,而不是 expr1 | expr2 | expr3 或者 expr1 ^ expr2 ^ expr3 如果你真的需要pyparsing中更昂贵的匹配最长行为。为了更容易地跟踪你的代码,我做的第一件事就是将所有这些明显的构造转换成使用pyparsing的重载运算符的构造:

    def __init__(self):
        self.integer = pp.Word(pp.nums).set_results_name('int')
        self.string1 = pp.QuotedString(quoteChar='"')
        self.string2 = pp.QuotedString(quoteChar="'")
        self.string = (self.string1 | self.string2).set_results_name('str')
        self.object = self.string | self.integer
        LPAR = pp.Suppress("(")
        RPAR = pp.Suppress(")")
        self.tuple = pp.Group(LPAR + pp.delimited_list(self.object, delim=',') + RPAR)
        self.tuple = self.tuple.set_results_name('tuple')
        self.object = self.string | self.integer | self.tuple

        self.varname = pp.Word(pp.alphas + "_").set_results_name('varname')
        self.let_ = pp.Keyword('let')
        self.const_ = pp.Keyword('const')
        self.var_ = pp.Keyword('var')
        self.set_ = pp.one_of(": =")
        self.variable = pp.Optional(self.let_ | self.const_ | self.var_) + self.varname + self.set_ + self.object

事实上,只有self.variable真正需要与self连接。所有其他的可以只写成本地变量(虽然你可能想要更改那些与Python内置函数重名的变量,比如objecttuple)。

    def __init__(self):
        integer = pp.Word(pp.nums).set_results_name('int')
        string1 = pp.QuotedString(quoteChar='"')
        string2 = pp.QuotedString(quoteChar="'")
        string = (string1 | string2).set_results_name('str')
        object = string | integer
        LPAR = pp.Suppress("(")
        RPAR = pp.Suppress(")")
        tuple = pp.Group(LPAR + pp.delimited_list(object, delim=',') + RPAR)
        tuple = tuple.set_results_name('tuple')
        object = string | integer | tuple

        varname = pp.Word(pp.alphas + "_").set_results_name('varname')
        let_ = pp.Keyword('let')
        const_ = pp.Keyword('const')
        var_ = pp.Keyword('var')
        set_ = pp.one_of(": =")
        self.variable = pp.Optional(let_ | const_ | var_) + varname + set_ + object

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接