0

Ich habe einen lexikalischen Analysator für eine C-ähnliche Sprache erstellt, die zum Beispiel bei dieser Eingabe das folgende Ergebnis liefert.Literalextraktionsrichtlinie für einen lexikalischen Analysator

Eingang

int i = 0 ; int j = i + 3; 

Ausgabe

int KEYWORD 
i  IDENTIFIER 
=  OPERATOR 
;  PUNCTUATION 
int KEYWORD 
j  IDENTIFIER 
=  OPERATOR 
i  IDENTIFIER 
+  OPERATOR 
3  INTEGER_CONSTANT 
;  PUNCTUATION 

Im obigen Beispiel Sie die gegebene Eingabe syntaktisch korrekt war bemerkt haben, aber wenn ich es so etwas geben, darunter fehlschlägt.

Eingang

int i = "1.2.2222.+\<++++ 

ich eine Klasse, deren einziger Zweck gemacht haben, ist die obige Zeichenfolge in kleine Teile zu brechen (ich nenne sie Literale, weiß nicht, ob es der richtige Begriff ist) das kann mit Regex abgeglichen oder mit DFA validiert werden.

Problem tritt bei den mehrdeutigen Situationen wie + auf, wobei + entweder ein Additionsoperator oder ein Teil eines bevorstehenden ganzzahligen Literals oder sogar Teil eines Inkrementoperators sein kann. Meine Lehreranforderung wird im nächsten Abschnitt erläutert.

Wenn einem + ein + vorangestellt wird, sollte es als Inkrementoperator verarbeitet werden. In einfachen Worten muss das Programm versuchen, nach jeder Möglichkeit zu suchen und das Beste zu wählen. Das bedeutet, wenn das Programm eine gültige Eingabe hat, dann eine ungültige Eingabe, die wiederum eine gültige Eingabe ist, sollte es nicht bei dieser ungültigen Eingabe stoppen, sondern stattdessen die korrekten Literale finden. Für mich bin ich dagegen. Mein Argument ist, wenn eine Programmzeichenkette bei einem bestimmten Index ungültig wird, sollte sie die Verarbeitung stoppen, weil wir kein Fehlerprüfsystem schreiben.

Ich habe versucht, alle Möglichkeiten mit einer komplexen (für mich) verschachtelte wenn andere Struktur und erhalten Teilerfolg. Kann einer von euch mir eine einfachere und elegantere Lösung vorschlagen? Ich habe auch darüber nachgedacht, dieses Problem in eine Zustandsmaschine zu strukturieren, aber ich bin mir nicht sicher, weil ich niemals eine Zustandsmaschine vor einem anderen als dem DFA implementiert habe, das nur Ja oder Nein für den Mustervergleich sagen kann.

Wie Sie sehen können, ist es eine Hausaufgabe, aber ich frage nicht nach Code.

+0

Der beste Weg IMHO, falsche lexikalische Elemente zu behandeln, besteht darin, sie an den Parser zurückzugeben. Du gibst bereits '+', ';', etc. zurück (und es ist am besten, sie als sich selbst zurückzugeben, anstatt sie auf einen konstanten Namen abzubilden): Wenn du also einen illegalen Charakter bekommst, gibst du diesen auch zurück. Dann kann der Parser damit umgehen, was auch immer sein Fehlerwiederherstellungsschema ist. Dies ist besser als ein getrenntes Fehlerwiederherstellungsschema für den lexikalischen Analysator, das in der Praxis nur darin bestehen kann, das Zeichen wegzuwerfen. Der Parser kann das auch, aber es kann auch Reduktionen versuchen, um zu sehen, ob sie helfen. – EJP

Antwort

0

Der übliche Ansatz zur lexikalischen Analyse ist die Verwendung des "maximal munch"-Algorithmus: Der Eingabestrom wird in Tokens unterteilt, indem wiederholt das längste Präfix genommen wird, das ein einzelnes Token sein könnte. Siehe this answer für einen Algorithmus.

Es ist gelegentlich notwendig, Ausnahmen von dieser Regel zu machen (in C++, beispielsweise <:: normalerweise gelext in <, ::), aber im Großen und Ganzen die maximale Munch Regel ist einfach und zu implementieren, was noch wichtiger ist, zu lesen .

Verwandte Themen