2015-11-19 13 views
5

Ich bin gerade dabei, einen C to Assembly Compiler zu schreiben, es soll nicht praktisch sein, aber ich würde es gerne für den Bildungswert machen. Ich frage mich, wenn ich nach Schlüsselwörtern teste, gibt es einen effizienteren Weg, anstatt nur das nächste Wort in der Datei einzulesen und dann durch eine Menge verschachtelter if-Anweisungen zu laufen, die nach den Schlüsselwörtern suchen. Gibt es einen besseren Weg?Wie soll ich beim Schreiben eines C-Compilers Schlüsselwörter analysieren?

+2

Sie können perfektes Hashing versuchen, aber es ist unwahrscheinlich, dass diese Phase Ihr Leistungsengpass ist. –

+2

Ich ändere das Tag [Parsing] in [Scannen]. Das Identifizieren einzelner Tokens erfolgt durch die erste Phase des Compilers, den Scanner, und nicht durch die zweite Phase, den Parser. –

+0

Und jetzt habe ich festgestellt, dass [Scannen] das falsche Tag ist. Habe es wieder geändert zu [lexer]. –

Antwort

8

Ihre Frage ist eigentlich ziemlich spezifisch. Sie fragen, wie Sie den lexikalischen Analysator, auch Scanner genannt, bauen und Schlüsselwörter effizient und bequem erkennen. Der Scanner ist die erste Phase eines typischen Compilers und konvertiert den Quellcode, der eine Folge von Zeichen darstellt, in eine Folge von Token, wobei ein Token eine Einheit wie eine Zahl, ein Operator oder ein Schlüsselwort ist.

Da Schlüsselwörter dem Muster für allgemeine Bezeichner entsprechen, besteht ein üblicher Trick darin, alle Schlüsselwörter in die Symboltabelle zusammen mit Informationen einzugeben, dass es sich um ein Schlüsselwort handelt. Wenn der Scanner dann einen Identifizierer findet, durchsucht er wie gewöhnlich die Symboltabelle, um zu sehen, ob dieser Identifizierer vorher gesehen wurde. Wenn dieser Bezeichner ein kevyord war, wird er zusammen mit der Information darüber, um welches Schlüsselwort es sich handelt, gefunden.

4

Machst du das für einen Teil einer Klasse? Wenn ja, sollte es Richtlinien für das Parsen und Lexieren geben. Wenn nicht, haben Sie eine Menge Arbeit!

Das Schreiben eines tatsächlichen Compilers ist viel komplizierter, als nur eine Reihe von if-Anweisungen durchzugehen, weil Sie die Umgebung im Auge behalten müssen. Sie müssen darüber nachdenken, wie Sie Klassen, Funktionen, Funktionsaufrufe, Klasseninstanziierungen, rekursive Funktionen zulassen ... die Liste wird fortgesetzt.

Schauen Sie sich auf Vorlesungen von UC Berkeley zum Thema, dh Parsing, lexing, Codegenerierung und die Werkzeuge, die Sie brauchen:

http://www-inst.eecs.berkeley.edu/~cs164/fa13/

Beachten Sie, dass dieser Kurs in bestimmten gebrauchten C++ um einen Python 2.5-Assembler-Compiler zu schreiben, aber die Konzepte in den Vorlesungen und Lesungen und einige der Werkzeuge sind nicht sprachbeschränkt.

3

Schlüsselwörter (anstelle von Token im Allgemeinen) ist eine geschlossene Menge, für die es praktisch ist, eine kollisionsfreie Hash-Funktion zu erzeugen. Da die Menge klein ist, ist es nicht einmal notwendig, eine minimale Hash-Funktion zu haben.

0

Sie können es mit einer Reihe von if - sonst if-Anweisungen und strcmp() tun. Das Schreiben von Anweisungen für alle Schlüsselwörter wird jedoch sehr schnell nervig. Sie sollten besser eine Hash-Tabelle verwenden - zu Beginn der Kompilierung legen Sie alle Schlüsselwörter in die Tabelle und dann suchen Sie nach Bedarf. Der Nachteil davon ist, dass wenn Sie C verwenden müssen, Sie auch Ihre eigene Hash-Tabelle schreiben müssen (oder eine aus einer Bibliothek verwenden). Wenn Sie jedoch C++ verwenden können, können Sie eine Map oder eine unordered_map aus der AWL verwenden. In jedem Fall, wenn Sie sich Sorgen um die Leistung machen, wie jemand anderes erwähnt, wird es kein Flaschenhals sein.