Repository: cayenne
Updated Branches:
  refs/heads/master a6c5efbcd -> d249aa37d


http://git-wip-us.apache.org/repos/asf/cayenne/blob/55e3c975/cayenne-server/src/main/jjtree/org/apache/cayenne/template/parser/SQLTemplateParser.jjt
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/jjtree/org/apache/cayenne/template/parser/SQLTemplateParser.jjt
 
b/cayenne-server/src/main/jjtree/org/apache/cayenne/template/parser/SQLTemplateParser.jjt
new file mode 100644
index 0000000..8e8cae5
--- /dev/null
+++ 
b/cayenne-server/src/main/jjtree/org/apache/cayenne/template/parser/SQLTemplateParser.jjt
@@ -0,0 +1,327 @@
+options {
+
+       MULTI = true;
+       NODE_DEFAULT_VOID = true;
+
+       STATIC = false;
+       DEBUG_PARSER = false;
+       DEBUG_LOOKAHEAD = false;
+       DEBUG_TOKEN_MANAGER = false;
+       JAVA_UNICODE_ESCAPE = true;
+       UNICODE_INPUT = true;
+}
+
+PARSER_BEGIN(SQLTemplateParser)
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.template.parser;
+
+/**
+  * Parser of Cayenne Templates.
+  *
+  * @since 4.1
+  */
+public class SQLTemplateParser {
+}
+
+PARSER_END(SQLTemplateParser)
+
+
+ASTBlock template() : {}
+{
+       block() <EOF>
+    {
+        return (ASTBlock) jjtree.rootNode();
+    }
+}
+
+void block() #Block : {}
+{
+    (   text()
+    |   ifElse()
+    |   directive()
+    ) *
+}
+
+void text() #Text : {
+    Token t;
+}
+{
+    t = <TEXT> {
+        jjtThis.setValue(t.image);
+    }
+}
+
+void ifElse() #IfElse : {}
+{
+    <IF> <LBRACKET> expression() <RBRACKET>
+    block()
+    ( <ELSE> block() )?
+    <END>
+}
+
+void directive() #Directive : {
+    Token t;
+}
+{
+    <SHARP> ( t = <IDENTIFIER> ) {
+        jjtThis.setIdentifier(t.image);
+    }
+    <LBRACKET> (expression() (<COMMA> expression())* )? <RBRACKET>
+}
+
+void expression() #Expression : {}
+{
+    scalar()
+    |   variable()
+}
+
+void scalar() : {}
+{
+    <SINGLE_QUOTED_STRING> { 
jjtThis.setValue((String)token_source.literalValue); } #StringScalar(0)
+    |   <DOUBLE_QUOTED_STRING> { 
jjtThis.setValue((String)token_source.literalValue); } #StringScalar(0)
+    |   <INT_LITERAL>   { jjtThis.setValue((Long)token_source.literalValue); } 
#IntScalar(0)
+    |   <FLOAT_LITERAL> { jjtThis.setValue((Double)token_source.literalValue); 
} #FloatScalar(0)
+    |   <TRUE>  { jjtThis.setValue(true);  } #BoolScalar(0)
+    |   <FALSE> { jjtThis.setValue(false); } #BoolScalar(0)
+}
+
+void variable() #Variable : {
+    Token t;
+}
+{
+    <DOLLAR> ( t = <IDENTIFIER> ) {
+        jjtThis.setIdentifier(t.image);
+    }
+    ( <DOT> method() )*
+}
+
+void method() #Method : {
+    Token t;
+}
+{
+    ( t = <IDENTIFIER> ) {
+        jjtThis.setIdentifier(t.image);
+    }
+    <LBRACKET> (expression() (<COMMA> expression())* )? <RBRACKET>
+}
+
+/****************************************
+ * Copy of ExpressionParser definitions *
+ ****************************************/
+
+TOKEN_MGR_DECLS:
+{
+    /** Holds the last value computed by a constant token. */
+    Object literalValue;
+
+    /** Holds the last string literal parsed. */
+    private StringBuffer stringBuffer;
+
+    /** Converts an escape sequence into a character value. */
+    private char escapeChar() {
+        int ofs = image.length() - 1;
+        switch ( image.charAt(ofs) ) {
+            case 'n':   return '\n';
+            case 'r':   return '\r';
+            case 't':   return '\t';
+            case 'b':   return '\b';
+            case 'f':   return '\f';
+            case '\\':  return '\\';
+            case '\'':  return '\'';
+            case '\"':  return '\"';
+        }
+
+          // Otherwise, it's an octal number.  Find the backslash and convert.
+        while ( image.charAt(--ofs) != '\\' ){
+        }
+
+        int value = 0;
+        while ( ++ofs < image.length() ) {
+            value = (value << 3) | (image.charAt(ofs) - '0');
+        }
+        return (char) value;
+    }
+
+    private Object makeInt() {
+        Object  result;
+        String  s = image.toString();
+        int     base = 10;
+
+        if ( s.charAt(0) == '0' ) {
+            base = (s.length() > 1 && (s.charAt(1) == 'x' || s.charAt(1) == 
'X'))? 16 : 8;
+        }
+        if ( base == 16 ) {
+            s = s.substring(2); // Trim the 0x off the front
+        }
+
+        switch ( s.charAt(s.length()-1) ) {
+            case 'l': case 'L':
+                result = Long.valueOf( s.substring(0,s.length()-1), base );
+                break;
+
+            default:
+                result = Long.valueOf( s, base );
+                break;
+        }
+        return result;
+    }
+
+    private Object makeFloat() {
+        String s = image.toString();
+        switch ( s.charAt(s.length()-1) ) {
+            case 'f': case 'F':
+                return Double.valueOf( s );
+
+            case 'd': case 'D':
+            default:
+                return Double.valueOf( s );
+        }
+    }
+}
+
+TOKEN:
+{
+    <IF: "#if">
+|   <ELSE: "#else">
+|   <END: "#end">
+}
+
+TOKEN:
+{
+    <TRUE: "true" | "TRUE">
+|   <FALSE: "false" | "FALSE">
+}
+
+TOKEN:
+{
+    <WHITESPACE : ([" ","\t"])+ >
+|   <NEWLINE : ("\n" | "\r" | "\r\n") >
+}
+
+TOKEN :
+{
+    <SHARP: "#">
+|   <DOLLAR: "$">
+|   <LBRACKET: "(">
+|   <RBRACKET: ")">
+|   <COMMA: "," | " ">
+|   <DOT: ".">
+}
+
+TOKEN :
+{
+    <IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
+|   <#LETTER: ["_","a"-"z","A"-"Z"] >
+|   <#DIGIT: ["0"-"9"] >
+}
+
+TOKEN :
+{
+    < "##" > : IN_SINGLE_LINE_COMMENT
+}
+
+<IN_SINGLE_LINE_COMMENT>
+TOKEN :
+{
+    <SINGLE_LINE_COMMENT_END: "\n" | "\r" | "\r\n" > : DEFAULT
+}
+
+<IN_SINGLE_LINE_COMMENT>
+SKIP :
+{
+    < ~[] >
+}
+
+/**
+ * Quoted Strings, whose object value is stored in the token manager's
+ * "literalValue" field. Both single and double qoutes are allowed
+ */
+MORE:
+{
+    "'"  { stringBuffer = new StringBuffer(); }: WithinSingleQuoteLiteral
+ |
+    "\""  { stringBuffer = new StringBuffer(); }: WithinDoubleQuoteLiteral
+}
+
+<WithinSingleQuoteLiteral> MORE:
+{
+       < ESC: "\\" ( ["n","r","t","b","f","\\","'","`","\""]
+                | (["0"-"3"])? ["0"-"7"] (["0"-"7"])?
+                )
+    >
+        { stringBuffer.append( escapeChar() ); }
+ |
+    < (~["'","\\"]) >
+        { stringBuffer.append( image.charAt(image.length()-1) ); }
+}
+
+<WithinSingleQuoteLiteral> TOKEN :
+{
+    <SINGLE_QUOTED_STRING: "'">
+        { literalValue = stringBuffer.toString(); }
+        : DEFAULT
+}
+
+<WithinDoubleQuoteLiteral> MORE :
+{
+    < STRING_ESC: <ESC> >
+        { stringBuffer.append( escapeChar() ); }
+ |
+    < (~["\"","\\"]) >
+        { stringBuffer.append( image.charAt(image.length()-1) ); }
+}
+
+<WithinDoubleQuoteLiteral> TOKEN:
+{
+    <DOUBLE_QUOTED_STRING: "\"">
+        { literalValue = stringBuffer.toString(); }
+        : DEFAULT
+}
+
+TOKEN:
+{
+    <INT_LITERAL:
+        ( "0" (["0"-"7"])* | ["1"-"9"] (["0"-"9"])* | "0" ["x","X"] 
(["0"-"9","a"-"f","A"-"F"])+ )
+        (["l","L","h","H"])?
+    >
+    { literalValue = makeInt(); }
+|   <FLOAT_LITERAL:
+        ( <DEC_FLT> (<EXPONENT>)? (<FLT_SUFF>)?
+        | <DEC_DIGITS> <EXPONENT> (<FLT_SUFF>)?
+        | <DEC_DIGITS> <FLT_SUFF>
+        )
+    >
+    { literalValue = makeFloat(); }
+
+|   <#DEC_FLT: (["0"-"9"])+ "." (["0"-"9"])* | "." (["0"-"9"])+ >
+|   <#DEC_DIGITS: (["0"-"9"])+ >
+|   <#EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
+|   <#FLT_SUFF: ["d","D","f","F","b","B"] >
+}
+
+// This must be last to not interfere with string literals
+TOKEN :
+{
+    <DOUBLE_ESCAPE : "\\\\">
+|   <ESCAPE: "\\" >
+|   <TEXT: (~["$", "#", "\\"])* (~["$", "#", "\\", " ", "\t"])+ (~["$", "#", 
"\\"])* >
+}
+

Reply via email to