簡體   English   中英

Bison yyerror 忽略語法上的下一個標記

[英]Bison yyerror ignore next token on grammar

所以我的 Bison 程序有一個小問題,首先要知道我的程序有效並且完全是 function 你在這里看到的只是一個摘錄,足以幫助我。

基本上,解析器讀取“ vector(x,2) ”程序正在檢查變量“ x ”是否已經存在以及元素的數量“ 2 ”是否大於 1。當這種情況不發生時,我會拋出 yyerror。 問題是錯誤沒有忽略令牌的 rest。 讓我展示一個 vector(x,1) 的例子,你會看到它應該在減少時忽略該語句,但不是。

Starting parse
Entering state 0
Stack now 0
Reducing stack by rule 1 (line 58):
-> $$ = nterm PROGRAM (1.1: )
Entering state 1
...
....
Entering state 24
Stack now 0 1 5 12 15 18 24
Next token is token PARENTSIS_RIGHT (1.1: )
Shifting token PARENTSIS_RIGHT (1.1: )
Entering state 33
Stack now 0 1 5 12 15 18 24 33
Reducing stack by rule 10 (line 87):
   $1 = token RESEV_VAR (1.1: )
   $2 = token PARENTSIS_LEFT (1.1: )
   $3 = token STRING (1.1: )
   $4 = token COMMA (1.1: )
   $5 = nterm ELEMENTS (1.1: )
   $6 = token PARENTSIS_RIGHT (1.1: )
        Erro: blalalala.
-> $$ = nterm DEFINE_VECTOR (1.1: ) //here it should not run this one should skip it
Entering state 9
Stack now 0 1 9
Reducing stack by rule 6 (line 65):
   $1 = nterm DEFINE_VECTOR (1.1: )
        VECTOR
-> $$ = nterm DECLARACAO (1.1: )

正如你在最后看到的那樣,當我指定錯誤時,他正在運行減少到 DEFINE_VECTOR。

%start PROGRAM

%%

PROGRAM:
       | PROGRAM STATMENT
       | PROGRAM error STATMENT
;

STATMENT: QUIT  { fclose(yyin); printf("\nBYE\n"); exit('0');}
    | DEFINE_VAR    { printf("\tVAR\n"); }
    | DEFINE_VECTOR { printf("\tVAR\n"); }
;

...
DEFINE_VECTOR: RESEV_VAR PARENTSIS_LEFT STRING COMMA ELEMENT PARENTSIS_RIGHT { 
            if($5<=1){
                 yyerror("Vector to small");
            }else{
                 if(check($3)==0){
                    createVar($3, 2, $5);
                 }else{
                    yyerror("Variable alrady exists");
                 }
            }
}
;

ELEMENTS: ELMENTINT
    | ELMENTFLOAT{ $$ = $1;}
;

解決方案:

%start PROGRAM

%%

PROGRAM:
       | PROGRAM STATMENT
       | PROGRAM error STATMENT
       | PROGRAM error PARENTSIS_RIGHT STATMENT // added here
;

STATMENT: QUIT  { fclose(yyin); printf("\nBYE\n"); exit('0');}
    | DEFINE_VAR    { printf("\tVAR\n"); }
    | DEFINE_VECTOR { printf("\tVAR\n"); }
;

...
DEFINE_VECTOR: RESEV_VAR PARENTSIS_LEFT STRING COMMA ELEMENT PARENTSIS_RIGHT { 
            if($5<=1){
                 yyerror("Vector to small");
                 YYERROR;  //added here
            }else{
                 if(check($3)==0){
                    createVar($3, 2, $5);
                 }else{
                    yyerror("Variable alrady exists");
                    YYERROR;  added here
                 }
            }
}
;

ELEMENTS: ELMENTINT
    | ELMENTFLOAT{ $$ = $1;}
;

yyerror只是一個打印錯誤消息的 function。 野牛解析器在出現語法錯誤時調用它,但您也可以在其他地方調用它來打印錯誤。 它對解析沒有影響(它不會中斷或改變它——它不會“拋出”)

如果要影響解析,則需要使用YYERROR (觸發解析器錯誤的宏,然后解析器將嘗試從中恢復)。 但是,如果您有這樣的語義錯誤(不是語法錯誤),您可能不想這樣做,因為沒有可恢復的語法。 您可能想使用YYABORT立即中止解析(從 yyparse 返回)。 或者您可能只想繼續解析,以識別其他錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM