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

📄 dql.g

📁 OBPM是一个开源
💻 G
📖 第 1 页 / 共 2 页
字号:
	| 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)
	;

// 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 expression
primaryExpression
	:   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) 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)*) ) CLOSE!)
	;

exprList
{
   AST trimSpec = null;
}
	: (t:TRAILING {#trimSpec = #t;} | l:LEADING {#trimSpec = #l;} | b:BOTH {#trimSpec = #b;})?
	  		{ if(#trimSpec != null) #trimSpec.setType(IDENT); }
	  ( 
	  		expression
	  )?
	;

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 ******************************************************************

class DqlBaseLexer extends Lexer;

options {
	exportVocab=Dql;      // 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);
		}
	;

protected
ID_START_LETTER
    :    '_'
    |    '$'
    |	 '#'
    |    'a'..'z'
    |    '\u0080'..'\ufffe'       // HHH-558 : Allow unicode chars in identifiers
    ;

protected
ID_LETTER
    :    ID_START_LETTER
    |    '0'..'9'
    ;

QUOTED_STRING
	: '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
	;

protected
ESCqs
	:
		'\'' '\''
	;

WS  :   (   ' '
		|   '\t'
		|   '\r' '\n' { newline(); }
		|   '\n'      { newline(); }
		|   '\r'      { newline(); }
		)
		{$setType(Token.SKIP);} //ignore this token
	;

//--- From the Java example grammar ---
// a numeric literal
NUM_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!)
protected
HEX_DIGIT
	:	('0'..'9'|'a'..'f')
	;

// a couple protected methods to assist in matching floating point numbers
protected
EXPONENT
	:	('e') ('+'|'-')? ('0'..'9')+
	;

protected
FLOAT_SUFFIX
	:	'f'|'d'
	;

//**********************************
class ExprTreeParser extends TreeParser;
/*
options {
    importVocab=DQL;
}
*/
expr[ParamsTable params, int side, int opt] returns [String r=""]
{ String a,b; }
    :   #(AND a=expr[params,1,AND] b=expr[params,2,AND])  {r = "("+a+" AND "+b+")";}
    |   #(OR a=expr[params,1,OR] b=expr[params,2,OR])  {r = "("+a+" OR "+b+")";}   
    |	#(EQ a=expr[params,1,EQ] b=expr[params,2,EQ])  {r = "("+a+" = "+b+")";} 
    |	#(LT a=expr[params,1,LT] b=expr[params,2,LT])  {r = "("+a+" < "+b+")";} 
    |	#(GT a=expr[params,1,GT] b=expr[params,2,GT])  {r = "("+a+" > "+b+")";} 
    |	#(NE a=expr[params,1,NE] b=expr[params,2,NE])  {r = "("+a+" <> "+b+")";} 
    |	#(LE a=expr[params,1,LE] b=expr[params,2,LE])  {r = "("+a+" <= "+b+")";} 
    |	#(GE a=expr[params,1,GE] b=expr[params,2,GE])  {r = "("+a+" >= "+b+")";} 
    |	#(CONCAT a=expr[params,1,CONCAT] b=expr[params,2,CONCAT])  {r = "("+a+" || "+b+")";} 
    |	#(PLUS a=expr[params,1,PLUS] b=expr[params,2,PLUS])  {r = "("+a+" + "+b+")";} 
    |	#(MINUS a=expr[params,1,MINUS] b=expr[params,2,MINUS])  {r = "("+a+" - "+b+")";} 
    |	#(STAR a=expr[params,1,STAR] b=expr[params,2,STAR])  {r = "("+a+" * "+b+")";} 
    |	#(DIV a=expr[params,1,DIV] b=expr[params,2,DIV])  {r = "("+a+" / "+b+")";} 
    |	#(LIKE a=expr[params,1,LIKE] b=expr[params,2,LIKE])  {r = "("+a+" LIKE "+b+")";} 
    |	#(ILIKE a=expr[params,1,ILIKE] b=expr[params,2,ILIKE])  {r = "("+a+" LIKE "+b+")";} 
    |	#(NOT_LIKE a=expr[params,1,NOT_LIKE] b=expr[params,2,NOT_LIKE])  {r = "("+a+" NOT LIKE "+b+")";} 
    |	#(NOT_ILIKE a=expr[params,1,NOT_ILIKE] b=expr[params,2,NOT_ILIKE])  {r = "(LOWER("+a+") NOT LIKE LOWER("+b+"))";} 
    |	#(IN a=expr[params,1,IN] b=expr[params,2,IN])  {r = "("+a+" IN "+b+")";} 
    |	#(NOT_IN a=expr[params,1,NOT_IN] b=expr[params,2,NOT_IN])  {r = "("+a+" NOT IN "+b+")";} 
    |	#(IS a=expr[params,1,IS] b=expr[params,2,IS])  {r = "("+a+" IS "+b+")";}
    |	#(NOT_IS a=expr[params,1,NOT_IS] b=expr[params,2,NOT_IS])  {r = "("+a+" NOT_IS "+b+")";}
    
    |	i3:IDENT{r = DQLASTUtil.transTo(i3.getText(),params,side,IDENT,opt);}
    |	i4:NUM_INT {r = DQLASTUtil.transTo(i4.getText(),params,side,NUM_INT,opt);}
    |	i5:NUM_FLOAT {r = DQLASTUtil.transTo(i5.getText(),params,side,NUM_FLOAT,opt);}
    |	i6:NUM_LONG {r = DQLASTUtil.transTo(i6.getText(),params,side,NUM_LONG,opt);}
    |	i7:NUM_DOUBLE {r = DQLASTUtil.transTo(i7.getText(),params,side,NUM_DOUBLE,opt);}
    |	i8:QUOTED_STRING {r = DQLASTUtil.transTo(i8.getText(),params,side,QUOTED_STRING,opt);}
    |	i9:NULL {r = DQLASTUtil.transTo(i9.getText(),params,side,NULL,opt);}
    |	i10:TRUE {r = DQLASTUtil.transTo(i10.getText(),params,side,TRUE,opt);}
    |	i11:FALSE {r = DQLASTUtil.transTo(i11.getText(),params,side,FALSE,opt);}
    |	i12:EMPTY {r = DQLASTUtil.transTo(i12.getText(),params,side,EMPTY,opt);}
    |	i13:IN_LIST {r = DQLASTUtil.transTo(DQLASTUtil.inListToString(i13),params,side,IN_LIST,opt);}
    
    ;
    

⌨️ 快捷键说明

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