我发现我可以在语法规则中使用'error'作为错误恢复的机制。因此,如果出现错误,解析器必须丢弃当前行并从下一行继续解析。来自野牛手册的一个例子可能是这样的:
stmts:
exp
|stmts exp
| error '\n'
但我不能用它;因为我必须在我的scannar中使flex忽略'\ n',所以表达式不限于在一行中表示。我怎样才能使解析器 - 遇到错误时 - 继续解析到下一行,假设没有特殊字符(即分号)来表示表达式的结尾并且没有'换行符'令牌?
谢谢..
答案 0 :(得分:6)
由于您已经删除了示例中使用的标记,因此您必须使用特技来获得相同的效果。
我认为你可以使用它:
stmts:
exp
| stmts exp
| error { eat_to_newline(); }
其中eat_to_newline()
是扫描仪(源文件)中的一个函数,它安排丢弃任何已保存的令牌并读取下一个换行符。
extern void eat_to_newline(void);
void eat_to_newline(void)
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
它可能需要比这更复杂,但并不比那复杂得多。在调用yyerrok;
后,您可能需要使用yyclearin;
(并且,正如评论提醒我的那样,eat_to_newline()
。)