Wie kann man wissen, welches Pyparsing -Parserelement welche Parseresulate erzeugt hat?
Posted: 19 May 2025, 09:10
Das Problem
Ich habe eine Reihe von Gruppenausdrücken wie diese, die alle zur gleichen Grammatik beitragen:
Die innersten haben die folgenden Attribute, von denen keiner den ursprünglichen Ausdruck herausgefunden hat (diese sind auch nicht dokumentiert; in dieser gesamten Seite "modal oder all_names ):
"> ">"> ">"> ">"> ">"> ">"> ">">
Wenn ich ein willkürliches Parseresults -Objekt bestanden habe, woher weiß ich, welcher Ausdruck ihn erstellt hat? Gruppe . Ich habe eine expandierte -Klass, die das genaue Gegenteil (Code hier für die Kürze ausgelassen wird), die in einem übergeordneten Ausdruck verwendet werden kann, um die Ergebnisse zu verflachten. Um jedes dieser Elemente korrekt zu behandeln, muss ich den Typ des Ausdrucks kennen, der ihn überhaupt erzeugt hat. ist eine generische Unterklasse von Tokenconverter . Dies bedeutet, dass das Objekt an expon.postParse () ein tatsächlicher Parseresults sein muss oder zumindest die gleiche Schnittstelle von einem (Iterabilität, Einweisbarkeit, Methoden usw.) haben. Dies, aber ich bin mir nicht einmal sicher, ob dies die beabsichtigten Argumente sind. Die Parameter sind ebenfalls undokumentiert, nicht angedeutet, und der Code ist verwirrend zu lesen.:
.
Die zweite ist hässlich. Noch mehr mit zehn Ausdrücken. Darüber hinaus hat es das gleiche Problem mit dem dritten, was unten erklärt wird. Die ersten Ergebnisse müssen in einem austauschbaren Format vorliegen, das dann leicht in beide umgewandelt werden kann, denke ich. Ich möchte die beiden Parsers unabhängig machen (kein CST zu AST -Konvertierung), wenn dies überhaupt möglich ist. /> Schlussfolgerung < /h2>
Dies ist besonders schwierig, wenn ich mich frage, ob ich den falschen Weg genommen habe. Wenn es bessere Lösungen gibt, um meinen vorhandenen Code zu ändern, bin ich bereit zu hören.
Ich habe eine Reihe von Gruppenausdrücken wie diese, die alle zur gleichen Grammatik beitragen:
Code: Select all
first_and_operator = Group(Char('ab')('first') + Char('+-')('operator'))
full_expression = Group(first_and_operator + Char('cd')('second'))
< /code>
full_expression.parse_string('a + d', parse_all = True)
< /code>
Dies gibt beispielsweise die folgenden Ergebnisse aus: < /p>
ParseResults([
ParseResults([
# How to know that this is first_and_operator's results?
ParseResults(['a', '+'], {'first': 'a', 'operator': '+'}),
'd'
], {'second': 'd'})
], {})
"> ">"> ">"> ">"> ">"> ">"> ">">
Code: Select all
[
attr_value for attr in dir(results)
if not attr.startswith('__')
and not callable(attr_value := getattr(results, attr))
]
< /code>
[
('_all_names', set()), ('_modal', True), ('_name', 'first'),
('_null_values', (None, [], ())), ('_parent', None),
('_tokdict', {...: ...}), ('_toklist', ['a', '+']),
('first', 'a'), ('operator', '+')
]
Code: Select all
expression_list = Expand(full_expression) + (',' + Expand(full_expression))[1, ...]
< /code>
expression_list.parse_string('a + c, a - d, b + d', parse_all = True)
< /code>
ParseResults([
ParseResults(['a', '+'], {'first': 'a', 'operator': '+'}),
'c', ',',
ParseResults(['a', '-'], {'first': 'a', 'operator': '-'}),
'd', ',',
ParseResults(['b', '+'], {'first': 'b', 'operator': '+'}),
'd'
], {})
< /code>
Expand
Code: Select all
class TypedParseResults(ParseResults):
__slots__ = ('type',)
def __init__(self, *args, result_type: str, **kwargs):
self.type = result_type
super().__init__(*args, **kwargs)
@first_and_operator.add_parse_action
def make_results_typed(results: ParseResults):
return TypedParseResults(
self._toklist,
result_type = 'first_and_operator'
)
< /code>
This only ever raises an exception from somewhere deep down in core.py
Code: Select all
Traceback (most recent call last):
File ".../main.py", line 85, in
r = full_expression.parse_string('a + d', parse_all = True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
File ".../site-packages/pyparsing/core.py", line 895, in _parseNoCache
ret_tokens = ParseResults(
^^^^^^^^^^^^^
TypeError: TypedParseResults.__init__() missing 1 required keyword-only argument: 'result_type'
< /code>
This question, while sounds similar, does not answer mine since it is about debugging and not runtime checking. Also, none of the answers at this question works for me, for various reasons:
[*]The first is incompatible with Expand
Die zweite ist hässlich. Noch mehr mit zehn Ausdrücken. Darüber hinaus hat es das gleiche Problem mit dem dritten, was unten erklärt wird. Die ersten Ergebnisse müssen in einem austauschbaren Format vorliegen, das dann leicht in beide umgewandelt werden kann, denke ich. Ich möchte die beiden Parsers unabhängig machen (kein CST zu AST -Konvertierung), wenn dies überhaupt möglich ist. /> Schlussfolgerung < /h2>
Dies ist besonders schwierig, wenn ich mich frage, ob ich den falschen Weg genommen habe. Wenn es bessere Lösungen gibt, um meinen vorhandenen Code zu ändern, bin ich bereit zu hören.