Kann Instaparse oder eine andere Clojure-Bibliothek verwendet werden, um eine einrückungsbasierte Sprache zu analysieren? Ich habe Beispiele gesehen, wie Instaparse verwendet wird, um Grammatiken ausgedrückt in EBNF/ABNF zu analysieren. Gibt es einen guten Weg, es zu verwenden, um eine einrückungsbewusste Sprache wie Python zu analysieren?
Antworten
Zu viele Anzeigen?Typischerweise benötigen Sie zur Einrückungsbasierten Analyse drei Dinge:
-
Erweitern Sie den Tokenizer, um ein Token aus den führenden Leerzeichen jeder Zeile zu erstellen
-
Verarbeiten Sie den Strom von Tokens, vergleichen Sie für jede Zeile die führenden Leerzeichen mit dem aktuellen Kontext und geben Sie an, ob es eine Erhöhung oder Verringerung gibt (so ändern Sie ein Token am Anfang jeder Zeile zu einem Token, wenn sich die Einrückungsebene ändert)
-
Schreiben Sie einen "normalen" Parser, der sich der Tokens bewusst ist, die eine Änderung der Einrückebene anzeigen.
Je nach Sprache müssen Sie möglicherweise einige Informationen aus dem dritten Teil an den zweiten Teil zurückgeben.
Ich kenne nichts über Instaparse (der einzige Grund, warum ich antworte, ist, dass Leute, die bei Fragen wie dieser fragen: "Was hast du bisher versucht?" mich wirklich ärgern) also müssten Sie prüfen, ob es eine Möglichkeit gibt, die zweite Phase zwischen den Tokenizer und den Parser zu platzieren (ich habe die Dokumentation durchsucht und es scheint nichts zu geben, das den zweiten Teil für Sie erledigt, aber Sie könnten das selbst schreiben). Aber es sollte die ersten und dritten Teile gut erledigen können.
Offenbar bist du nicht die erste Person, die dieses Problem mit Instaparse hat.
Bei den meisten Parser-Generatoren löst man dieses Problem mit einem benutzerdefinierten Lexer, der auf einer Variante des von @andrewcooke vorgeschlagenen Schemas basiert. Instaparse wurde jedoch so konzipiert, dass kein Lexer erforderlich ist, und bietet daher keine Schnittstelle, die einen verwendet.
Dieser Mangel wurde speziell in Issue 9 angesprochen, das von Issue 10 abgelöst wurde; im letzteren schlägt der Autor von Instaparse einen Workaround vor:
In der Zwischenzeit gibt es einen Workaround, den du möglicherweise nutzen könntest. Du könntest Tokens wie INDENT und DEDENT auf unbenutzte Zeichen abbilden und sie dann als Zeichenkette neu erstellen und anschließend instaparse damit ausführen. Ich glaube, ASCII-Zeichen 0-8 und 11-31 sind unbenutzt und könnten als Tokens dienen.
Das ist sicherlich eine Möglichkeit, obwohl es eine ästhetische Beurteilung ist, ob das "sehr hacky ist". Trotzdem könntest du einen solchen Hack schreiben in der Hoffnung, dass er entfernt werden kann, sobald Issue 10 gelöst ist. Vielleicht möchtest du dich an der Diskussion zu diesem Thema beteiligen.