由于换行引起的bison程序报错ERROR: syntax error解决方法

最近在写flex & bison程序,但是bison总是解析不正确,第一次运行yyparse()是正确的,但enter后再输入,总会报错ERROR: syntax error。改写yyerror函数为

yyerror(char *s)
{
	extern int yylineno;	// defined and maintained in lex
	extern char *yytext;	// defined and maintained in lex
	int len=strlen(yytext);
	int i;
	char buf[512]={0};
	for (i=0;i

之后,可以输出报错字符串的ASCII码。发现是10号字符,也就是换行的\n解析出错导致。众所周知,Linux下换行就是\n,而windows下是\r\n。
由于换行引起的bison程序报错ERROR: syntax error解决方法_第1张图片
于是,在a.l文件加入:

[\r\n]  {printf("%d",yytext[0]);return EOL;}

让\r和\n都能输出EOL,同时把ASCII码送出来方便调试。

结果,经过测试,windosws控制台的换行就是\n,就没有\r什么事儿。只能另寻思路排错。

最后发现是BNC写错了。
原来的BNC写的是这样:

exp: 
  | block exp EOL
;

block: NOTE {printf("%c ",$1);}
  | AT NUMBER {printf("at%d ",$2);}
  | LEFT NUMBER COLON exp RIGHT
  | EXCLAM NOTE {printf("%c3/4 ",$2);}
  | BIGGER NOTE {printf("%c1/4 ",$2);}
  | NOTE MINUS {printf("%c%d ",$1,$2+1);}
;

解析exp的时候,每层exp展开都会在后面带一个EOL,展开多少层就多少个EOL,但实际输入串只有一个EOL是结束符,这样,bison在读完第一个EOL时,还在等待后面的EOL送进来,但实际上进来的已经是另一个串了,所以这时新串无法解析,就会报错。

改为以下写法后,问题解决。

exp: 
  | block exp
;

block: NOTE {printf("%c ",$1);}
  | AT NUMBER {printf("at%d ",$2);}
  | LEFT NUMBER COLON exp RIGHT
  | EXCLAM NOTE {printf("%c3/4 ",$2);}
  | BIGGER NOTE {printf("%c1/4 ",$2);}
  | NOTE MINUS {printf("%c%d ",$1,$2+1);}
  | EOL {printf("eol ",$1);}
;

你可能感兴趣的:(编译原理)