`
江南白衣
  • 浏览: 549947 次
  • 来自: 广州
社区版块
存档分类
最新评论

Antlr--看Hibernate3如何解释HQL语言

阅读更多

    作者:江南白衣 

     ANTLR(ANother Tool for Language Recognition)风头正盛,经常可以看到用它做语法解释器的项目,比如Hibernate就在3.0换上它来解释HQL,加强了HQL的语法。
     因为Antlr是EBNF-AST语法解释系的代表,而自己总是心思思想搞一下DSL(领域语言),所以从Hibernate来学习一下Antlr的应用。

     Hibernate HQL translator作者Joshua Davis的两个Blog
     Hibernate3 Query Translator Design - Part One : The Basics
     Hibernate3 Query Translator Design - Part Two : Parsing HQL

     Antlr最好的介绍文章是那篇,在《程序员》2004年3月有中文的版本。  不过,那个计算器的例子太简单了。深刻一点的有<ashley j.s="" very="" thorough="" tutorial=""></ashley>
     另外,SlickEdit 支持Antlr的语法,是一定要用的编辑器,在 ttdown.com上有破解。


  一,Antlr引擎的工作过程大概是这样的:
  1.Lexer类--词法分析器。 
        定义语言中的各种Token(单词),如 From 、Where、=、<>.......
        Lexer负责把读入的普通文本流识别成Token串。

  2.Parser类--语法分析器。
        使用BNF语法,递归定义句子的Pattern,如whereStatement、FromStatement、SelectStatement。
     Parser负责把读入的Token串匹配成句子,翻译出AST(抽象语法树)。
     有些简单的应用,也可以在本层现炒现卖,完成所有动作,属于Single Pass Builder。

  3.TreeParser类--抽象语法树遍历器。
        根据Parser类分析出来的AST(抽象语法树)进行动作。
           
        用Parser把AST抽取出来,再用TreeParser进行动作的Double Pass Builder模式,解耦了Parser和Generation,再配合Template 生成代码,是Antlr推荐的最佳模式。

  二,开发人员的实际步骤

  1.按照Antlr的简单语法定义前面讲的3个类,文件的后缀名为g。

  2.使用java antlr.Tool xxx.g 命令,把grammar文件编译成java文件。

  3.编写应用程序,如:


     看过Antlr对HQL的解释,觉得EBNF系的方法要解释Java这样的编程语言还好些,如果要解释类自然语言的DSL就比较痛苦,所以情绪不是很高涨,挑一条最容易的"Delete from goods where ....." 匆匆走过场

   Joel的一句话对我的影响比较大:"如果为了证明一个微不足道的问题需要花三个小时写下几黑板的证明步骤,那么这种机制不可能用来证明任何有趣的东西" 。对于我这个层次的程序员,antlr在我手中造不出有趣的DSL来。

import antlr.*
import antlr.collections.
*
public class Main 

  
public static void main(String[] args) throws Exception 
  {
     ExprLexer lexer 
= new ExprLexer(System.in); 
     ExprParser parser 
= new ExprParser(lexer);
     parser.expr(); AST ast 
= parser.getAST();
     ExprTreeParser treeParser 
= new ExprTreeParser();
     
int x = treeParser.expr(ast); 
  } 


    三,Hibernate对Antlr的应用

   Hibernate的HQL Grammar文件一共有三个,在/grammar目录下:
   1.hql.g   定义Token类和Parser类,将HQL解释成hql的抽象语法树(AST)
   2.hql-sql.g  定义Tree Walker ,将HQL AST转化为SQL AST,将生成模块与Hibernate解耦。
   3.sql-gen.g 定义Tree Walker,从SQL AST生成sql

   下面看 DELETE FROM GOODS的翻译过程

   1.HqlBaseLexer extends Lexer
     
定义EQ: '=';  LT: '<';  GT: '>';PLUS: '+';等符号
      及IDENT: ( 'a' .. 'z' | '_' ) ( 'a' .. 'z' | '0' .. '9' | '_' | '$' )*

   2.HqlBaseParser extends Parser
      先定义DELETE="delete"; FROM="from"; MIN="min"; 等字符串
      再定义:

statement
          : ( updateStatement 
| deleteStatement | selectStatement )
          ; 三种Statement之一

      deleteStatement
         : DELETE
^
           (optionalFromTokenFromClause)
           (whereClause)
?
         ;DELETE为叶子,(whereClause)可选

      optionalFromTokenFromClause
!
        : (FROM
!)? f:path {
           AST #range 
= #([RANGE, "RANGE"], #f);
           #optionalFromTokenFromClause 
= #([FROM, "FROM"], #range);
          }
         ;不是很好懂对吧,我也这样觉得,whereClause就更加不要看了。 

     

     3. HqlSqlBaseWalker extends TreeParser  
         hql与sql的delete语句基本上是一样的,没什么转换。

     4.SqlGeneratorBase extends TreeParser
          
         根据SQL AST, 生成SQL语句         

 private StringBuffer buf = new StringBuffer();
          
protected void out(String s) 
          {
                buf.append(s);
          }

          statement
          : selectStatement 
| updateStatement | deleteStatement
          ; 
         deleteStatement
         : #(DELETE { 
out("delete"); }
               from
              (whereClause)
?
             )
         ;输出
"delete"          from
          : #(f:FROM { 
out(" from "); }
           (fromTable)
* )
                    fromTable
         : #( a:FROM_FRAGMENT  { 
out(a); } (tableJoin [ a ])* { fromFragmentSeparator(a); } )
         
| #( b:JOIN_FRAGMENT  { out(b); } (tableJoin [ b ])* { fromFragmentSeparator(b); } )
         ;         tableJoin [ AST parent ]
          : #( c:JOIN_FRAGMENT { 
out(" "); out(c); } (tableJoin [ c ] )* )
          
| #( d:FROM_FRAGMENT { nestedFromFragment(d,parent); } (tableJoin [ d ] )* )
         ;

         .晕了吧 
~~~~~
         whereClause
          : #(WHERE { 
out(" where "); } ( conditionList | booleanExpr[ false ] ) )
          ;




分享到:
评论
1 楼 rongxh7 2009-08-25  
发觉Antlr比大学里学的编译原理还要难,呵呵

相关推荐

    antlr-2.7.5H3.jar和antlr-2.7.6rc1.jar

    在实际开发中,ANTLR不仅用于JPA和Hibernate,还广泛应用于构建各种领域特定语言(DSLs)、编译器、解释器以及命令行工具。其强大的自定义能力使得开发者可以定义自己的语法,并生成对应的解析器来处理这种语法。 ...

    antlr-2.7.6.jar

    项目中没有添加antlr-2.7.6.jar,hibernate不会执行hql语句

    antlr-2.7.6rc1.jar

    解决weblogic抛出的ClassNotFoundException: org.hibernate.hql.ast.HqlToken异常

    antlr-2.7.7

    ANTLR在这里可能是用于解析Hibernate的配置文件或HQL(Hibernate Query Language)查询。HQL是Hibernate提供的一个类似于SQL的语言,但它是面向对象的,可以直接操作持久化类。 在压缩包文件名称列表中,我们看到有...

    antlr.jar-2.7.6

    当Hibernate接收到一个HQL(Hibernate查询语言)或JPQL(Java Persistence Query Language)查询时,ANTLR会解析这些高级查询语言并生成相应的SQL,从而与底层数据库进行交互。这使得开发者无需直接编写SQL,而是...

    weblogic12 下 org.hibernate.hql.ast.HqlToken

    ### WebLogic 12下org.hibernate.hql.ast.HqlToken冲突解决方案 在使用WebLogic 12部署应用程序时,可能会遇到与`org.hibernate.hql.ast.HqlToken`相关的异常问题。这种异常通常与Hibernate版本之间的不兼容性有关...

    Hibernate基础配置导入的最小JAR包

    hibernate3.jar-核心类库 antlr-2.7.6.jar-代码扫描器,用来翻译HQL语句 commons-collections-3.1.jar-功能比java.util.*强大 dom4j-1.6.1.jar-类似于jdom,用来读写XML文件的 javassist-3.4.GA.jar- Javassist 字节...

    antlr-2.7.7.zip

    在使用Hibernate时所必须的jar包,如果没有添加那么相关的hibernate映射不会执行hql语句并且会报NoClassDefFoundError:antlr/ANTLRException错误。

    antlr-3.1.1

    ANTLR在这里可能用于解析Hibernate的配置文件,或者处理HQL(Hibernate Query Language),这是Hibernate特有的SQL扩展,用于更加灵活地查询数据库。 最后,“c#版本”说明ANTLR不仅限于Java平台,也提供了C#的实现...

    hibernate核心包

    antlr-2.7.6.jar 一个语言转换工具(Hibernate利用它实现 HQL 到 SQL 的转换模板相关操作需要包) c3p0-0.9.1.jar c3p0数据源实现的jar文件 cglib.jar CGLIB 字节码解释器 commons-collections-3.1.jar collections ...

    hibernate3-jar

    在Hibernate中,ANTLR用于解析HQL(Hibernate查询语言)和SQL语句,提供了类似于SQL的面向对象查询能力。 接着,`cglib-2.1.3.jar`是Code Generation Library的简称,它是对Java字节码操作的库,主要用于动态创建...

    hibernate所包含的所有jar包

    6. **antlr-*.jar**:ANTLR是一个强大的解析器生成器,Hibernate使用其处理HQL(Hibernate Query Language)。 7. **dom4j-*.jar**:提供XML处理,Hibernate用其解析和生成HQL的XML配置文件。 8. **slf4j-api.jar...

    Hibernate的Antlr在Weblogic中产生Jar冲突的解决办法

    Hibernate框架使用Antlr库来解析HQL(Hibernate Query Language)和Criteria查询。Weblogic服务器本身也依赖于Antlr库来进行一些内部处理工作。不同版本的Antlr可能具有不同的语法解析规则,这就会导致两个版本之间...

    hibernate3需要的jar包

    1. **hibernate3.jar**:这是Hibernate的核心库,包含了所有基本的ORM功能,如实体管理、会话管理、查询语言(HQL)解析等。开发者主要通过这个jar包与Hibernate进行交互。 2. **javassist-3.9.0.GA.jar**:Java...

    hibernate-lib。rar

    3. Hibernate关键组件: - Session:是Hibernate的主要工作单元,负责与数据库进行交互,提供了持久化对象的创建、查询、更新和删除等操作。 - SessionFactory:是Hibernate的配置中心,负责创建Session实例,一次...

    java开发支持,包含c3p0-0.9.1、hibernate3.jar、

    在Hibernate中,ANTLR可能用于解析HQL(Hibernate查询语言)。 7. **sqljdbc4.jar**:这是微软提供的JDBC驱动,用于与SQL Server数据库进行交互。它支持Java 6及以上版本,提供了连接、查询、更新和管理SQL Server...

    hibernate-jpa学习

    6. **查询语言HQL**:Hibernate Query Language(HQL)是Hibernate提供的一种面向对象的查询语言,类似于SQL但更接近于Java。例如,`antlr-2.7.7.jar`是HQL解析器的一部分,用于处理HQL查询。 7. **元数据索引**:`...

    hibernate-release-4.2.4核心jar包

    首先,`hibernate-core-4.2.4.Final.jar`是Hibernate的核心组件,它包含了ORM的主要功能,如实体管理、持久化操作、查询语言(HQL)解析等。这个jar包是使用Hibernate进行开发时必不可少的部分,它定义了Hibernate API...

Global site tag (gtag.js) - Google Analytics