我正在尝试创建自己的错误,但显然,调用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);
}
对于lex:
%{
#include <stdio.h>
#include "y.tab.h"
int linenum = 1;
%}
%%
[0-9] {
yylval = yytext[0] - '0';
return DIGIT;
}
[ \t\r]+ ;
\n ++linenum;
. return(yytext[0]);
解析器的输入:
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!
即使发现了第三行的错误,解析仍然会继续。我怎么才能修复它?
Upd:通过使用YYERROR解决了问题;
发布于 2015-11-19 04:35:14
如果您希望它在检测到一个错误后停止(为什么?),只需从相关的生产返回。
默认情况下,它将执行错误恢复。
发布于 2015-11-19 09:19:55
解析继续进行,因为您有一个包含error
的规则,这是一个错误恢复规则,它告诉解析器如何从错误中恢复并继续。如果在发生错误后不想继续,请删除错误恢复规则。则yyparse
将在出现错误后立即返回(非零)。
发布于 2015-11-19 03:39:50
在我看来,yyerror()
只是打印错误消息,但没有在解析器中设置错误状态。你可以稍微修改一下语法吗?
莱克斯:
0 {
yylval = 0;
return ZERO;
}
[1-9] {
yylval = yytext[0] - '0';
return DIGITNOZERO;
}
yacc:
number: DIGITNOZERO |
number DIGITNOZERO {$$ = $1*10+$2;} |
number ZERO {$$ = $1*10;}
https://stackoverflow.com/questions/33788501
复制相似问题