Hier ist ein Parser, der wahrscheinlich ähnlich der ist, dass Sie schreibt:
import pyparsing as pp
LPAR, RPAR = map(pp.Suppress, "()")
OR = pp.Keyword("OR")
term = pp.pyparsing_common.identifier
or_expr = pp.Forward()
or_expr <<= pp.Group(OR + pp.Group(LPAR + pp.delimitedList(or_expr | term)) + RPAR)
Wenn es den String parst Sie gabst es den gleichen verschachtelten Ausgang zur Verfügung stellt.
die „expn“ Ausdruck Namen zu erstellen, können Sie eine Parse-Aktion verwenden, um die Ausdrücke zu sammeln, und die damit verbundenen Ausdruck id, in einer globalen Liste var:
# add parse action to convert OR's to exprs
exprs = []
def generate_expr_definition(tokens):
expr_name = "exp{}".format(len(exprs)+1)
exprs.append((expr_name, tokens.asList()[0]))
return expr_name
or_expr.addParseAction(generate_expr_definition)
Wenn Sie diesen Parser ausführen, die erstellte Ergebnisse sind nicht der wichtige Teil. Was wichtig ist, ist die exprs
Liste, die gebaut wurde, während Analyse:
or_expr.parseString(sample)
# generate assignments for each nested OR expr
for name, expr in exprs:
print("{} = {}".format(name, expr))
Das gibt:
exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', ['exp1', 'in3']]
Jetzt sehe ich das, und fragen: „Wie werde ich wissen, der Unterschied zwischen 'exp1'
das war analysiert aus dem Eingang vs. 'exp1'
, das angeblich einen analysierte Ausdruck darzustellen Wenn dies als eine Python Zuordnung zu interpretieren ist, sollte es wirklich lesen.
exp2 = ['OR', [exp1, 'in3']]
ohne Anführungszeichen um den Variablennamen.
Um dies zu tun, müssen wir ein Objekt aus der Analyse Aktion, die repr
als Name ohne die umgebenden Anführungszeichen wird zurückgeben. Wie folgt aus:
class ExprName:
def __init__(self, name):
self._name = name
def __repr__(self):
return self._name
Ändern der return-Anweisung in der Parse-Aktion:
return ExprName(expr_name)
und die resultierende Ausgabe sieht nun wie:
exp1 = ['OR', ['in1', 'in2']]
exp2 = ['OR', [exp1, 'in3']]
Jetzt können Sie die generierten expN
Vars unterscheiden von geparsten Eingaben.
Wow, es funktioniert wie ein Zauber, wusste nicht, dass Pyparsing so mächtig war, ich dachte daran, den Parse Baum zu durchqueren, um die Ausdrücke zu bekommen, und das macht tatsächlich das, was ich von Anfang an wollte Ausdruck von unten nach root – dpalma
Ich habe noch eine Frage, was passiert, wenn ich keinen verschachtelten Ausdruck habe? weil ich Namen nicht ersetzen möchte, wenn ich einen einfachen Ausdruck wie ODER habe (in1, in2) – dpalma
Ist das geschehen? Ich glaube nicht, dass mein Test das tut (schau dir die gepostete Ausgabe in meiner Antwort an). – PaulMcG