Ich versuche, eine einfache key = Wert Abfragesprache zu analysieren. Ich habe es tatsächlich mit einem riesigen Monstrositäts-Parser erreicht, den ich dann zum zweiten Mal passiere, um den Parse-Baum aufzuräumen. Was ich tun möchte, ist eine saubere Parse von unten nach oben, die Dinge wie die Verwendung von Sets für die Paare (Schlüssel, Wert) enthält, so dass redundante Paare eliminiert werden usw. Während ich es vorher funktionierte, fühle ich nicht Wie ich völlig verstanden habe, warum Pyapsing sich so verhielt, wie es war, also habe ich viel Arbeit um mich herum gemacht, irgendwie gegen den Strich gekämpft.Pyparsing setParseAction Funktion erhält keine Argumente
Derzeit hier ist der Anfang meines „vereinfacht“ Parser:
from pyparsing import *
bool_act = lambda t: bool(t[0])
int_act = lambda t: int(t[0])
def keyval_act(instring, loc, tokens):
return set([(tokens.k, tokens.v)])
def keyin_act(instring, loc, tokens):
return set([(tokens.k, set(tokens.vs))])
string = (
Word(alphas + '_', alphanums + '_')
| quotedString.setParseAction(removeQuotes)
)
boolean = (
CaselessLiteral('true')
| CaselessLiteral('false')
)
integer = Word(nums).setParseAction(int_act)
value = (
boolean.setParseAction(bool_act)
| integer
| string
)
keyval = (string('k') + Suppress('=') + value('v')
).setParseAction(keyval_act)
keyin = (
string('k') + Suppress(CaselessLiteral('in')) +
nestedExpr('{','}', content = delimitedList(value)('vs'))
).setParseAction(keyin_act)
grammar = keyin + stringEnd | keyval + stringEnd
Derzeit ist der „Grammatik“ Nicht-Terminal ist nur ein Stummel, ich werde schließlich nestbarer Konjunktionen und Disjunktionen zu den Tasten hinzufügen, so dass Durchsuchungen
a = 1, b = 2 , c in {1,2,3} | d = 4, (e = 5 | e = 2, (f = 3, f = 4))
Vorerst aber, ich habe Probleme zu verstehen, wie pyparsing meine setParseAction Funktionen aufruft: wie diese können analysiert werden. Ich weiß, dass es eine gewisse Magie gibt, wenn man bedenkt, wie viele Argumente übergeben werden, aber ich bekomme einen Fehler, bei dem überhaupt keine Argumente an die Funktion übergeben werden. Also zur Zeit, wenn ich es tue:
grammar.parseString('hi in {1,2,3}')
ich diesen Fehler:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 1021, in parseString
loc, tokens = self._parse(instring, 0)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 894, in _parseNoCache
loc,tokens = self.parseImpl(instring, preloc, doActions)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 2478, in parseImpl
ret = e._parse(instring, loc, doActions)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 894, in _parseNoCache
loc,tokens = self.parseImpl(instring, preloc, doActions)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 2351, in parseImpl
loc, resultlist = self.exprs[0]._parse(instring, loc, doActions, callPreParse=False)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 921, in _parseNoCache
tokens = fn(instring, tokensStart, retTokens)
File "/usr/lib/python2.6/site-packages/pyparsing.py", line 675, in wrapper
return func(*args[limit[0]:])
TypeError: keyin_act() takes exactly 3 arguments (0 given)
Wie Sie aus der Zurückverfolgungs sehen können, ich bin mit python2.6 und pyparsing 1.5.6
Kann mir jemand einen Einblick geben, warum die Funktion nicht die richtige Anzahl von Argumenten bekommt?
Dieser Code könnte wirklich Kommentare verwenden, um uns Lesern zu helfen. – Paragon
Das meiste davon ist ziemlich Standard-PIPARSING-Code, welchen Teil möchten Sie geklärt haben? – deontologician
Es ist einfach nicht gut lesbar. Ich begann, den Code durchzugehen, aber ich stoppte, weil es zu lange dauert, um den Zweck von Funktionen mit nicht-beschreibenden Namen herauszufinden. – Paragon