Frage

Verzeihen Sie mir, ich bin ganz neu in das Parsen und lex / yacc, und ich bin wahrscheinlich in Art und Weise über den Kopf, aber dennoch:

Ich schreibe einen ziemlich grundlegenden Rechner mit PLY, aber es ist Eingabe könnte immer nicht eine Gleichung sein, und ich brauche, um zu bestimmen, ob es oder nicht, ist beim Parsen. Die Extreme des Eingangs wären etwas, das perfekt auf eine Gleichung ergibt, die es analysiert fein und berechnet, oder etwas, das nichts, wie eine Gleichung ist, die Analyse nicht und ist auch in Ordnung.

Der graue Bereich ist eine Eingabe, die Gleichung artige Teile aufweist, von denen der Parser greifen wird und funktioniert. Das ist nicht das, was ich will -. Ich muss in der Lage zu sagen, wenn Teile der Zeichenfolge nicht bekommen abgeholt und Token versehen, so kann ich einen Fehler zurück werfen, aber ich habe keine Ahnung, wie dies zu tun

Wer weiß, wie ich definieren kann, im Grunde ein ‚alles fangen, was übrig bleibt‘ Token? Oder gibt es einen besseren Weg, ich kann damit umgehen?

War es hilfreich?

Lösung

Es gibt eine eingebaute in error Token in yacc. Normalerweise würden Sie so etwas wie:

line: goodline | badline ;

badline : error '\n' /* Error-handling action, if needed */

goodline : equation '\n' ;

Jede Zeile, die nicht equation passt wird von badline behandelt werden.

Sie könnten yyerrok in der Fehleraktion Umgang verwenden möchten Fehlerverarbeitung ist für die nächste Zeile zurückgesetzt zu gewährleisten.

Andere Tipps

Definieren

ein Token (Ende der Eingabe), und machen Sie Ihre Lexer Ausgabe, die es am Ende des Eingangs.

Also, bevor, wenn Sie diese Token haben:

'1' 'PLUS' '1'

Sie werden jetzt haben:

'1' 'PLUS' '1' 'END_OF_INPUT'

Jetzt können Sie Ihre Top-Level-Regel in Ihrem Parser definieren. Anstelle von (zum Beispiel):

Equation ::= EXPRESSION

Sie müssen

Equation ::= EXPRESSION END_OF_INPUT

Natürlich musst du diese in PLY Syntax neu zu schreiben, aber das sollte man die meisten die Quere kommen.

ich in der Regel über einen separaten ‚Befehl Leser‘ verwenden, um einen vollständigen Befehl zu erhalten - wahrscheinlich eine Zeile in Ihrem Fall - in einen Host-Variablen-String, und dann für die lexikalische Analyse ordne die Zeichenfolge zu analysieren, einschließlich mir zu sagen, wenn es didn‘ t das Ende erreichen. Das ist schwer zu konfigurieren, aber einige Klassen von Fehlern machen die Berichterstattung zu erleichtern. Einer der Orte, die ich diese Technik routinemäßig verwendet haben, hat Multi-line-Befehle mit 3 Kommentar Konventionen, zwei Sätze von Strings in Anführungszeichen, und einige andere Gemeinheiten auf meine Zähne stumpf (kontextsensitive tokenization - igitt).

Ansonsten Don Rat mit der Yacc 'Fehler' Token ist gut.

Es sieht aus wie Sie bereits eine Lösung gefunden habe, aber ich werde einen anderen Vorschlag hinzufügen, falls Sie oder andere interessieren sich für einen alternativen Ansatz.

Sie sagen, Sie PLY verwenden, aber ist, dass, weil Sie der Compiler laufen in einer Python-Umgebung wollen? Wenn ja, dann kann man auch andere Werkzeuge betrachten. Für solche Jobs verwende ich oft ANTLR ( http://www.antlr.org ), die einen Python-Code-Generator hat . ANTLR hat viele Tricks für die Dinge zu tun, ein paar Eingang an der Lexer Ebene wie das Essen so der Parser sieht es nie (zB Kommentare), die Fähigkeit, eine Unterregel (zB Gleichung) innerhalb eines größeren Grammatik zu nennen (die einst die beendet werden soll Regel wurde ohne Verarbeitung mehr Eingangs abgestimmt ... klingt ein wenig wie das, was Sie tun mögen) und ein sehr schöner links~~POS=TRUNC Faktorisierungsalgorithmus.

ANTLRs Fähigkeit, mit der Verwendung des String kombiniert Parsen ( http://www.stringtemplate.org ) Motor macht eine schöne Kombination und beide unterstützen Python (unter vielen anderen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top