热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

扩展iQuery使其支持多种编程语言(四)–兼编译器的语法错误处理简介

扩展iQuery使其支持多种编程语言(四)–兼编译器的语法错误处理简介iQuery是一个开源的自动化测试框架项目,有兴趣的朋友可以在这里下载:https:github.comvow

扩展iQuery使其支持多种编程语言(四) – 兼编译器的语法错误处理简介

iQuery是一个开源的自动化测试框架项目,有兴趣的朋友可以在这里下载:https://github.com/vowei/iQuery/downloads

源码位置:https://github.com/vowei/iQuery

相关的使用文档,请参看:

开源类库iQuery Android版使用说明
类jQuery selector的控件查询iQuery开源类库介绍
开源手机自动化测试框架iQuery入门教程(一)
开源手机自动化测试框架iQuery入门教程(二)
开源手机自动化测试框架iQuery入门教程(三)
在上一篇文章中,简单介绍了iQuery解释器的语义分析部分。

ANTLR已经自带了一些对词法和语法错误的处理功能,当一行语句出现语法错误时,ANTLR会尽量跳过出错的一行代码,恢复编译和解释功能,通过一个回调函数,我们可以向最终用户显示更细致的错误提示。

一般来说,好的错误提示应该有以下几个性质:
1.    需要指明错误的行号和列号,以便用户快速在源代码中定位出错的那一行代码,这个功能ANTLR会在调用我们的回调函数时传入这些信息。
2.    需要指明错误原因,例如“不匹配的字符”这样的错误信息显然没有“第1行,第25列: 没有关闭的语句,期望']',当前碰到的是''''!”这样的信息更明确。
3.    需要指明导致出错的文字,例如在编程中,针对使用一个未定义的变量的编程错误,当然需要在错误信息里指出这个未定义的变量名。
4.    最好给出修复错误的建议。

在ANTLR里,可以在代码里定义一个getErrorMessage函数,以便ANTLR回调。在Java版本中,getErrorMessage函数的声明形式如下(代码实现在:https://github.com/vowei/iQuery/blob/master/java/iquery/iquery-core/src/main/java/cc/iqa/iquery/iQuery.g):

   1:  public String getErrorMessage(RecognitionException e,
   2:                                      String[] tokenNames)

当ANTLR碰到词法或者语法错误时,会抛出一个基类为RecognitionException的异常,并传递给getErrorMessage函数,而第二个参数tokenNames就是导致词法/语法错误时的源码符号,getErrorMessage函数的返回值就是细化后的错误消息。

ANTLR针对不同的词/语法错误会生成不同的RecognitionException的继承类,在这些继承类里,分别定义了一些对细化错误消息有帮助的属性。下面代码是一个细化错误消息的例子,其中MismatchedTokenException表示一个未匹配的语法,在MismatchedTokenException的对象里,可以通过expecting字段获取期望的词法符号(原始代码位置是:https://github.com/vowei/iQuery/blob/master/java/iquery/iquery-core/src/main/java/cc/iqa/iquery/ErrorMessageHelper.java )。

   1:  if (e instanceof MismatchedTokenException) {
   2:              MismatchedTokenException mte = (MismatchedTokenException) e;
   3:              String tokenName = "";
   4:              if (mte.expecting == Token.EOF) {
   5:                  tokenName = "EOF";
   6:              } else if (tokenNames != null) {
   7:                  tokenName = tokenNames[mte.expecting];
   8:              } else {
   9:                  tokenName = new String(new char[] {(char)mte.expecting});
  10:              }
  11:   
  12:              if ( e.token != null ) {
  13:                  msg = String.format("%1$s: 没有关闭的语句,期望%2$s,当前碰到的是'%3$s'!",
  14:                          hdr, tokenName, recognizer.getTokenErrorDisplay(e.token));
  15:              } else {
  16:                  msg = String.format("%1$s: 没有关闭的语句,期望%2$s!",
  17:                          hdr, tokenName);                
  18:              }
  19:          }

Javascript版本里getErrorMessage函数的声明类似,处理方式也类似参考代码:https://github.com/vowei/iQuery/blob/master/iOS/lib/iQuery.g 和 https://github.com/vowei/iQuery/blob/master/iOS/lib/error.js ):

   1:  function onMismatchedTokenException(mte, tokenNames, recognizer) {
   2:      debug("onMismatchedTokenException");
   3:   
   4:      var tokenName = "";
   5:      if (mte.expecting == org.antlr.runtime.Token.EOF) {
   6:          tokenName = "EOF";
   7:      } else if (tokenNames != null) {
   8:          tokenName = tokenNames[mte.expecting];
   9:      } else {
  10:          debug("[onMismatchedTokenException] - mte.expecting: " + mte.expecting);
  11:          tokenName = mte.expecting;
  12:      }
  13:   
  14:      if (mte.token != null) {
  15:          return "没有关闭的语句,期望" + tokenName + ",当前碰到的是'" + recognizer.getTokenErrorDisplay(mte.token) + "'!";
  16:      } else if (tokenName != undefined) {
  17:          return "没有关闭的语句,期望" + tokenName + "!";
  18:      } else {
  19:          return "没有关闭的语句!";
  20:      }
  21:  }

由于词法分析器(Lexer)和语法分析器(Parser)是两个类,而且词法和语法分析过程都有可能发生错误,因此需要分别在两个分析器里定义getErrorMessage函数,添加的方式很简单,在antlr的语法定义.g文件里,添加在@lexer::members和@parser::members代码块里即可,例如下面是Javascript版本的声明方式:

   1:  @lexer::members {
   2:  _errors = [];
   3:  this.getErrorMessage = function(e, tokenNames)
   4:  {
   5:      var error = getErrorsHelper(e, null, tokenNames, this);
   6:   
   7:      if ( _errors != undefined && _errors != null ) {
   8:          _errors.push(error);   
   9:      }
  10:   
  11:      return error;
  12:  }
  13:  }
  14:   
  15:  @parser::members {
  16:  _errors = [];
  17:  this.getErrorMessage = function(e, tokenNames)
  18:  {
  19:      var error = getErrorsHelper(e, this.input, tokenNames, this);
  20:   
  21:      if ( _errors != undefined && _errors != null ) {
  22:          _errors.push(error);   
  23:      }
  24:   
  25:      return error;
  26:  }
  27:  }


推荐阅读
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 本文全面解析了JavaScript中的DOM操作,并提供了详细的实践指南。DOM节点(Node)通常代表一个标签、文本或HTML属性,每个节点都具有一个nodeType属性,用于标识其类型。文章深入探讨了DOM节点的创建、查询、修改和删除等操作,结合实际案例,帮助读者更好地理解和掌握DOM编程技术。 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 本文深入剖析了jQuery的架构设计与实现原理。jQuery的总体结构采用了一个自执行匿名函数的形式,该函数接收`window`和`undefined`作为参数,并在内部定义了一个局部的jQuery副本,以确保其内部变量和方法不会污染全局命名空间。这种设计不仅提高了代码的封装性和安全性,还使得jQuery能够更好地与其他JavaScript库兼容。通过详细分析这一架构,读者可以更好地理解jQuery的核心机制及其高效运行的原理。 ... [详细]
  • jQuery Flot 数据可视化插件:高效绘制图表的专业工具
    jQuery Flot 是一款高效的数据可视化插件,专为绘制各种图表而设计。该工具支持丰富的图表类型和自定义选项,适用于多种应用场景。用户可以通过其官方网站获取示例代码和下载资源,以便快速上手和使用。 ... [详细]
  • 近日,我在处理一个复杂的前端问题时遇到了极大困扰。具体来说,我之前开发了一个功能丰富的纯jQuery代码的前端GridView控件,实现了多种功能和视觉效果,并在多个项目中表现良好。然而,最近在尝试应用 `border-box` 布局模式时,却遇到了意想不到的兼容性和性能问题。这提醒我们在条件尚未完全成熟的情况下,应谨慎使用 `border-box` 布局模式,以免引入不必要的复杂性和潜在的bug。 ... [详细]
  • 帝国CMS中的信息归档功能详解及其重要性
    本文详细解析了帝国CMS中的信息归档功能,并探讨了其在内容管理中的重要性。通过归档功能,用户可以有效地管理和组织大量内容,提高网站的运行效率和用户体验。此外,文章还介绍了如何利用该功能进行数据备份和恢复,确保网站数据的安全性和完整性。 ... [详细]
  • 触发器的稳态数量分析及其应用价值
    本文对数据库中的SQL触发器进行了稳态数量的详细分析,探讨了其在实际应用中的重要价值。通过研究触发器在不同场景下的表现,揭示了其在数据完整性和业务逻辑自动化方面的关键作用。此外,还介绍了如何在Ubuntu 22.04环境下配置和使用触发器,以及在Tomcat和SQLite等平台上的具体实现方法。 ... [详细]
  • 为开发者提供了一系列实用的参考网站和资源链接,包括HTML速查手册( 和 ),帮助开发者快速查找和学习相关技术知识。此外,还涵盖了其他重要的开发工具和文档,为编程工作提供全面支持。 ... [详细]
  • 本文详细介绍了 jQuery 的入门知识与实战应用,首先讲解了如何引入 jQuery 库及入口函数的使用方法,为初学者提供了清晰的操作指南。此外,还深入探讨了 jQuery 在实际项目中的多种应用场景,包括 DOM 操作、事件处理和 AJAX 请求等,帮助读者全面掌握 jQuery 的核心功能与技巧。 ... [详细]
  • 本文详细解析了JSONP(JSON with Padding)的跨域机制及其工作原理。JSONP是一种通过动态创建``标签来实现跨域请求的技术,其核心在于利用了浏览器对``标签的宽松同源策略。文章不仅介绍了JSONP的产生背景,还深入探讨了其具体实现过程,包括如何构造请求、服务器端如何响应以及客户端如何处理返回的数据。此外,还分析了JSONP的优势和局限性,帮助读者全面理解这一技术在现代Web开发中的应用。 ... [详细]
  • 本文详细解析了如何使用 jQuery 实现一个在浏览器地址栏运行的射击游戏。通过源代码分析,展示了关键的 JavaScript 技术和实现方法,并提供了在线演示链接供读者参考。此外,还介绍了如何在 Visual Studio Code 中进行开发和调试,为开发者提供了实用的技巧和建议。 ... [详细]
author-avatar
心星Lover
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有