我有一个类型化的可选嵌套参数列表要解析。在
Input:
(int:1, float:3, list:(float:4, int:5))
Expected Dump:
[[['int', '1'], ['float', '3'], ['list', [['float', '4'], ['int', '5']]]]]
如果省略类型,则应根据以下值选择标准类型:
^{pr2}$如您所料,我将使用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
此实现几乎可以正常工作,但我的嵌套序列的默认值有一个严重问题:
parameterValue.parseString('(int:1, float:3, list:(float:4, int:5))').dump()
"[[['int', '1'], ['float', '3'], ['list', [['float', '4'], ['int', '5']]]]]"
parameterValue.parseString('(1, float:3, (4, int:5))').dump()
"[[['str', '1'], ['float', '3'], [['str', '4'], ['int', '5']]]]"
如您所见,序列的预期默认值tuple没有设置,结果列表的深度也不正确。我猜nestedExpr()
在模式通过解析器(castPatternSeq + nestedValue)
之前捕捉到(4, int:5)
。这个问题对我来说很严重,因为我计划在nestedExpr模式中调用parserAction:
(castPattern + value("rawValue")).setParseAction(castParameter)) |
(castPatternSeq + nestedValue).setParseAction(castParameter))
如果显式地给出了一个类型,那么这种方法很有效,但是如果不是这样,它当然会失败。在
有没有机会让nestedExpr
少一点贪婪?在
嗨,伙计们。在昨天浪费了几乎一天的时间之后,今天早上我立即找到了解决上述问题的方法。在
我在实现中添加了一个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
这很好,但不是很好,正如您在以下示例中看到的:
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']]]]]]]"
示例2中的异常让我想到,nestedExpr
和{,
,那么{,
和显式类型,解析才能正常工作。在
有什么想法吗?在
问题是,声明
parameterValue.parseString('(int:1, ((int:2, int:4), (int:6, int9)) )').dump()
引发一个异常,可以通过稍微改变实现来解决(但这看起来更像是一种黑客行为,而不是真正的解决方案)。我刚刚添加了表达式| 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)
)
) | pp.Literal(",").suppress())
nestedValue <<= parameterValue
目前没有回答
相关问题 更多 >
编程相关推荐