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的趁手工具。