我正在使用pyparsing来解析十六进制字符串,我正在寻找一种自动打印解析器树的方法。
近乎接近的方法是命令转储,但它打印了大量重复的信息。
例如:
from pyparsing import * #Word, Optional, OneOrMore, Group, ParseException
data = Forward()
arrayExpr = Forward()
def data_array(s,l,t):
n = int(t[0], 16)
arrayExpr << ( n * data)
return t[0]
array = Word(hexnums, exact=2).setParseAction(data_array) + arrayExpr
data << (Literal('01') + array.setResultsName('array')
| Literal('03') + Word(hexnums, exact=2)('char')
| Literal('04') + Word(hexnums, exact=2)('boolean'))
frame = (Word(hexnums, exact=2)('id') \
+ data('data'))('frame')
result = frame.parseString("02010203010302");
print result.dump()
目标是result.dump()的结果类似于
- frame: ['02', '01', '03', '03', '01', '04', '02', '03', '02']
- id: 02
- array: ['03', '03', '01', '04', '02', '03', '02']
- char: 01
- boolean: 02
- char: 02
漂亮的印刷品不是强制性的,假装是树形结构。
是否有办法制作此版画,或者我需要为所有规则设置setParseAction?
答案 0 :(得分:4)
看起来你需要为每个规则设置一个setParseAction。
从parsing to object hierarchy:“将解析操作附加到每个表达式,但这里有诀窍:使用类而不是函数。类的 init 方法将被调用,并返回一个那个班的实例。“
答案 1 :(得分:2)
喜欢添加答案而不是编辑问题,代码很多..
不完美,级别不正确,如果我可以从printAction获取resultsName,则可以丢弃类。也许应该创建一个新问题: - /
如果有人使用它并改进,请说明如何:)
#!/usr/bin/python
from pyparsing import * #Word, Optional, OneOrMore, Group, ParseException
data = Forward()
level = 0
arrayExpr = Forward()
def data_array(s,l,t):
n = int(t[0], 16)
arrayExpr << ( n * data)
return t[0]
class TreeChild(object):
def __init__(self,t):
self.args = t
def __str__(self):
ret = " %s: " % self.name
return ' ' * level + ret + self.args[0] + "\n"
class TreeBranch(object):
def __init__(self,t):
self.args = t
def __str__(self):
global level
level = level + 1
childs = " ".join(map(str,self.args))
level = level - 1
ret = " %s: " % self.name + '\n'
return ' ' * level + ret + childs + "\n"
class Frame(TreeBranch):
name = 'frame'
class Char(TreeChild):
name = 'char'
class Boolean(TreeChild):
name = 'boolean'
class Id(TreeChild):
name = 'id'
class Array(TreeBranch):
name = 'array'
array = Suppress(Word(hexnums, exact=2).setParseAction(data_array)) + arrayExpr
data << (Suppress(Literal('01')) + array.setResultsName('array').setParseAction(Array)
| Suppress(Literal('03')) + Word(hexnums, exact=2)('char').setParseAction(Char)
| Suppress(Literal('04')) + Word(hexnums, exact=2)('boolean').setParseAction(Boolean))
frame = (Word(hexnums, exact=2)('id').setParseAction(Id) \
+ data('data'))('frame').setParseAction(Frame)
result = frame.parseString("020103030104020302");
print result[0]