⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hql.g

📁 hibernate-distribution-3.3.1.GA-dist.zip源码
💻 G
📖 第 1 页 / 共 2 页
字号:
//             ( 4)  relational: <, <=, >, >=,//                   LIKE, NOT LIKE, BETWEEN, NOT BETWEEN, IN, NOT IN//             ( 3)  addition and subtraction: +(binary) -(binary)//             ( 2)  multiplication: * / %, concatenate: ||// highest --> ( 1)  +(unary) -(unary)//                   []   () (method call)  . (dot -- identifier qualification)//                   aggregate function//                   ()  (explicit parenthesis)//// Note that the above precedence levels map to the rules below...// Once you have a precedence chart, writing the appropriate rules as below// is usually very straightfowardlogicalExpression	: expression	;// Main expression ruleexpression	: logicalOrExpression	;// level 7 - ORlogicalOrExpression	: logicalAndExpression ( OR^ logicalAndExpression )*	;// level 6 - AND, NOTlogicalAndExpression	: negatedExpression ( AND^ negatedExpression )*	;// NOT nodes aren't generated.  Instead, the operator in the sub-tree will be// negated, if possible.   Expressions without a NOT parent are passed through.negatedExpression!{ weakKeywords(); } // Weak keywords can appear in an expression, so look ahead.	: NOT^ x:negatedExpression { #negatedExpression = negateNode(#x); }	| y:equalityExpression { #negatedExpression = #y; }	;//## OP: EQ | LT | GT | LE | GE | NE | SQL_NE | LIKE;// level 5 - EQ, NEequalityExpression	: x:relationalExpression (		( EQ^		| is:IS^	{ #is.setType(EQ); } (NOT! { #is.setType(NE); } )?		| NE^		| ne:SQL_NE^	{ #ne.setType(NE); }		) y:relationalExpression)* {			// Post process the equality expression to clean up 'is null', etc.			#equalityExpression = processEqualityExpression(#equalityExpression);		}	;// level 4 - LT, GT, LE, GE, LIKE, NOT LIKE, BETWEEN, NOT BETWEEN// NOTE: The NOT prefix for LIKE and BETWEEN will be represented in the// token type.  When traversing the AST, use the token type, and not the// token text to interpret the semantics of these nodes.relationalExpression	: concatenation (		( ( ( LT^ | GT^ | LE^ | GE^ ) additiveExpression )* )		// Disable node production for the optional 'not'.		| (n:NOT!)? (			// Represent the optional NOT prefix using the token type by			// testing 'n' and setting the token type accordingly.			(i:IN^ {					#i.setType( (n == null) ? IN : NOT_IN);					#i.setText( (n == null) ? "in" : "not in");				}				inList)			| (b:BETWEEN^ {					#b.setType( (n == null) ? BETWEEN : NOT_BETWEEN);					#b.setText( (n == null) ? "between" : "not between");				}				betweenList )			| (l:LIKE^ {					#l.setType( (n == null) ? LIKE : NOT_LIKE);					#l.setText( (n == null) ? "like" : "not like");				}				concatenation likeEscape)			| (MEMBER! (OF!)? p:path! {				processMemberOf(n,#p,currentAST);			  } ) )		)	;likeEscape	: (ESCAPE^ concatenation)?	;inList	: x:compoundExpr	{ #inList = #([IN_LIST,"inList"], #inList); }	;betweenList	: concatenation AND! concatenation	;//level 4 - string concatenationconcatenation	: additiveExpression 	( c:CONCAT^ { #c.setType(EXPR_LIST); #c.setText("concatList"); } 	  additiveExpression	  ( CONCAT! additiveExpression )* 	  { #concatenation = #([METHOD_CALL, "||"], #([IDENT, "concat"]), #c ); } )?	;// level 3 - binary plus and minusadditiveExpression	: multiplyExpression ( ( PLUS^ | MINUS^ ) multiplyExpression )*	;// level 2 - binary multiply and dividemultiplyExpression	: unaryExpression ( ( STAR^ | DIV^ ) unaryExpression )*	;	// level 1 - unary minus, unary plus, notunaryExpression	: MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression	| PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression	| caseExpression	| quantifiedExpression	| atom	;	caseExpression	: CASE^ (whenClause)+ (elseClause)? END! 	| CASE^ { #CASE.setType(CASE2); } unaryExpression (altWhenClause)+ (elseClause)? END!	;	whenClause	: (WHEN^ logicalExpression THEN! unaryExpression)	;	altWhenClause	: (WHEN^ unaryExpression THEN! unaryExpression)	;	elseClause	: (ELSE^ unaryExpression)	;	quantifiedExpression	: ( SOME^ | EXISTS^ | ALL^ | ANY^ ) 	( identifier | collectionExpr | (OPEN! ( subQuery ) CLOSE!) )	;// level 0 - expression atom// ident qualifier ('.' ident ), array index ( [ expr ] ),// method call ( '.' ident '(' exprList ') )atom	 : primaryExpression		(			DOT^ identifier				( options { greedy=true; } :					( op:OPEN^ {#op.setType(METHOD_CALL);} exprList CLOSE! ) )?		|	lb:OPEN_BRACKET^ {#lb.setType(INDEX_OP);} expression CLOSE_BRACKET!		)*	;// level 0 - the basic element of an expressionprimaryExpression	:   identPrimary ( options {greedy=true;} : DOT^ "class" )?	|   constant	|   COLON^ identifier	// TODO: Add parens to the tree so the user can control the operator evaluation order.	|   OPEN! (expressionOrVector | subQuery) CLOSE!	|   PARAM^ (NUM_INT)?	;// This parses normal expression and a list of expressions separated by commas.  If a comma is encountered// a parent VECTOR_EXPR node will be created for the list.expressionOrVector!	: e:expression ( v:vectorExpr )? {		// If this is a vector expression, create a parent node for it.		if (#v != null)			#expressionOrVector = #([VECTOR_EXPR,"{vector}"], #e, #v);		else			#expressionOrVector = #e;	}	;vectorExpr	: COMMA! expression (COMMA! expression)*	;// identifier, followed by member refs (dot ident), or method calls.// NOTE: handleDotIdent() is called immediately after the first IDENT is recognized because// the method looks a head to find keywords after DOT and turns them into identifiers.identPrimary	: identifier { handleDotIdent(); }			( options { greedy=true; } : DOT^ ( identifier | ELEMENTS | o:OBJECT { #o.setType(IDENT); } ) )*			( options { greedy=true; } :				( op:OPEN^ { #op.setType(METHOD_CALL);} exprList CLOSE! )			)?	// Also allow special 'aggregate functions' such as count(), avg(), etc.	| aggregate	;//## aggregate://##     ( aggregateFunction OPEN path CLOSE ) | ( COUNT OPEN STAR CLOSE ) | ( COUNT OPEN (DISTINCT | ALL) path CLOSE );//## aggregateFunction://##     COUNT | 'sum' | 'avg' | 'max' | 'min';aggregate	: ( SUM^ | AVG^ | MAX^ | MIN^ ) OPEN! additiveExpression CLOSE! { #aggregate.setType(AGGREGATE); }	// Special case for count - It's 'parameters' can be keywords.	|  COUNT^ OPEN! ( STAR { #STAR.setType(ROW_STAR); } | ( ( DISTINCT | ALL )? ( path | collectionExpr ) ) ) CLOSE!	|  collectionExpr	;//## collection: ( OPEN query CLOSE ) | ( 'elements'|'indices' OPEN path CLOSE );collectionExpr	: (ELEMENTS^ | INDICES^) OPEN! path CLOSE!	;                                           // NOTE: compoundExpr can be a 'path' where the last token in the path is '.elements' or '.indicies'compoundExpr	: collectionExpr	| path	| (OPEN! ( (expression (COMMA! expression)*) | subQuery ) CLOSE!)	;subQuery	: union	{ #subQuery = #([QUERY,"query"], #subQuery); }	;exprList{   AST trimSpec = null;}	: (t:TRAILING {#trimSpec = #t;} | l:LEADING {#trimSpec = #l;} | b:BOTH {#trimSpec = #b;})?	  		{ if(#trimSpec != null) #trimSpec.setType(IDENT); }	  ( 	  		expression ( (COMMA! expression)+ | FROM { #FROM.setType(IDENT); } expression | AS! identifier )? 	  		| FROM { #FROM.setType(IDENT); } expression	  )?			{ #exprList = #([EXPR_LIST,"exprList"], #exprList); }	;constant	: NUM_INT	| NUM_FLOAT	| NUM_LONG	| NUM_DOUBLE	| QUOTED_STRING	| NULL	| TRUE	| FALSE	| EMPTY	;//## quantifiedExpression: 'exists' | ( expression 'in' ) | ( expression OP 'any' | 'some' ) collection;//## compoundPath: path ( OPEN_BRACKET expression CLOSE_BRACKET ( '.' path )? )*;//## path: identifier ( '.' identifier )*;path	: identifier ( DOT^ { weakKeywords(); } identifier )*	;// Wraps the IDENT token from the lexer, in order to provide// 'keyword as identifier' trickery.identifier	: IDENT	exception	catch [RecognitionException ex]	{		identifier_AST = handleIdentifierError(LT(1),ex);	}	;// **** LEXER ******************************************************************/** * Hibernate Query Language Lexer * <br> * This lexer provides the HQL parser with tokens. * @author Joshua Davis (pgmjsd@sourceforge.net) */class HqlBaseLexer extends Lexer;options {	exportVocab=Hql;      // call the vocabulary "Hql"	testLiterals = false;	k=2; // needed for newline, and to distinguish '>' from '>='.	// HHH-241 : Quoted strings don't allow unicode chars - This should fix it.	charVocabulary='\u0000'..'\uFFFE';	// Allow any char but \uFFFF (16 bit -1, ANTLR's EOF character)	caseSensitive = false;	caseSensitiveLiterals = false;}// -- Declarations --{	// NOTE: The real implementations are in the subclass.	protected void setPossibleID(boolean possibleID) {}}// -- Keywords --EQ: '=';LT: '<';GT: '>';SQL_NE: "<>";NE: "!=" | "^=";LE: "<=";GE: ">=";COMMA: ',';OPEN: '(';CLOSE: ')';OPEN_BRACKET: '[';CLOSE_BRACKET: ']';CONCAT: "||";PLUS: '+';MINUS: '-';STAR: '*';DIV: '/';COLON: ':';PARAM: '?';IDENT options { testLiterals=true; }	: ID_START_LETTER ( ID_LETTER )*		{    		// Setting this flag allows the grammar to use keywords as identifiers, if necessary.			setPossibleID(true);		}	;protectedID_START_LETTER    :    '_'    |    '$'    |    'a'..'z'    |    '\u0080'..'\ufffe'       // HHH-558 : Allow unicode chars in identifiers    ;protectedID_LETTER    :    ID_START_LETTER    |    '0'..'9'    ;QUOTED_STRING	  : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''	;protectedESCqs	:		'\'' '\''	;WS  :   (   ' '		|   '\t'		|   '\r' '\n' { newline(); }		|   '\n'      { newline(); }		|   '\r'      { newline(); }		)		{$setType(Token.SKIP);} //ignore this token	;//--- From the Java example grammar ---// a numeric literalNUM_INT	{boolean isDecimal=false; Token t=null;}	:   '.' {_ttype = DOT;}			(	('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?				{					if (t != null && t.getText().toUpperCase().indexOf('F')>=0)					{						_ttype = NUM_FLOAT;					}					else					{						_ttype = NUM_DOUBLE; // assume double					}				}			)?	|	(	'0' {isDecimal = true;} // special case for just '0'			(	('x')				(											// hex					// the 'e'|'E' and float suffix stuff look					// like hex digits, hence the (...)+ doesn't					// know when to stop: ambig.  ANTLR resolves					// it correctly by matching immediately.  It					// is therefore ok to hush warning.					options { warnWhenFollowAmbig=false; }				:	HEX_DIGIT				)+			|	('0'..'7')+									// octal			)?		|	('1'..'9') ('0'..'9')*  {isDecimal=true;}		// non-zero decimal		)		(	('l') { _ttype = NUM_LONG; }		// only check to see if it's a float if looks like decimal so far		|	{isDecimal}?			(   '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?			|   EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?			|   f4:FLOAT_SUFFIX {t=f4;}			)			{				if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)				{					_ttype = NUM_FLOAT;				}				else				{					_ttype = NUM_DOUBLE; // assume double				}			}		)?	;// hexadecimal digit (again, note it's protected!)protectedHEX_DIGIT	:	('0'..'9'|'a'..'f')	;// a couple protected methods to assist in matching floating point numbersprotectedEXPONENT	:	('e') ('+'|'-')? ('0'..'9')+	;protectedFLOAT_SUFFIX	:	'f'|'d'	;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -