001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * // Copyright (c) 1998, 2007, Oracle. All rights reserved.
005: *
006: *
007: * The contents of this file are subject to the terms of either the GNU
008: * General Public License Version 2 only ("GPL") or the Common Development
009: * and Distribution License("CDDL") (collectively, the "License"). You
010: * may not use this file except in compliance with the License. You can obtain
011: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
012: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
013: * language governing permissions and limitations under the License.
014: *
015: * When distributing the software, include this License Header Notice in each
016: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
017: * Sun designates this particular file as subject to the "Classpath" exception
018: * as provided by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the License
020: * Header, with the fields enclosed by brackets [] replaced by your own
021: * identifying information: "Portions Copyrighted [year]
022: * [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * If you wish your version of this file to be governed by only the CDDL or
027: * only the GPL Version 2, indicate your decision by adding "[Contributor]
028: * elects to include this software in this distribution under the [CDDL or GPL
029: * Version 2] license." If you don't indicate a single choice of license, a
030: * recipient has the option to distribute your version of this file under
031: * either the CDDL, the GPL Version 2 or to extend the choice of license to
032: * its licensees as provided above. However, if you add GPL Version 2 code
033: * and therefore, elected the GPL Version 2 license, then the option applies
034: * only if the new code is made subject to such option by the copyright
035: * holder.
036: */
037: // Copyright (c) 1998, 2007, Oracle. All rights reserved.
038: package oracle.toplink.essentials.internal.parsing.ejbql;
039:
040: /**
041: * This class provides for versioning of the grammar
042: */
043: public class GrammarSpecial {
044: //This shows the grammar (in comment form), copied directly from "EJBQLParser.g"
045: public static void grammar() {
046:
047: /*
048: // Added 20/12/2000 JED. Define the package for the class
049: header {
050: package oracle.toplink.essentials.internal.parsing.ejbql;
051: }
052:
053: class EJBQLParser extends Parser;
054: options {
055: exportVocab=EJBQL;
056: k = 2; // This is the number of tokens to look ahead to
057: buildAST = true;
058: }
059:
060: tokens {
061: FROM="FROM";
062: WHERE="WHERE";
063: OR="OR";
064: AND="AND";
065: TRUE="TRUE";
066: FALSE="FALSE";
067: BETWEEN="BETWEEN";
068: CONCAT="CONCAT";
069: SUBSTRING="SUBSTRING";
070: LENGTH="LENGTH";
071: LOCATE="LOCATE";
072: ABS="ABS";
073: SQRT="SQRT";
074: IS="IS";
075: UNKNOWN="UNKNOWN";
076: LIKE="LIKE";
077: NOT="NOT";
078: PERCENT="%";
079: UNDERSCORE="_";
080: IN="IN";
081: NULL="NULL";
082: EMPTY="EMPTY";
083: AS="AS";
084: }
085:
086: document
087: : (fromClause) (whereClause)?
088: ;
089:
090: //================================================
091: fromClause
092: : from identificationVariableDeclaration (COMMA identificationVariableDeclaration)*
093: ;
094:
095: from
096: : FROM {matchedFrom();}
097: ;
098:
099: identificationVariableDeclaration
100: : collectionMemberDeclaration
101: | rangeVariableDeclaration
102: ;
103:
104: collectionMemberDeclaration
105: : identifier IN singleValuedNavigation
106: ;
107:
108: rangeVariableDeclaration
109: : abstractSchemaName (AS)? abstractSchemaIdentifier
110: ;
111:
112: singleValuedPathExpression
113: // : (singleValuedNavigation | identifier) DOT^ identifier
114: : singleValuedNavigation
115: ;
116:
117: singleValuedNavigation
118: : identifier dot (identifier dot)* identifier
119: ;
120:
121: //collectionValuedPathExpression
122: // : identifier DOT^ (identifier DOT^)* identifier
123:
124: //================================================
125:
126: //from
127: // : (FROM) {matchedFrom();} abstractSchemaClause (whereClause)?
128: // ;
129:
130: //Abstract Schema
131: //abstractSchemaClause
132: // : abstractSchemaName (abstractSchemaVariableClause)?
133: // ;
134:
135: abstractSchemaName
136: : TEXTCHAR {matchedAbstractSchemaName();}
137: ;
138:
139: abstractSchemaIdentifier
140: : identifier {matchedAbstractSchemaIdentifier();}
141: ;
142:
143: dot
144: : DOT^ {matchedDot();}
145: ;
146:
147: identifier
148: : TEXTCHAR {matchedIdentifier();}
149: ;
150:
151: whereClause
152: : WHERE {matchedWhere();} conditionalExpression
153: ;
154:
155: conditionalExpression
156: : conditionalTerm (OR{matchedOr();} conditionalTerm {finishedOr();})*
157: ;
158:
159: conditionalTerm
160: : {conditionalTermFound();} conditionalFactor (AND{matchedAnd();} conditionalFactor {finishedAnd();})*
161: ;
162:
163: conditionalFactor
164: : conditionalTest
165: ;
166:
167: conditionalTest
168: : conditionalPrimary (isExpression (NOT)? (literalBoolean | UNKNOWN))?
169: ;
170:
171: conditionalPrimary
172: : simpleConditionalExpression
173: | (LEFT_ROUND_BRACKET {matchedLeftRoundBracket();} conditionalExpression RIGHT_ROUND_BRACKET {matchedRightRoundBracket();})
174: ;
175:
176: simpleConditionalExpression
177: : comparisonLeftOperand comparisonRemainder
178: ;
179:
180: comparisonLeftOperand
181: : singleValuedPathExpression
182: ;
183:
184: comparisonRemainder
185: : equalsRemainder
186: | betweenRemainder
187: | likeRemainder
188: | inRemainder
189: | nullRemainder
190: ;
191:
192: comparisonExpression
193: : expressionOperandNotMagnitude equals expressionOperandNotMagnitude {finishedEquals();}
194: | expressionOperandMagnitude comparisonOperator expressionOperandMagnitude {finishedComparisonExpression();}
195: ;
196:
197: equalsRemainder
198: : equals (stringExpression | literalNumeric | singleValuedPathExpression) {finishedEquals();}
199: ;
200:
201: betweenRemainder
202: : (NOT {matchedNot();})? ((BETWEEN {matchedBetween();}) literalNumeric) AND
203: {matchedAndAfterBetween();} literalNumeric {finishedBetweenAnd();}
204: ;
205:
206: likeRemainder
207: : (NOT {matchedNot();})? (LIKE {matchedLike();}) literalString {finishedLike();}
208: ;
209:
210: inRemainder
211: : (NOT {matchedNot();})? (IN {matchedIn();})
212: (LEFT_ROUND_BRACKET
213: (literalString|literalNumeric)
214: (COMMA (literalString|literalNumeric))*
215: RIGHT_ROUND_BRACKET)
216: {finishedIn();}
217: ;
218:
219: emptyCollectionRemainder
220: : IS (NOT {matchedNot();})? EMPTY {matchedEmpty();} {finishedEmpty();}
221: ;
222:
223: nullRemainder
224: : IS (NOT {matchedNot();})? NULL {matchedNull();} {finishedNull();}
225: ;
226:
227: arithmeticExpression
228: : literal
229: ;
230:
231: stringExpression
232: : literalString
233: ;
234:
235: expressionOperandNotMagnitude
236: : literalString
237: | singleValuedPathExpression
238: ;
239:
240: expressionOperandMagnitude
241: : literalNumeric
242: // | singleValuedReferenceExpression
243: ;
244:
245: singleValueDesignator
246: : singleValuedPathExpression
247: ;
248:
249: singleValuedReferenceExpression
250: : variableName (DOT^ variableName)?
251: ;
252:
253: singleValuedDesignator
254: : scalarExpression
255: ;
256:
257: scalarExpression
258: : arithmeticExpression
259: ;
260:
261: variableName
262: : TEXTCHAR {matchedVariableName();}
263: ;
264:
265: isExpression
266: : (IS {matchedIs();})
267: ;
268:
269: //Literals and Low level stuff
270:
271: literal
272: : literalNumeric
273: | literalBoolean
274: | literalString
275: ;
276:
277: literalNumeric
278: : NUM_INT {matchedInteger();}
279: | NUM_FLOAT^ {matchedFloat();}
280: ;
281:
282: literalBoolean
283: : TRUE {matchedTRUE();}
284: | FALSE {matchedFALSE();}
285: ;
286:
287: // Added Jan 9, 2001 JED
288: literalString
289: : STRING_LITERAL {matchedString();}
290: ;
291:
292: // Added 20/12/2000 JED
293: comparisonOperator
294: : (equals|greaterThan|greaterThanEqualTo|lessThan|lessThanEqualTo|notEqualTo)
295: ;
296:
297: equals
298: : (EQUALS) {matchedEquals();}
299: ;
300:
301: greaterThan
302: : (GREATER_THAN) {matchedGreaterThan();}
303: ;
304:
305: greaterThanEqualTo
306: : GREATER_THAN_EQUAL_TO {matchedGreaterThanEqualTo();}
307: ;
308:
309: lessThan
310: : (LESS_THAN) {matchedLessThan();}
311: ;
312:
313: lessThanEqualTo
314: : LESS_THAN_EQUAL_TO {matchedLessThanEqualTo();}
315: ;
316:
317: notEqualTo
318: : (NOT_EQUAL_TO) {matchedNotEqualTo();}
319: ;
320:
321: // End of addition 20/12/2000 JED
322:
323: class EJBQLLexer extends Lexer;
324: options {
325: k = 4;
326: exportVocab=EJBQL;
327: charVocabulary = '\3'..'\377';
328: caseSensitive=true;
329: }
330:
331: // hexadecimal digit (again, note it's protected!)
332: protected
333: HEX_DIGIT
334: : ('0'..'9'|'A'..'F'|'a'..'f')
335: ;
336:
337: WS : (' ' | '\t' | '\n' | '\r')+
338: { $setType(Token.SKIP); } ;
339:
340: LEFT_ROUND_BRACKET
341: : '('
342: ;
343:
344: RIGHT_ROUND_BRACKET
345: : ')'
346: ;
347:
348: COMMA
349: : ','
350: ;
351:
352: TEXTCHAR
353: : ('a'..'z' | 'A'..'Z' | '_')+
354: ;
355:
356: // a numeric literal
357: NUM_INT
358: {boolean isDecimal=false;}
359: : '.' {_ttype = DOT;}
360: (('0'..'9')+ (EXPONENT)? (FLOAT_SUFFIX)? { _ttype = NUM_FLOAT; })?
361: | ( '0' {isDecimal = true;} // special case for just '0'
362: ( ('x'|'X')
363: ( // hex
364: // the 'e'|'E' and float suffix stuff look
365: // like hex digits, hence the (...)+ doesn't
366: // know when to stop: ambig. ANTLR resolves
367: // it correctly by matching immediately. It
368: // is therefor ok to hush warning.
369: options {
370: warnWhenFollowAmbig=false;
371: }
372: : HEX_DIGIT
373: )+
374: | ('0'..'7')+ // octal
375: )?
376: | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal
377: )
378: ( ('l'|'L')
379:
380: // only check to see if it's a float if looks like decimal so far
381: | {isDecimal}?
382: ( '.' ('0'..'9')* (EXPONENT)? (FLOAT_SUFFIX)?
383: | EXPONENT (FLOAT_SUFFIX)?
384: | FLOAT_SUFFIX
385: )
386: { _ttype = NUM_FLOAT; }
387: )?
388: ;
389:
390: // a couple protected methods to assist in matching floating point numbers
391: protected
392: EXPONENT
393: : ('e'|'E') ('+'|'-')? ('0'..'9')+
394: ;
395:
396:
397: protected
398: FLOAT_SUFFIX
399: : 'f'|'F'|'d'|'D'
400: ;
401:
402: EQUALS
403: : '='
404: ;
405:
406: GREATER_THAN
407: : '>'
408: ;
409:
410: GREATER_THAN_EQUAL_TO
411: : ">="
412: ;
413:
414: LESS_THAN
415: : '<'
416: ;
417:
418: LESS_THAN_EQUAL_TO
419: : "<="
420: ;
421:
422: NOT_EQUAL_TO
423: : "<>"
424: ;
425:
426: // Added Jan 9, 2001 JED
427: // string literals
428: STRING_LITERAL
429: : '"' (ESC|~('"'|'\\'))* '"'
430: ;
431:
432: // Added Jan 9, 2001 JED
433: // escape sequence -- note that this is protected; it can only be called
434: // from another lexer rule -- it will not ever directly return a token to
435: // the parser
436: // There are various ambiguities hushed in this rule. The optional
437: // '0'...'9' digit matches should be matched here rather than letting
438: // them go back to STRING_LITERAL to be matched. ANTLR does the
439: // right thing by matching immediately; hence, it's ok to shut off
440: // the FOLLOW ambig warnings.
441: protected
442: ESC
443: : '\\'
444: ( 'n'
445: | 'r'
446: | 't'
447: | 'b'
448: | 'f'
449: | '"'
450: | '\''
451: | '\\'
452: | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
453: | ('0'..'3')
454: (
455: options {
456: warnWhenFollowAmbig = false;
457: }
458: : ('0'..'7')
459: (
460: options {
461: warnWhenFollowAmbig = false;
462: }
463: : '0'..'7'
464: )?
465: )?
466: | ('4'..'7')
467: (
468: options {
469: warnWhenFollowAmbig = false;
470: }
471: : ('0'..'9')
472: )?
473: )
474: ;
475:
476:
477: */
478: }
479: }
|