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

本文介绍了一个使用flex和bison开发程序时遇到的问题及解决方案。主要问题是bison在解析输入时出现错误,特别是在处理换行符时。通过调整BNC文法,解决了因多余EOL符号导致的解析错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在写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<len;++i)
	{
		sprintf(buf,"%s%d ",buf,yytext[i]);
	}
	fprintf(stderr, "ERROR: %s at symbol '%s' on line %d\n", s, buf, yylineno);
	yyparse();
}

之后,可以输出报错字符串的ASCII码。发现是10号字符,也就是换行的\n解析出错导致。众所周知,Linux下换行就是\n,而windows下是\r\n。
在这里插入图片描述
于是,在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);}
;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值