2012-04-14 7 views
1

Ich möchte die Fehlerkorrektur von bison2.4.1 behandeln.über die Fehlerwiederherstellung von bison2.4.1

beziehen ich mich auf ein Buch oreilly (lex & yacc) und einige Websites die Fehler-Token in meiner Regel zu setzen,

aber ich denke, es funktioniert nicht. Es hilft mir nicht bei der Fehlerbehebung!

mein Code ist wie folgt:

PDL: 
    DataDesc ComputationDesc {Build_front_proc($1,$2);} 
    ; 
DataDesc: 
    PartyDecl AccLvDesc  {$$ = echo_dataDesc($1, $2);} 
    ; 
// Party Description 
PartyDecl: 
    PARTY ':' ID ',' ID ENDL {if($3->is_func || $5->is_func) 
         yyerror("it is a reserved word!\n"); 
        $$ = echo_partyDecl($3->name,$5->name);} 
    |error ENDL   {printf("There is a error");} 
    ; 

Ich habe Worte "Partei: ID_A;" (Es soll nach „Party“ zwei ID-Name sein.)

und es ging direkt in yyerror() und zeigte Syntaxfehler ...

Ich habe keine Ahnung, warum es diesen Fehler nicht behandeln.

+0

mögliche Duplikate von [Fehlerbehandlung in YACC] (http://stackoverflow.com/questions/9796608/error-handling-in-yacc) – Kaz

Antwort

1

Fehlerregeln in yacc/bison verhindern keine Fehler - sie ERNEUERN sich von Fehlern. In diesem Fall erhalten Sie einen Fehler (und es ruft yyerror("syntax error")), und THEN sucht nach Fehlerregeln zum Wiederherstellen. Also in diesem Fall wird es in einem Zustand auf der Suche nach einem ',' zu verschieben, nach dem Verschieben PARTY, ':' und ID. In diesem Zustand kann eine ';' nicht analysiert werden, so dass ein Syntaxfehler ausgegeben wird. Nach dem Fehler wird es beginnen, Zustände zu knacken, bis es einen mit einer Fehlerproduktion findet - in diesem Fall 3 Zustände, um zu dem zu kommen, der dem Anfang eines PartyDecl entspricht. In diesem Zustand wird der Fehler verschoben und in einen Zustand versetzt, in dem ein ENDL erwartet wird. Es wird dann Eingabesymbole (die ; und alles danach) wegzuwerfen, bis sie eine ENDL findet, die sie verschieben, in einem Zustand versetzt, wo er die PartyDecl: error ENDL Regel reduzieren, printf("There is a error");

Aufruf Wenn es nie eine ENDL findet , wird es beendet, nachdem es zu einem EOF gekommen ist, nie wieder von dem Fehler erholt. Darüber hinaus wird es im Fehler-Recovery-Modus für 2 weitere Schichten nach dem ENDL bleiben - wenn es einen anderen Fehler vor dann bekommt, wird es yerror nicht aufrufen und wird stattdessen direkt zur Fehlerbeseitigung gehen.