中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
关于lex与yacc生成parser的错误信息提示
作者:未知 时间:2005-09-13 23:29 出处:Blog.ChinaUnix.net 责编:chinaitpower
              摘要:关于lex与yacc生成parser的错误信息提示
以前在学校的时候弄过lex和yacc,当时抱着完成作业的心态,对于一些问题也没好好研究过。最近忙里偷闲,又玩了一把,对于如何产生parser错误信息算是有了一些了解。

用的是freebsd5.3自带的lex以及yacc,一般情况下生成的parser在遇到错误是只能报出一句简单的“syntax error”,对于错误的位置、期待的token等均没有提示。

事实上从lex可以获得行号的信息,只要在lex源文件的头上加上,
%option yylineno
即可。

而对于yacc输出的一些处理即可以实现简单的错误信息提示。方法是修改yyerror这个函数,下面是我修改后的一个例子,
void yyerror(char* s, int state){
     fprintf(stderr, "%s\n", s);    
     if(state != -1){
         fprintf(stderr, "line %d: ", yylineno);
         fprintf(stderr, "%s expected ", yyerrmtx[state]);
         fprintf(stderr, "before \"%s\"\n", yytext);
     }//if       
}
这里通过extern int yylineno得到当前的行号;另一方面,用一个自定义的yyerrmtx字符串数组存放各个状态值下的期待的token,同时从通过extern char* yytext从lex引入当前实际输入的token。这样就可以形成一个简单的错误提示,形如,
line 3: VARIABLE expected before LEFTBRACE

这里的关键是如何得到yyerrmtx这张表。当然可以手工输入,但是有个方法可自动生成。执行yacc的时候加上-d参数可以得到一个名为y.output的文件,其内容是对parser的各个状态、所作shift或reduce动作的一个文本说明。那么就可以写一段脚本(我是用perl写的)从这个文件中取出各个状态下期待的token的信息,从而得到yyerrmtx。

此外,关于出错位置,lex只能通过yylineno提供行号(据说有很大开销),而列号即行内的字符位置是不能直接提供的,网上有一些对应的方法,不过我没有试过。


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有