Python Pyparsing:使用nestedExpr解析嵌套的、类型化的参数列表

Python Pyparsing:使用nestedExpr解析嵌套的、类型化的参数列表,python,nested,pyparsing,Python,Nested,Pyparsing,我有一个要分析的类型化和可选嵌套参数列表 Input: (int:1, float:3, list:(float:4, int:5)) Expected Dump: [[['int', '1'], ['float', '3'], ['list', [['float', '4'], ['int', '5']]]]] 如果省略该类型,则应根据以下值选择标准类型: Input: (1, float:3, (4, int:5)) Expected Dump: [[['str', '1'], ['f

我有一个要分析的类型化和可选嵌套参数列表

Input:
(int:1, float:3, list:(float:4, int:5))

Expected Dump:
[[['int', '1'], ['float', '3'], ['list', [['float', '4'], ['int', '5']]]]]
如果省略该类型,则应根据以下值选择标准类型:

Input:
(1, float:3, (4, int:5))

Expected Dump:
[[['str', '1'], ['float', '3'], ['tuple', [['str', '4'], ['int', '5']]]]]
正如您可能期望的那样,我将使用parseAction中的类型在解析过程中自动转换值。但这一步已经起作用了,所以我跳过这里

我对这个问题的看法是:

import pyparsing as pp

diCastTypes={
    "str": lambda value: value,
    "int": lambda value: int(value),
    "float": lambda value: float(value), 
    "tuple": lambda value: tuple(value),
    "list": lambda value: list(value),
    "set": lambda value: set(value),
    "dict": lambda value: dict(value),
}

bsQuoted = lambda expr : pp.Literal('\\').suppress() + expr

def parsingString (specialSigns = '', printables = pp.printables):
    seSpecialSigns = set(specialSigns).union(set('\\'))
    signs = ''.join(sorted(set(printables).difference(seSpecialSigns)))
    allowedLiterals = (
        pp.Literal(r"\t").setParseAction(lambda : "\t")      |
        pp.Literal(r"\ ").setParseAction(lambda : " ")       | 
        pp.Literal(r"\n").setParseAction(lambda : "\n")      | 
        pp.Word(signs)                                       |
        bsQuoted('"')                                        | 
        bsQuoted("'")
    )
    for special in seSpecialSigns:
        allowedLiterals = allowedLiterals | bsQuoted(special)           
    return pp.Combine(pp.OneOrMore(allowedLiterals))

value = parsingString('(),=:')
nestedValue = pp.Forward()
castPattern = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "str")("castType")
castPatternSeq = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "tuple")("castType")
parameterValue = pp.nestedExpr(content=(
    pp.Group( 
        (castPattern + value("rawValue")) | 
        (castPatternSeq + nestedValue)
    ) | 
    pp.Literal(',').suppress()
))
nestedValue <<= parameterValue
如您所见,未设置序列的预期默认值元组,并且结果列表的深度不正确。我猜
nestedExpr()
在模式
(4,int:5)
通过解析器
(castPatternSeq+nestedValue)
之前捕获了它。这个问题对我来说很严重,因为我计划在nestedExpr模式中调用ParseAction:

如果显式地给出了一个类型,那么它工作得很好,但如果不是这样,它当然会失败

是否有机会让nestedExpr不那么贪婪

更新1 嗨,伙计们。在昨天浪费了几乎一整天的时间后,今天早上我立即找到了上述问题的解决方案

我在实现中添加了一个
delimitedList

value = parsingString('(),=:')
nestedValue = pp.Forward()
castPattern = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "str")("castType")
castPatternSeq = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "tuple")("castType")
parameterValue = pp.nestedExpr(content=pp.delimitedList(
    pp.Group( 
        (castPattern + value("rawValue")) | 
        (castPatternSeq + nestedValue)
    )
))
nestedValue <<= parameterValue
例2中的异常让我想到,
nestedExpr
delimitedList
彼此之间的工作不太好,它们从彼此捕获了模式。不管原因是什么,这似乎是一个普遍的问题,因为如果我省略了
,就像在示例3中一样,
分隔列表
没有任何内容需要捕获,并且整个模式匹配。但不像我预期的那样,因为默认类型再次丢失。只有在没有
和显式类型的情况下,解析才能正常工作

有什么想法吗

更新2 问题是,这句话

parameterValue.parseString('(int:1, ((int:2, int:4), (int:6, int9)) )').dump()
引发了一个异常,可以通过稍微修改实现来解决(但这似乎更像是一种黑客行为,而不是真正的解决方案)。我刚刚添加了表达式
|pp.Literal(“,”).suppress()

value=parsinString('(),=:')
nestedValue=pp.Forward()
castPattern=pp.Optional(pp.oneOf(list(diCastTypes.keys())+pp.Literal(“:”).suppress(),“str”)(“castType”)
castPatternSeq=pp.Optional(pp.oneOf(list(diCastTypes.keys())+pp.Literal(“:”).suppress(),“tuple”)(“castType”)
参数值=pp.nestedExpr(内容=pp.delimitedList(
pp.Group(
(模式+价值(“原始价值”)|
(castPatternSeq+nestedValue)
)
)| pp.Literal(“,”.suppress())
嵌套值
value = parsingString('(),=:')
nestedValue = pp.Forward()
castPattern = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "str")("castType")
castPatternSeq = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "tuple")("castType")
parameterValue = pp.nestedExpr(content=pp.delimitedList(
    pp.Group( 
        (castPattern + value("rawValue")) | 
        (castPatternSeq + nestedValue)
    )
))
nestedValue <<= parameterValue
parameterValue.parseString('(int:1, (int:2, int:4))').dump()
"[[['int', '1'], ['tuple', [['int', '2'], ['int', '4']]]]]"

parameterValue.parseString('(int:1, ((int:2, int:4), (int:6, int9)) )').dump()
pyparsing.ParseException: Expected ")" (at char 6), (line:1, col:7)

parameterValue.parseString('(int:1, ((int:2, int:4) (int:6, int:9)) )').dump()
"[[['int', '1'], ['tuple', [[['int', '2'], ['int', '4']], [['int', '6'], ['int', '9']]]]]]"

parameterValue.parseString('(int:1, (tuple:(int:2, int:4) tuple:(int:6, int9)) )').dump()
"[[['int', '1'], ['tuple', [['tuple', [['int', '2'], ['int', '4']]], ['tuple', [['int', '6'], ['str', 'int9']]]]]]]"
parameterValue.parseString('(int:1, ((int:2, int:4), (int:6, int9)) )').dump()
value = parsingString('(),=:')
nestedValue = pp.Forward()
castPattern = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "str")("castType")
castPatternSeq = pp.Optional(pp.oneOf(list(diCastTypes.keys())) + pp.Literal(":").suppress(), "tuple")("castType")
parameterValue = pp.nestedExpr(content=pp.delimitedList(
    pp.Group( 
        (castPattern + value("rawValue")) | 
        (castPatternSeq + nestedValue)
    )
) | pp.Literal(",").suppress())
nestedValue <<= parameterValue