简体   繁体   English

有没有办法在 pyparsing 结果中获取嵌套字典?

[英]Is there a way to get nested dictionary’s in pyparsing result?

I have the code here:我这里有代码:

#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())

And I get:我得到:

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

(sorry for the “ and ' swapping - [EDIT]fixed these for you ) But what I want to get is this: (对不起“和”交换 - [编辑]为你修复了这些)但我想要得到的是:

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

Is there anyway I could get this result?反正我能得到这个结果吗?

You are really very very close with this.你真的非常非常接近这一点。 The only thing you need to do is to suppress the opening and closing parentheses from your parsed results.您唯一需要做的就是从解析结果中抑制左括号和右括号。

This is pretty common with punctuation in parsing.这在解析中的标点符号很常见。 The punctuation characters are super important during the parsing process, but post-parsing, they just get in the way.标点符号在解析过程中非常重要,但在解析后,它们只是碍事。 For your parser, I defined tuple as this:对于您的解析器,我将tuple定义为:

        LPAR = pp.Suppress("(")
        RPAR = pp.Suppress(")")
        self.tuple = pp.Group(LPAR + pp.delimited_list(self.object, delim=',') + RPAR)

after which I get the output that you said that you wanted.之后我得到你说你想要的输出。

I'm also curious, as to why you use the Or([expr1, expr2, expr3]) style, as opposed to expr1 | expr2 | expr3我也很好奇,为什么你使用Or([expr1, expr2, expr3])风格,而不是expr1 | expr2 | expr3 expr1 | expr2 | expr3 expr1 | expr2 | expr3 or expr1 ^ expr2 ^ expr3 if you truly need the more expensive match-longest behavior of pyparsing's Or. expr1 | expr2 | expr3expr1 ^ expr2 ^ expr3如果您确实需要 pyparsing 的 Or 的更昂贵的匹配最长行为。 To work on your code, the first thing I did to make it easier for me to follow was to convert all those overt constructions to ones using pyparsing's overloaded operators:为了处理你的代码,我做的第一件事是让我更容易理解,就是使用 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

And in truth, the only one of these that really needs to be attached to self is self.variable .事实上,其中唯一真正需要附加到self的是self.variable All the rest can be written just a local variables (though you will probably want to change those like object and tuple which clash with Python builtins).其余的都可以只写一个局部变量(尽管您可能希望更改与 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM