我尝试提取一行的内容,并在该行中的输入被从野牛中拒绝时打印出来。 我尝试重现这些建议:http://archive.oreilly.com/pub/a/linux/excerpts/9780596155971/error-reporting-recovery.html但是当输入被拒绝时,打印下一行而不是被拒绝的行,同时正确打印行号。
挠曲:
%{
#include <stdio.h>
#include "parser.tab.h"
int line_number = 0;
char linebuf[500];
%}
...
%%
\n.* { ++line_number; strncpy(linebuf, yytext+1, sizeof(linebuf)); /* save the next line */
yyless(1); /* give back all but the \n to rescan */
}
%%
野牛:
%{
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "parser.tab.h"
extern int yylex(void);
extern int line_number;
extern char line_contents[500];
void yyerror(char const *s);
%}
...
%%
int main(){
if( yyparse() == 0)
printf("Accepted\n");
else
printf("Syntax error in line %d: %s\n" line_number, linebuf);
...
在从野牛被拒绝的输入上,上面的方法打印了包含语法错误的那一行的下一行。
input:
result = function //(semicolon expected)
else
输出:
Syntax error in line 1: else
我认为词汇规则\n.*
或yytext+1
将输出驱动到下一行但是哪个词法规则是正确的?
答案 0 :(得分:1)
这是因为bison使用1令牌前瞻来解析。因此,在扫描程序读取并返回ELSE令牌之前,不会注意到(或诊断出)丢失的分号。此时,前面的规则(期望分号或某些东西表达更长的表达式)无法匹配(在该状态下对令牌ELSE没有移位或减少操作)。
一旦发现错误,解析器会调用yyerror来打印消息(以及最近读取的行,即带有ELSE令牌的行)。