2012-04-15 6 views
4

Fast alle Compiler wird eine Zeilennummer zusammen mit Fehlermeldung zurückgeben. Ich frage mich in der Compiler-Design-Perspektive, wie Compiler Line Number-Nachricht in Bezug auf folgende Phasen zu behandeln? Vielen Dank.Wie behandelt Compiler Zeilennummer in Laufzeitfehlermeldung

  • Scanner
  • Parser
  • AST Datenstruktur
  • Codegenerierung

In weiteren:

  • Laufzeitumgebung
  • Maschinen Dolmetscher
+0

Runtime und Machine Interpreter sind nicht die Teile eines Compilers. –

+0

Danke. Ich habe die Frage ein wenig bearbeitet. –

Antwort

1

Ich habe einen ziemlich einfachen Compiler für meine Klassenzuordnung implementiert. Es war eine Untergruppe von Pascal mit einigen anderen Einschränkungen.

Compiler ist ein Werkzeug, das eine Sprache in eine andere übersetzt. Dies geschieht durch eine Fehlerprüfung und generiert dann (wenn möglich) einen Ausgabecode. Üblicherweise wird die Pipeline eines Compilers entspricht in etwa:

Code eingeben -> Lexer (Scanner) -> Syntax Analyzer -> Semantic Analyzer -> Code-Generator -> Ausgabe Code *

Da meine Sprache einfach war, konnte ich eine Reihe von Annahmen machen, z Eine Anweisung wird nur in einer Zeile sein. Mein Lexer verwendete reguläre Ausdrücke, um nach Zeichen zu suchen, die z. "Zeichen, die keine Zahlen, Buchstaben sind" (",", "". "Usw.") Ich lese eine Datei in eine Liste von Zeichenfolgen, wobei jede Zeichenfolge eine nächste Zeile ist. Wenn ich also eine Zeile scanne und einen Fehler finde, gehe ich zurück der Index + 1, die die Nummer der Zeile ist.

mit der Syntax Analyzer (Parser), die zB überprüft „Wenn ein Variablenname mit einem Buchstaben beginnt“ der Algorithmus ähnlich war.

Wenn ich den Parser erweitert Ich verknüpfte ein Token mit der Zeile im Code, um es im Fehlerfall zurückzugeben.

Ich weiß nicht, wie moderne Compiler dieses Problem lösen, aber ich kann vermuten, dass das auch eine Art von Assoziation von AST und Zeilennummer ist mit dem Gedanken, dass ein AST in ein paar Zeilen sein könnte (na ja , das ist sprachabhängig).

Mit Code-Generierung Compiler weiß, dass der Code korrekt ist (nach ihrem Wissen) und der Rückkehr Fehler würde nicht über den Code sein, sondern dass es ein Problem mit dem Compiler oder dem Prozess (Bug, nicht genug Speicher, kann nicht zum Standort schreiben usw.).

Laufzeitumgebungen und Maschineninterpreter könnten auch einen Compiler, z.B. JIT, aber die Fehlermeldung Rückkehr bedeutet in der Regel Fehler im Compiler oder Laufzeit, nicht der Code.

* Beachten Sie, dass dies ein sehr einfaches Modell von 3 Durchgängen ist. Modern compilers have a lot more.

EDIT: Ich habe festgestellt, dass AST ein Feld, Zeilennummer und Dateien für einen Fehler (für jeden Knoten) hat.

0

Die meisten Lexer- und Parsergeneratoren generieren Code mit Fehlerberichtsmethoden, die aufgerufen werden, wenn ein passender Fehler auftritt. Sie können diese Methode überschreiben und tun, was Sie wollen.

Wie bereits erwähnt, ist es üblich, in der Lexer-Spezifikation eine Zeile und eine Charakternummer mit einem Bezeichner oder einem String/char/integer/boolean literal zu verknüpfen. Normalerweise stellt ein Lexer dafür eine yyline() Methode zur Verfügung. Anstatt dass der Lexer einen rohen Token-Wert (z. B. einen String) zurückgibt, muss er ein Objekt zurückgeben, das den Zeichenfolgenwert, das Zeichen und die Zeilennummer enthält. Zum Beispiel, werfen Sie einen Blick auf this lexer spec.

private Symbol symbol(int type) { 
    return new Symbol(type, yyline, yycolumn); 
} 

Der Parser wird das Symbol während des Parse empfangen und die Ortsinformationen übernehmen sollte, zusammen mit dem Token-Wert, und sie in den AST-Knoten anschließen. Diese Information sollte schließlich ihren Weg in die Symboltabelle finden. Bei der Typanalyse werden an jeden Blattknoten Standortinformationen gebunden. Das sollte alles sein, was Sie für eine ziemlich gute Fehlerdiagnose benötigen.