Yacc/Bison错误

Yacc/Bison错误,c,parsing,bison,yacc,C,Parsing,Bison,Yacc,我试图创建自己的错误,但显然,envoking yyerror()不足以告诉解析器存在错误。我举了一个小例子来更好地描述我的问题。 所以这里有一个解析器,它必须检查一个语句是否是两个数字,它们之间是否有逗号。数字不能以0开头 yacc的输入: %token DIGIT %{ #include <stdio.h> #include <stdlib.h> void yyerror(char *s); %} %% lis

我试图创建自己的错误,但显然,envoking yyerror()不足以告诉解析器存在错误。我举了一个小例子来更好地描述我的问题。 所以这里有一个解析器,它必须检查一个语句是否是两个数字,它们之间是否有逗号。数字不能以0开头

yacc的输入:

%token DIGIT            

%{      
#include <stdio.h> 
#include <stdlib.h>
void yyerror(char *s);    
%}

%%
    list:    |
        list stat ';' {printf("The statement is correct!\n\n");} |
        list error ';' {printf("The statement is incorrect!\n\n");}

    stat:   number ',' number

    number: DIGIT {if ($1==0) yyerror("number starts with 0");} | 
        number DIGIT {$$ = $1*10+$2;}
%%
extern int linenum;
void yyerror(char *s) {
    fprintf(stderr, " line %d: %s\n", linenum, s);
}
以下是输出:

The statement is correct!

 line 2: syntax error
The statement is incorrect!

 line 3: number starts with 0
The statement is correct!
即使在第3行发现错误,解析仍在继续。我怎样才能修好它

Upd:使用YYERROR解决问题

在我看来
yyerror()
只是打印错误消息,但没有在解析器中设置错误状态。你可以稍微修改一下语法吗

法律:

雅克:


如果您希望它在检测到一个错误后停止(为什么?),只需从相关生产返回即可


默认情况下,它将执行错误恢复。

解析将继续,因为您有一个包含
error
的规则,这是一个错误恢复规则,告诉解析器如何从错误中恢复并继续。如果不希望在发生错误后继续,请删除错误恢复规则。然后,
yyparse
将在出现错误后立即返回(非零)。

您的解决方案没有帮助,因为我仍然需要以某种方式将错误告知解析器。不过还是要谢谢你!顺便说一句,这个问题是通过像这样使用YYERROR来解决的:
number:DIGIT{if($1==0){yyrorr(“数字以0开头”);yyrorr;}}
这种事情当然应该在lexer中完成,但它不能解决问题。使用shift-reduce解析来实现
atoi()
是荒谬的。
34, 43;
32,fs;
03, 23;
The statement is correct!

 line 2: syntax error
The statement is incorrect!

 line 3: number starts with 0
The statement is correct!
0          {
             yylval = 0;
             return ZERO;
           }
[1-9]      {
             yylval = yytext[0] - '0';
             return DIGITNOZERO;
           }
number: DIGITNOZERO | 
        number DIGITNOZERO  {$$ = $1*10+$2;} | 
        number ZERO {$$ = $1*10;}