2012-03-23 8 views
6

Używam pyparsing do parsowania ciągu szesnastkowego i szukam automatycznego sposobu drukowania drzewa parsera.Wydrukuj drzewo wyników pyparsingu

Podejście bliskie jest zrzutem polecenia, ale drukuje wiele powielonych informacji.

Na przykład:

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

Celem jest to, że wynikiem result.dump() było coś podobnego do

- 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 

Pretty drukowania nie jest obowiązkowe, udawał, że jest struktura drzewa .

Czy istnieje sposób na wykonanie tego wydruku, czy też będę potrzebował ustawić wartośćParsena dla wszystkich reguł?

Odpowiedz

4

Wygląda na to, że dla każdej reguły potrzebujesz funkcji setParseAction.

Od parsing to object hierarchy: „Dołącz analizować działania każdej wypowiedzi, ale tutaj jest trick: użyć klasy zamiast funkcji startowych metoda klasy będą się nazywa, i powrócić instancję tej klasy.”.

+0

Dzięki, zrobiłem coś takiego jak SimpleBool – Nine

+2

Doskonała! Myślę, że twoja implementacja wygląda na rozsądny początek. –

+1

dokładnie to, czego szukałem! bez tagowania trudno jest rozpoznać typy w drzewie. – dashesy

2

Wolę dodawać odpowiedź zamiast edytować pytanie, na dużo kodu ..

Nie jest idealny, poziomy nie są poprawne, a klasy mogą zostać odrzucone, jeśli mogę uzyskać resultName z printAction. Może powinniśmy stworzyć nowe pytanie: -/

Jeśli ktoś go używać i poprawy proszę powiedzieć jak :)

#!/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]