ANTLR解析(一)

ANTLR是一个开源的词法分析器,包含了词法分析和语法分析,可以按照自定义规则去解析文件,得到一个树,下面主要结束使用ANTLR解析简单的HQL(此HQL只包含简单的select和from语句),大概介绍了解析的方法,提供一种大概步骤,有关hibernate对于字符串HQL的详细解析可以参照hibernate的hql.g文件

首先我们需要借助一个ANTLR的图形化编辑工具antlrworks-1.5.jar,这个jar可以使我们图形化编辑.g文件(本人理解.g文件为文法),可以实时验证语法、生成java语法解析类和此法解析类

下面是.g文法文件的主要代码:

grammar CustomHQL;

options{
	output = AST;
	ASTLabelType = CommonTree;
}

tokens{
	SELECT = 'select';
	DISTINCT='distinct';
	FROM = 'from';
	AS = 'as';
	HQL;
	FROMCLAUSE;
	FROMRANGE;
	TABLENAME;
	TABLEALIAS;
	TABLEFIELD;
	SELECTCLAUSE;
	SELECTRANGE;
	CHILDTABLENAME;
	SORTWAY;
}

@header {package mtpackage;}
@lexer::header{package mypackage;}


hql	:	selectClause* fromClause* ->^(HQL selectClause* fromClause*) 
	;
selectClause	:	SELECT DISTINCT? selectRange? (',' selectRange)* -> ^(SELECTCLAUSE SELECT DISTINCT? selectRange*)
	;	
selectRange	:	(tableAlias '.' (childTableName '.')?)? tableField  -> ^(SELECTRANGE tableAlias? childTableName? tableField)
	;
fromClause 	:	FROM fromRange? (',' fromRange)* -> ^(FROMCLAUSE FROM fromRange*)
	;
fromRange 	:	tableName (AS? tableAlias)? -> ^(FROMRANGE tableName (AS? tableAlias)?)
	;		
tableName	:	ID -> ^(TABLENAME ID)
	;	
tableAlias	:	ID -> ^(TABLEALIAS ID)
	;
tableField	:	ID -> ^(TABLEFIELD ID)
	;	
childTableName	:	ID -> ^(CHILDTABLENAME ID)
	;	
sort	:	SORT ->^(SORTWAY SORT)
	;

SORT	:	('asc' | 'desc')+;
ID : ('a'..'z' |'A'..'Z')+ ;
INT : '0'..'9' + ;
NEWLINE:'\r' ? '\n' ;
WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;

开头的单词grammar关键字,用来定义文法的名字

option定义一些操作:输出为一个AST树,类型为CommonTree

tokens是我们自定义的一些标记,这里主要是一些关键字和占位符然后下面的是一个文法结构:这里hql节点后面只能有selectClause或fromClause 语句后面的箭头->是重写树规则,前面的文法结构式不会出现在树里面的,树的结构需要重新定义,关于树结构有两种写法,一种是直接在文法结构里面嵌套写,另外一种是在语句后面重写规则,这里采用第二种,这样有利于维护以上文法写好之后可以进行语法验证,看有没有错误:Gramat->Check Gramar 还可以在antlrworks-1.5.jar工作界面的interpreter界面写一些语句进行验证,如果执行可以生成树接表示文件正确,然后直接生成语法解析文件、文法解析文件和一个标记文件,生成这三个文件之后就可以在java里面使用了

使用主要代码如下

String hql = "select u.name, b.name.child from ConfigTable   as  eedc, InventTable as i, BatchTable";
CharStream charStream = new ANTLRStringStream(hql);
CustomHQL Lexer lexer = new CustomHQLLexer(charStream);
TokenStream tokenStream = new CommonTokenStream(lexer);CustomHQLParser parser = new CustomHQLParser(tokenStream);
CustomHQLParser.hql_return ret = parser.hql();CommonTree tree = ret.getTree();

到这里我们就已经得到一棵HQL树了


最后推荐一遍有关ANTLR入门文章http://www.oschina.net/question/12_16797

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值