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