您可以在这里快速查找:


 
您的位置: 编程学习 > java教程 > 200601
文章分类

Java技术
2005: 03 04 05 06 07 08
09 10 11 12
2006: 01 02

Asp.net
2005: 07 08 09 10 11 12
2006: 01 02

VB编程
2006: 02

Asp编程
2005: 11 12
2006: 01 02

C++/VC
2005: 10 11 12
2006: 01 02

Delphi
2005: 12
2006: 01 02

其它

 本文章适合所有读者

Antlr--看Hibernate3如何解释HQL语言(下)

calvinxiu

Antlr--看Hibernate3如何解释HQL语言(上)  

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

   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
     
定义EQ: ´=´;  LT: ´<´;  GT: ´>´;PLUS: ´+´;等符号及IDENT  ( ´a´ .. ´z´ | ´_´ ) ( ´a´ .. ´z´ | ´0´ .. ´9´ | ´_´ | ´$´ )*

   2.HqlBaseParser
      先定义DELETE="delete"; FROM="from"; MIN="min"; 等Token


      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 
         hql与sql的delete语句基本上是一样的,没什么转换。

     4.SqlGeneratorBase
          
         根据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 ] ) )
          ;
so,antlr 算不得我这个level的programmer的趁手工具。