2016-06-29 8 views
1

Auf einer einfachen Grammatik bin ich in der schlechten Situation, dass eine meiner ParseActions nicht aufgerufen wird.Pyparsing: ParseAction nicht

Für mich ist das seltsam, da ParseActions eines Basissymbols ("logic_oper") und eines abgeleiteten Symbols ("cmd_line") korrekt aufgerufen werden. Nur "pa_logic_cmd" wird nicht aufgerufen. Sie können dies auf der Ausgabe sehen, die am Ende des Codes enthalten ist.

Da es keine Ausnahme beim Parsing der Eingabezeichenfolge gibt, gehe ich davon aus, dass die Grammatik (im Grunde) korrekt ist.

import io, sys 
import pyparsing as pp 

def diag(msg, t): 
    print("%s: %s" % (msg , str(t))) 


def pa_logic_oper(t): diag('logic_oper', t) 
def pa_operand(t):  diag('operand', t) 
def pa_ident(t):  diag('ident', t) 
def pa_logic_cmd(t): diag('>>>>>> logic_cmd', t) 
def pa_cmd_line(t):  diag('cmd_line', t) 

def make_grammar(): 

    semi = pp.Literal(';') 
    ident = pp.Word(pp.alphas, pp.alphanums).setParseAction(pa_ident) 
    operand = (ident).setParseAction(pa_operand) 

    op_and  = pp.Keyword('A') 
    op_or  = pp.Keyword('O') 

    logic_oper = ((op_and | op_or) + pp.Optional(operand)) 
    logic_oper.setParseAction(pa_logic_oper) 

    logic_cmd = logic_oper + pp.Suppress(semi) 
    logic_cmd.setParseAction(pa_logic_cmd) 

    cmd_line = (logic_cmd) 
    cmd_line.setParseAction(pa_cmd_line) 

    grammar = pp.OneOrMore(cmd_line) + pp.StringEnd() 

    return grammar 

if __name__ == "__main__": 
    inp_str = ''' 
     A param1; 
     O param2; 
     A ; 
     ''' 
    grammar = make_grammar() 
    print("pp-version:" + pp.__version__) 

    parse_res = grammar.parseString(inp_str) 

'''USAGE/Output: python test_4.py 
pp-version:2.0.3 
operand: ['param1'] 
logic_oper: ['A', 'param1'] 
cmd_line: ['A', 'param1'] 
operand: ['param2'] 
logic_oper: ['O', 'param2'] 
cmd_line: ['O', 'param2'] 
logic_oper: ['A'] 
cmd_line: ['A'] 
''' 

Kann mir jemand einen Hinweis auf dieses Problem parseAction geben? Danke,

+0

Irgendwelche Gedanken über die Aktualisierung auf den neuesten Piparsen? Wir sind jetzt bei 2.1.6 und es sollte bei dieser Version für eine Weile stabil sein. – PaulMcG

Antwort

0

Das Problem dabei ist:

cmd_line = (logic_cmd) 
cmd_line.setParseAction(pa_cmd_line) 

Die erste Zeile cmd_line tritt der gleiche Ausdruck wie logic_cmd sein. Sie können durch das Hinzufügen dieser Zeile überprüfen:

print("???", cmd_line is logic_cmd) 

Dann wird die zweite Zeile ruft setParseAction, die die Parse-Aktion von logic_cmd überschreibt, so dass die pa_logic_cmd wird nie aufgerufen.

Entfernen Sie die zweite Zeile, da Sie bereits den Aufruf der Analyseaktion mit pa_logic_cmd testen. Sie könnte ändern, um stattdessen die addParseAction Methode zu verwenden, aber meiner Meinung nach ist das ein ungültiger Test (Hinzufügen von 2 Parse-Aktionen zu demselben pyparser Expressionsobjekt).

Oder, ändern Sie die Definition von cmd_line zu:

cmd_line = pp.Group(logic_cmd) 

Jetzt haben Sie in einem anderen Ausdruck gewickelt logic_cmd, und Sie können dann unabhängig voneinander eingestellt und testen Sie die Ausführung von Parse-Aktionen auf den zwei verschiedenen Ausdrücken .

+0

Danke für Ihre Hilfe. Du hast vollkommen recht. (Der ursprüngliche Code hatte mehrere Elemente in diesen Klammern. Um den Code kurz zu halten, habe ich sie entfernt ...) Ja, und ich habe auf die neueste Version von pyparsing aktualisiert. – karlp

Verwandte Themen