2017-03-26 5 views
0

Was bedeutet "Token-Fehler"? wie man Fehler ohne erkennt;Yacc - Was bedeutet "Fehler"?

+0

"Fehler" bedeutet genau das, was es sagt: Ein Parserfehler. Es fängt den Fehler ab, so dass Sie selbst damit umgehen können, möglicherweise Ihre eigene Wiederherstellung oder benutzerdefinierte Berichterstattung. –

Antwort

2

Nachdem das Pseudo-Terminal error gefunden wurde, analysiert der Bison-Parser auf normale Weise weiter, außer dass Token verworfen werden, die "nicht behandelt werden können".

Wenn es auf ein Token trifft, das unmittelbar auf das Token error folgt, kann es dieses Token verschieben, was bedeutet, dass es aufhört, Tokens zu verwerfen.

Dies ist jedoch nicht die einzige Möglichkeit, wie der Parser mit einem Token umgehen kann. Es könnte auch damit umgehen, indem es eine Reduktion macht.

Hier wird das Wort "gehandhabt" etwas falsch interpretiert, da eine Reduktionsaktion das Lookahead-Token nicht wirklich akzeptiert. Dennoch reicht es aus, die Fehlererzeugung zu reduzieren.

In einem solchen Fall muss vorsichtig vorgegangen werden nicht Anruf yyerrok. Wenn die Fehlerbehandlung mit yyerrok abgebrochen wird und das Lookahead-Token nicht verschoben werden kann, wird der Fehlerhandler erneut eingegeben und es ist möglich, in eine Endlosschleife zu geraten.

Zum Beispiel

commands: %empty | commands command 

command : exp ';' { printf("Value is %d\n", $1); } 
     | error ';' { printf("Bad expression\n"); yyerrok; } 
     | error  { printf("Missing semicolon\n"); } 

Die erste command Produktion bewirkt, daß das Ergebnis eines korrekten Ausdruck ausgedruckt werden. Die zweite Produktion beschäftigt sich mit Syntaxfehlern, bei denen noch ein Semikolon vorhanden ist. Es kann die Fehlerbehandlung abbrechen, weil die ; bereits verschoben wurde, so dass es in Ordnung ist, die Fehlerbehandlung neu zu starten.

Die dritte Produktion beschäftigt sich mit einem fehlenden Semikolon. Hier können wir yyerrok nicht aufrufen, da es möglich ist, dass das Lookahead-Token ein unzulässiges Token ist, z. B. !. Wenn wir yyerrok aufrufen würden, würde der Fehlerstatus gelöscht, und die Fehlerbehandlung würde sofort mit dem gleichen Ausrufezeichen wie das Lookahead-Token erneut eingeleitet werden, was eine Endlosschleife verursachen würde. Aber ohne yyerrok, der Parser befindet sich immer noch im Fehlerbehandlungsmodus und das störende Token wird verworfen.

Hinweis: Das obige sollte helfen, die Frage zu beantworten, was wäre der Effekt einer error Produktion mit nichts nach dem error Token. Es war nicht beabsichtigt, eine Frage zu beantworten, die nicht gestellt wurde, wie "Wie mache ich das? X?" (Für verschiedene Werte von X). Das mitgelieferte Beispiel ist ein bisschen künstlich. Das Original verwendete ein Zeilenumbruchzeichen als Ausdrucksterminator, und es war nicht notwendig, die zweite Fehlerbehandlungsproduktion einzuschließen, da es effektiv unmöglich ist, einen abschließenden Zeilenumbruch außer bei EOF wegzulassen.

+0

Aber es kann global Dekorateur nicht umgehen: 'Programm \t \t \t: \t ExtDefList \t \t \t \t \t {} \t \t \t \t; ExtDefList \t \t: \t EXTDEF ExtDefList \t \t \t {} \t \t \t \t | \t/* * leer/\t \t \t \t \t} { \t \t \t \t; EXTDEF \t \t \t: \t Anforderung ExtDecList SEMI \t {} \t \t \t \t ... \t \t \t \t | \t Fehler SEMI \t \t \t \t \t {printf ("schlechter Ausdruck% s \ n", yytext); yyerrok;} \t \t \t \t | \t Fehler \t \t \t \t \t \t {printf ("missing halb \ n");} \t \t \t \t; ' – Rachel

+0

@rachel: dieser Kommentar ist im Wesentlichen unmöglich zu lesen, was in der Regel bedeutet, dass Sie eine neue Frage zu stellen mit sollten mehr Details. (Wie genau war dein Ziel genau und wie hat das, was du versucht hast, deine Anforderungen nicht erfüllt.) Aber es ist sicherlich nicht so einfach, fehlende Tokens zu erkennen, wenn kein Synchronisationstoken vorhanden ist. – rici

1

Eine häufige Quelle der Verwirrung - die error Token ist für die Fehler Erholung, Fehler nicht Erkennung. Syntaxfehler werden vom Parser automatisch erkannt und gemeldet. Sie können andere Fehler in den Aktionen erkennen und Bison darüber informieren, indem Sie das Makro YYERROR verwenden.

Konzeptionell ersetzt das Token error eine Sequenz von null oder mehr Eingabe-Token, um einen ungültigen Eingabestream in einen gültigen zu konvertieren.Wenn ein Fehler auftritt, geht der Bison-generierte Parser in den Fehlerwiederherstellungsmodus und verwirft Token und Zustände, bis er an einen Punkt gelangt, an dem der error Pseudo-Token verschoben werden kann. Es verschiebt dann das Fehler-Token und versucht von dort fortzufahren.