alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons JXPath example source code file (XPath.jj)

This example Commons JXPath source code file (XPath.jj) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons JXPath tags/keywords

additiveexpr, arraylist, arraylist, digit, expression, locationstep, lookahead, ncname, ncname, object, object, string, string, unaryexpr

The Commons JXPath XPath.jj source code

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

/* ----------------------------------------
    JavaCC 1.1 Options
-------------------------------------------*/

options {
    LOOKAHEAD = 1;                      // (default 1)
    CHOICE_AMBIGUITY_CHECK = 2;         // (default 2)
    OTHER_AMBIGUITY_CHECK = 1;          // (default 1)

    STATIC = false;                     // (default true)
    DEBUG_PARSER = false;               // (default false)
    DEBUG_LOOKAHEAD = false;            // (default false)
    DEBUG_TOKEN_MANAGER = false;        // (default false)
    OPTIMIZE_TOKEN_MANAGER = true;      // (default true)
    ERROR_REPORTING = true;             // (default true)
    JAVA_UNICODE_ESCAPE = false;        // (default false)
    UNICODE_INPUT = true;               // (default false)
    IGNORE_CASE = false;                // (default false)
    COMMON_TOKEN_ACTION = false;        // (default false)
    USER_TOKEN_MANAGER = false;         // (default false)
    USER_CHAR_STREAM = false;           // (default false)
    BUILD_PARSER = true;                // (default true)
    BUILD_TOKEN_MANAGER = true;         // (default true)
    SANITY_CHECK = true;                // (default true)
    FORCE_LA_CHECK = false;             // (default false)
    CACHE_TOKENS = true;                // (default false)
}

/*--------------------------------------------
    Parser Class
---------------------------------------------*/

PARSER_BEGIN(XPathParser)
    package org.apache.commons.jxpath.ri.parser;

    import org.apache.commons.jxpath.ri.Compiler;
    import java.util.ArrayList;

    public class XPathParser {
        private Compiler compiler;

        public void setCompiler(Compiler compiler){
            this.compiler = compiler;
        }

        private String unescape(String string){
            int index = string.indexOf("'");
            while (index != -1){
                string = string.substring(0, index) + "\'" + string.substring(index + 6);
                index = string.indexOf("'");
            }
            index = string.indexOf(""");
            while (index != -1){
                string = string.substring(0, index) + "\"" + string.substring(index + 6);
                index = string.indexOf(""");
            }
            return string;
        }
    }

PARSER_END(XPathParser)

/*----------------------------*/
/* Skip Whitespace everywhere */
/*----------------------------*/


/* [39]    ExprWhitespace    ::=    S  */
SKIP :
{
   " " | "\t" | "\n" | "\r" | "\f"
}

/*-----------------*/
/* Operator Tokens */
/*-----------------*/


TOKEN:
{
          <SLASH:      "/"    >
    |     <SLASHSLASH: "//"   >
    |     <UNION:      "|"    >
    |     <PLUS:       "+"    >
    |     <MINUS:      "-"    >
    |     <EQ:         "="    >
    |     <NEQ:        "!="   >
    |     <LT:         "<"    >
    |     <LTE:        "<="   >
    |     <GT:         ">"    >
    |     <GTE:        ">="   >
    |     <VARIABLE:   "$"    >
}


/*-----------------------------------------------*/
/* Unambigious Tokens (Number, Literal, Variable */
/*-----------------------------------------------*/

TOKEN:
{

/* [29] Literal    ::=    '"' [^"]* '"' | "'" [^']* "'"  */
    <Literal :
            "\"" (~["\""])* "\""
        |    "'"  (~["'"] )* "'"
    >

|

/* [31]    Digits    ::=    [0-9]+  */
    <#Digit :
        ["0"-"9"]
    >

|

/* [30]    Number    ::=    Digits ('.' Digits?)?  | '.' Digits  */
    <Number :
            (<Digit>)+ ("." ( ()+ )? )?
        |    "." (<Digit>)+
    >
}


/*-------------------------------*/
/* XML Names and Qualified Names */
/*-------------------------------*/

TOKEN:
{
    <#Letter :
        <BaseChar> | 
    >
|
    <#BaseChar :
        (
        ["\u0041"-"\u005A"] | ["\u0061"-"\u007A"] | ["\u00C0"-"\u00D6"] | ["\u00D8"-"\u00F6"] |
        ["\u00F8"-"\u00FF"] | ["\u0100"-"\u0131"] | ["\u0134"-"\u013E"] | ["\u0141"-"\u0148"] |
        ["\u014A"-"\u017E"] | ["\u0180"-"\u01C3"] | ["\u01CD"-"\u01F0"] | ["\u01F4"-"\u01F5"] |
        ["\u01FA"-"\u0217"] | ["\u0250"-"\u02A8"] | ["\u02BB"-"\u02C1"] | "\u0386" | ["\u0388"-"\u038A"] |
        "\u038C" | ["\u038E"-"\u03A1"] | ["\u03A3"-"\u03CE"] | ["\u03D0"-"\u03D6"] | "\u03DA" |
        "\u03DC" |  "\u03DE" | "\u03E0" | ["\u03E2"-"\u03F3"] | ["\u0401"-"\u040C"] | ["\u040E"-"\u044F"] |
        ["\u0451"-"\u045C"] | ["\u045E"-"\u0481"] | ["\u0490"-"\u04C4"] | ["\u04C7"-"\u04C8"] |
        ["\u04CB"-"\u04CC"] | ["\u04D0"-"\u04EB"] | ["\u04EE"-"\u04F5"] | ["\u04F8"-"\u04F9"] |
        ["\u0531"-"\u0556"] | "\u0559" | ["\u0561"-"\u0586"] | ["\u05D0"-"\u05EA"] | ["\u05F0"-"\u05F2"] |
        ["\u0621"-"\u063A"] | ["\u0641"-"\u064A"] | ["\u0671"-"\u06B7"] | ["\u06BA"-"\u06BE"] |
        ["\u06C0"-"\u06CE"] | ["\u06D0"-"\u06D3"] | "\u06D5" | ["\u06E5"-"\u06E6"] | ["\u0905"-"\u0939"] |
        "\u093D" | ["\u0958"-"\u0961"] | ["\u0985"-"\u098C"] | ["\u098F"-"\u0990"] | ["\u0993"-"\u09A8"] |
        ["\u09AA"-"\u09B0"] | "\u09B2" | ["\u09B6"-"\u09B9"] | ["\u09DC"-"\u09DD"] | ["\u09DF"-"\u09E1"] |
        ["\u09F0"-"\u09F1"] | ["\u0A05"-"\u0A0A"] | ["\u0A0F"-"\u0A10"] | ["\u0A13"-"\u0A28"] |
        ["\u0A2A"-"\u0A30"] | ["\u0A32"-"\u0A33"] | ["\u0A35"-"\u0A36"] | ["\u0A38"-"\u0A39"] |
        ["\u0A59"-"\u0A5C"] | "\u0A5E" | ["\u0A72"-"\u0A74"] | ["\u0A85"-"\u0A8B"] | "\u0A8D" |
        ["\u0A8F"-"\u0A91"] | ["\u0A93"-"\u0AA8"] | ["\u0AAA"-"\u0AB0"] | ["\u0AB2"-"\u0AB3"] |
        ["\u0AB5"-"\u0AB9"] | "\u0ABD" | "\u0AE0" |  ["\u0B05"-"\u0B0C"] | ["\u0B0F"-"\u0B10"] |
        ["\u0B13"-"\u0B28"] | ["\u0B2A"-"\u0B30"] | ["\u0B32"-"\u0B33"] | ["\u0B36"-"\u0B39"] |
        "\u0B3D" | ["\u0B5C"-"\u0B5D"] | ["\u0B5F"-"\u0B61"] | ["\u0B85"-"\u0B8A"] |  ["\u0B8E"-"\u0B90"] |
        ["\u0B92"-"\u0B95"] |  ["\u0B99"-"\u0B9A"] | "\u0B9C" | ["\u0B9E"-"\u0B9F"] | ["\u0BA3"-"\u0BA4"] |
        ["\u0BA8"-"\u0BAA"] | ["\u0BAE"-"\u0BB5"] | ["\u0BB7"-"\u0BB9"] | ["\u0C05"-"\u0C0C"] |
        ["\u0C0E"-"\u0C10"] | ["\u0C12"-"\u0C28"] | ["\u0C2A"-"\u0C33"] | ["\u0C35"-"\u0C39"] |
        ["\u0C60"-"\u0C61"] | ["\u0C85"-"\u0C8C"] | ["\u0C8E"-"\u0C90"] | ["\u0C92"-"\u0CA8"] |
        ["\u0CAA"-"\u0CB3"] | ["\u0CB5"-"\u0CB9"] | "\u0CDE" | ["\u0CE0"-"\u0CE1"] | ["\u0D05"-"\u0D0C"] |
        ["\u0D0E"-"\u0D10"] | ["\u0D12"-"\u0D28"] | ["\u0D2A"-"\u0D39"] | ["\u0D60"-"\u0D61"] |
        ["\u0E01"-"\u0E2E"] | "\u0E30" | ["\u0E32"-"\u0E33"] | ["\u0E40"-"\u0E45"] | ["\u0E81"-"\u0E82"] |
        "\u0E84" | ["\u0E87"-"\u0E88"] | "\u0E8A" | "\u0E8D" | ["\u0E94"-"\u0E97"] | ["\u0E99"-"\u0E9F"] |
        ["\u0EA1"-"\u0EA3"] | "\u0EA5" | "\u0EA7" | ["\u0EAA"-"\u0EAB"] | ["\u0EAD"-"\u0EAE"] | "\u0EB0" |
        ["\u0EB2"-"\u0EB3"] | "\u0EBD" | ["\u0EC0"-"\u0EC4"] | ["\u0F40"-"\u0F47"] | ["\u0F49"-"\u0F69"] |
        ["\u10A0"-"\u10C5"] | ["\u10D0"-"\u10F6"] | "\u1100" | ["\u1102"-"\u1103"] | ["\u1105"-"\u1107"] |
        "\u1109" | ["\u110B"-"\u110C"] | ["\u110E"-"\u1112"] | "\u113C" | "\u113E" | "\u1140" | "\u114C" |
        "\u114E" | "\u1150" | ["\u1154"-"\u1155"] | "\u1159" | ["\u115F"-"\u1161"] | "\u1163" | "\u1165" |
        "\u1167" | "\u1169" | ["\u116D"-"\u116E"] | ["\u1172"-"\u1173"] | "\u1175" | "\u119E" | "\u11A8" |
        "\u11AB" | ["\u11AE"-"\u11AF"] | ["\u11B7"-"\u11B8"] | "\u11BA" |  ["\u11BC"-"\u11C2"] | "\u11EB" |
        "\u11F0" | "\u11F9" | ["\u1E00"-"\u1E9B"] | ["\u1EA0"-"\u1EF9"] | ["\u1F00"-"\u1F15"] |
        ["\u1F18"-"\u1F1D"] |
        ["\u1F20"-"\u1F45"] | ["\u1F48"-"\u1F4D"] | ["\u1F50"-"\u1F57"] | "\u1F59" | "\u1F5B" | "\u1F5D" |
        ["\u1F5F"-"\u1F7D"] | ["\u1F80"-"\u1FB4"] | ["\u1FB6"-"\u1FBC"] | "\u1FBE" |  ["\u1FC2"-"\u1FC4"] |
        ["\u1FC6"-"\u1FCC"] | ["\u1FD0"-"\u1FD3"] | ["\u1FD6"-"\u1FDB"] | ["\u1FE0"-"\u1FEC"] |
        ["\u1FF2"-"\u1FF4"] | ["\u1FF6"-"\u1FFC"] | "\u2126" | ["\u212A"-"\u212B"] | "\u212E" |
        ["\u2180"-"\u2182"] | ["\u3041"-"\u3094"] | ["\u30A1"-"\u30FA"] | ["\u3105"-"\u312C"] |
        ["\uAC00"-"\uD7A3"]
        )
    >
|
    <#Ideographic :
        (["\u4E00"-"\u9FA5"] | "\u3007" | ["\u3021"-"\u3029"])
    >
|
    <#CombiningChar :
        (
        ["\u0300"-"\u0345"]    |    ["\u0360"-"\u0361"]     |    ["\u0483"-"\u0486"]    |    ["\u0591"-"\u05A1"] |
        ["\u05A3"-"\u05B9"]    |    ["\u05BB"-"\u05BD"]        |    "\u05BF"             |    ["\u05C1"-"\u05C2"] |
        "\u05C4"             | ["\u064B"-"\u0652"] | "\u0670"             | ["\u06D6"-"\u06DC"] |
        ["\u06DD"-"\u06DF"] | ["\u06E0"-"\u06E4"] | ["\u06E7"-"\u06E8"] | ["\u06EA"-"\u06ED"] |
        ["\u0901"-"\u0903"] | "\u093C"    |["\u093E"-"\u094C"] | "\u094D" | ["\u0951"-"\u0954"] |
        ["\u0962"-"\u0963"] | ["\u0981"-"\u0983"] | "\u09BC" | "\u09BE" | "\u09BF" | ["\u09C0"-"\u09C4"] |
        ["\u09C7"-"\u09C8"] | ["\u09CB"-"\u09CD"] | "\u09D7" | ["\u09E2"-"\u09E3"] | "\u0A02" | "\u0A3C" |
        "\u0A3E" | "\u0A3F" | ["\u0A40"-"\u0A42"] |
        ["\u0A47"-"\u0A48"] | ["\u0A4B"-"\u0A4D"] | ["\u0A70"-"\u0A71"] | ["\u0A81"-"\u0A83"] | "\u0ABC" |
        ["\u0ABE"-"\u0AC5"] | ["\u0AC7"-"\u0AC9"] | ["\u0ACB"-"\u0ACD"] | ["\u0B01"-"\u0B03"] | "\u0B3C" |
        ["\u0B3E"-"\u0B43"] | ["\u0B47"-"\u0B48"] | ["\u0B4B"-"\u0B4D"] | ["\u0B56"-"\u0B57"] |
        ["\u0B82"-"\u0B83"] | ["\u0BBE"-"\u0BC2"] | ["\u0BC6"-"\u0BC8"] | ["\u0BCA"-"\u0BCD"] | "\u0BD7" |
        ["\u0C01"-"\u0C03"] | ["\u0C3E"-"\u0C44"] | ["\u0C46"-"\u0C48"] | ["\u0C4A"-"\u0C4D"] |
        ["\u0C55"-"\u0C56"] | ["\u0C82"-"\u0C83"] | ["\u0CBE"-"\u0CC4"] | ["\u0CC6"-"\u0CC8"] |
        ["\u0CCA"-"\u0CCD"] | ["\u0CD5"-"\u0CD6"] | ["\u0D02"-"\u0D03"] | ["\u0D3E"-"\u0D43"] |
        ["\u0D46"-"\u0D48"] | ["\u0D4A"-"\u0D4D"] | "\u0D57" | "\u0E31" | ["\u0E34"-"\u0E3A"] |
        ["\u0E47"-"\u0E4E"] | "\u0EB1" | ["\u0EB4"-"\u0EB9"] | ["\u0EBB"-"\u0EBC"] | ["\u0EC8"-"\u0ECD"] |
        ["\u0F18"-"\u0F19"] | "\u0F35" | "\u0F37" | "\u0F39" | "\u0F3E" | "\u0F3F" | ["\u0F71"-"\u0F84"] |
        ["\u0F86"-"\u0F8B"] | ["\u0F90"-"\u0F95"] | "\u0F97" | ["\u0F99"-"\u0FAD"] | ["\u0FB1"-"\u0FB7"] |
        "\u0FB9" | ["\u20D0"-"\u20DC"] | "\u20E1" | ["\u302A"-"\u302F"] | "\u3099" | "\u309A"
        )
    >
|
    <#UnicodeDigit :
        ["\u0030"-"\u0039"] | ["\u0660"-"\u0669"] | ["\u06F0"-"\u06F9"] | ["\u0966"-"\u096F"] |
        ["\u09E6"-"\u09EF"] | ["\u0A66"-"\u0A6F"] | ["\u0AE6"-"\u0AEF"] | ["\u0B66"-"\u0B6F"] |
        ["\u0BE7"-"\u0BEF"] | ["\u0C66"-"\u0C6F"] | ["\u0CE6"-"\u0CEF"] | ["\u0D66"-"\u0D6F"] |
        ["\u0E50"-"\u0E59"] | ["\u0ED0"-"\u0ED9"] | ["\u0F20"-"\u0F29"]
    >
|
    <#Extender :
        "\u00B7" | "\u02D0" | "\u02D1" | "\u0387" | "\u0640" | "\u0E46" | "\u0EC6" |
        "\u3005" | ["\u3031"-"\u3035"] | ["\u309D"-"\u309E"] | ["\u30FC"-"\u30FE"]
    >
|
    <OR:    "or">
|
    <AND:    "and">
|
    <MOD:    "mod">
|
    <DIV:    "div">
|
    <NODE:    "node">
|
    <TEXT:    "text">
|
    <COMMENT:    "comment">
|
    <PI:    "processing-instruction">

|
    <AXIS_SELF: "self::">
|   <AXIS_CHILD: "child::">
|   <AXIS_PARENT: "parent::">
|   <AXIS_ANCESTOR: "ancestor::">
|   <AXIS_ATTRIBUTE: "attribute::">
|   <AXIS_NAMESPACE: "namespace::">
|   <AXIS_PRECEDING: "preceding::">
|   <AXIS_FOLLOWING: "following::">
|   <AXIS_DESCENDANT: "descendant::">
|   <AXIS_ANCESTOR_OR_SELF: "ancestor-or-self::">
|   <AXIS_FOLLOWING_SIBLING: "following-sibling::">
|   <AXIS_PRECEDING_SIBLING: "preceding-sibling::">
|   <AXIS_DESCENDANT_OR_SELF: "descendant-or-self::">

|   <FUNCTION_LAST: "last">
|   <FUNCTION_POSITION: "position">
|   <FUNCTION_COUNT: "count">
|   <FUNCTION_ID: "id">
|   <FUNCTION_KEY: "key">
|   <FUNCTION_LOCAL_NAME: "local-name">
|   <FUNCTION_NAMESPACE_URI: "namespace-uri">
|   <FUNCTION_NAME: "name">
|   <FUNCTION_STRING: "string">
|   <FUNCTION_CONCAT: "concat">
|   <FUNCTION_STARTS_WITH: "starts-with">
|   <FUNCTION_CONTAINS: "contains">
|   <FUNCTION_SUBSTRING_BEFORE: "substring-before">
|   <FUNCTION_SUBSTRING_AFTER: "substring-after">
|   <FUNCTION_SUBSTRING: "substring">
|   <FUNCTION_STRING_LENGTH: "string-length">
|   <FUNCTION_NORMALIZE_SPACE: "normalize-space">
|   <FUNCTION_TRANSLATE: "translate">
|   <FUNCTION_BOOLEAN: "boolean">
|   <FUNCTION_NOT: "not">
|   <FUNCTION_TRUE: "true">
|   <FUNCTION_FALSE: "false">
|   <FUNCTION_NULL: "null">
|   <FUNCTION_LANG: "lang">
|   <FUNCTION_NUMBER: "number">
|   <FUNCTION_SUM: "sum">
|   <FUNCTION_FLOOR: "floor">
|   <FUNCTION_CEILING: "ceiling">
|   <FUNCTION_ROUND: "round">
|   <FUNCTION_FORMAT_NUMBER: "format-number">
|
    <NCName :
        (<Letter> | ["_"]) ( |  | [".","-","_"] |  | )*
    >
}

// Note: XPath does not have reserved words, so we have to include all these terminals
String NCName() :
{}
{
    (
        NCName_Without_CoreFunctions()
    |   <NODE>
    |   <TEXT>
    |   <COMMENT>
    |   <PI>
    |   <FUNCTION_LAST>
    |   <FUNCTION_POSITION>
    |   <FUNCTION_COUNT>
    |   <FUNCTION_ID>
    |   <FUNCTION_LOCAL_NAME>
    |   <FUNCTION_NAMESPACE_URI>
    |   <FUNCTION_NAME>
    |   <FUNCTION_STRING>
    |   <FUNCTION_CONCAT>
    |   <FUNCTION_STARTS_WITH>
    |   <FUNCTION_CONTAINS>
    |   <FUNCTION_SUBSTRING_BEFORE>
    |   <FUNCTION_SUBSTRING_AFTER>
    |   <FUNCTION_SUBSTRING>
    |   <FUNCTION_STRING_LENGTH>
    |   <FUNCTION_NORMALIZE_SPACE>
    |   <FUNCTION_TRANSLATE>
    |   <FUNCTION_BOOLEAN>
    |   <FUNCTION_NOT>
    |   <FUNCTION_TRUE>
    |   <FUNCTION_FALSE>
    |   <FUNCTION_NULL>
    |   <FUNCTION_LANG>
    |   <FUNCTION_NUMBER>
    |   <FUNCTION_SUM>
    |   <FUNCTION_FLOOR>
    |   <FUNCTION_CEILING>
    |   <FUNCTION_ROUND>
    |   <FUNCTION_KEY>
    |   <FUNCTION_FORMAT_NUMBER>
    )
    {
        return token.image;
    }
}

String NCName_Without_CoreFunctions() :
{}
{
    (
        <NCName>
    |   <OR>
    |   <AND>
    |   <MOD>
    |   <DIV>
    )
    {
        return token.image;
    }
}

int CoreFunctionName() :
{
    int code;
}
{
    (
        <FUNCTION_LAST>             { code = Compiler.FUNCTION_LAST; }
    |   <FUNCTION_POSITION>         { code = Compiler.FUNCTION_POSITION; }
    |   <FUNCTION_COUNT>            { code = Compiler.FUNCTION_COUNT; }
    |   <FUNCTION_ID>               { code = Compiler.FUNCTION_ID; }
    |   <FUNCTION_LOCAL_NAME>       { code = Compiler.FUNCTION_LOCAL_NAME; }
    |   <FUNCTION_NAMESPACE_URI>    { code = Compiler.FUNCTION_NAMESPACE_URI; }
    |   <FUNCTION_NAME>             { code = Compiler.FUNCTION_NAME; }
    |   <FUNCTION_STRING>           { code = Compiler.FUNCTION_STRING; }
    |   <FUNCTION_CONCAT>           { code = Compiler.FUNCTION_CONCAT; }
    |   <FUNCTION_STARTS_WITH>      { code = Compiler.FUNCTION_STARTS_WITH; }
    |   <FUNCTION_CONTAINS>         { code = Compiler.FUNCTION_CONTAINS; }
    |   <FUNCTION_SUBSTRING_BEFORE> { code = Compiler.FUNCTION_SUBSTRING_BEFORE; }
    |   <FUNCTION_SUBSTRING_AFTER>  { code = Compiler.FUNCTION_SUBSTRING_AFTER; }
    |   <FUNCTION_SUBSTRING>        { code = Compiler.FUNCTION_SUBSTRING; }
    |   <FUNCTION_STRING_LENGTH>    { code = Compiler.FUNCTION_STRING_LENGTH; }
    |   <FUNCTION_NORMALIZE_SPACE>  { code = Compiler.FUNCTION_NORMALIZE_SPACE; }
    |   <FUNCTION_TRANSLATE>        { code = Compiler.FUNCTION_TRANSLATE; }
    |   <FUNCTION_BOOLEAN>          { code = Compiler.FUNCTION_BOOLEAN; }
    |   <FUNCTION_NOT>              { code = Compiler.FUNCTION_NOT; }
    |   <FUNCTION_TRUE>             { code = Compiler.FUNCTION_TRUE; }
    |   <FUNCTION_FALSE>            { code = Compiler.FUNCTION_FALSE; }
    |   <FUNCTION_NULL>             { code = Compiler.FUNCTION_NULL; }
    |   <FUNCTION_LANG>             { code = Compiler.FUNCTION_LANG; }
    |   <FUNCTION_NUMBER>           { code = Compiler.FUNCTION_NUMBER; }
    |   <FUNCTION_SUM>              { code = Compiler.FUNCTION_SUM; }
    |   <FUNCTION_FLOOR>            { code = Compiler.FUNCTION_FLOOR; }
    |   <FUNCTION_CEILING>          { code = Compiler.FUNCTION_CEILING; }
    |   <FUNCTION_ROUND>            { code = Compiler.FUNCTION_ROUND; }
    |   <FUNCTION_KEY>              { code = Compiler.FUNCTION_KEY; }
    |   <FUNCTION_FORMAT_NUMBER>    { code = Compiler.FUNCTION_FORMAT_NUMBER; }
    )
    {
        return code;
    }
}

Object QName() :
{String nc1, nc2 = null;}
{
    nc1 = NCName() ( ":" nc2 = NCName() )?
    {
        if (nc2 == null){
            return compiler.qname(null, nc1);
        }
        else {
            return compiler.qname(nc1, nc2);
        }
    }
}

Object QName_Without_CoreFunctions() :
{
    String nc1, nc2 = null;
}
{
    (
            LOOKAHEAD(NCName() ":") nc1 = NCName() ":" nc2 = NCName()
        |
            nc1 = NCName_Without_CoreFunctions()
    )
    {
        if (nc2 == null){
            return compiler.qname(null, nc1);
        }
        else {
            return compiler.qname(nc1, nc2);
        }
    }
}

Object parseExpression() :
{
    Object ex;
}
{
    ex = Expression()
    <EOF>
    {
        return ex;
    }
}

/* ################################################################################### */
/* XSLT Patterns (http://www.w3.org/1999/08/WD-xslt-19990813)                          */
/* ################################################################################### */

/* [XSLT1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern  */

//void Pattern() :
//{}
//{
//        LocationPathPattern() ( <UNION> LocationPathPattern() )* 
//}
//
//
///* [XSLT2] LocationPathPattern ::=
//   '/' RelativePathPattern? | IdKeyPattern (('/' | '//' RelativePathPattern)? | '//'? RelativePathPattern
//*/
//
//void LocationPathPattern() :
//{}
//{
//        <SLASH> ( RelativePathPattern() )?
//    |    (
//        LOOKAHEAD(IdKeyPattern())
//            IdKeyPattern() ( ( <SLASH> | ) RelativePathPattern() )?
//        |    ( <SLASHSLASH> )? RelativePathPattern()
//        )
//}
//
//
//
///* [XSLT3] IdKeyPattern    ::=    'id' '(' Literal ')' | 'key' '(' Literal ',' Literal ')'  */
//
//void IdKeyPattern() :
//{}
//{
//        <ID> "("  ")"
//    |    <KEY>  "("  ","  ")"
//}
//
//
///* [XSLT4] RelativePathPattern    ::=    StepPattern | RelativePathPattern '/' StepPattern
//                           | RelativePathPattern '//' StepPattern
//*/
//void RelativePathPattern() :
//{}
//{
//        StepPattern() ( ( <SLASH>|  ) StepPattern()    )*
//}
//
//
///* [XSLT5]    StepPattern    ::=    AbbreviatedAxisSpecifier NodeTest Predicate*   */
//void StepPattern() :
//{}
//{
//        AbbreviatedAxisSpecifier() NodeTest() (Predicate())*
//}



// See XPath Syntax (http://www.w3.org/TR/xpath )


//void XPath() :
//{}
//{
//    LocationPath()
//    <EOF>
//}


/* [1] LocationPath ::= RelativeLocationPath | AbsoluteLocationPath  */
Object LocationPath() :
{Object ex = null;}
{
    (
        ex = RelativeLocationPath()
    |   ex = AbsoluteLocationPath()
    )
    {
        return ex;
    }
}

/* [2] AbsoluteLocationPath ::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath  */
/* [10]    AbbreviatedAbsoluteLocationPath    ::=    '//' RelativeLocationPath  */

Object AbsoluteLocationPath() :
{
    ArrayList steps = new ArrayList();
}
{
    (
        LOOKAHEAD(LocationStep(steps)) (LocationStep(steps) ( LocationStep(steps) )* )
      | <SLASH>
    )
    {
        return compiler.locationPath(true, steps.toArray());
    }
}

/* [3] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath */

Object RelativeLocationPath() :
{
    ArrayList steps = new ArrayList();
}
{
    (
        NodeTest(steps) ( LocationStep(steps) )*
    )
    {
        return compiler.locationPath(false, steps.toArray());
    }
}

/* [3] RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath */
/* [11]    AbbreviatedRelativeLocationPath    ::=    RelativeLocationPath '//' Step  */


/*--------------------*/
/* 2.1 Location Steps */
/*--------------------*/

/* [4] Step ::= AxisSpecifier NodeTest Predicate*   | AbbreviatedStep  */

void LocationStep(ArrayList steps) :
{
    Object t;
    Object s;
}
{
    (
        <SLASH>
    |   <SLASHSLASH>
        {
            // Abbreviated step: descendant-or-self::node()
            t = compiler.nodeTypeTest(Compiler.NODE_TYPE_NODE);
            steps.add(compiler.step(Compiler.AXIS_DESCENDANT_OR_SELF, t, null));
        }
    )
    NodeTest(steps)
}

/* [7] NodeTest ::= WildcardName | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' */

void NodeTest(ArrayList steps) :
{
    int axis;
    int type = -1;
    String instruction = null;
    Object name = null;
    Object s;
    Object p;
    ArrayList ps = new ArrayList();
}
{
    (
        (
            axis = AxisSpecifier()
            (
                LOOKAHEAD(NodeType() "(" ")") type = NodeType() "(" ")"
            |   LOOKAHEAD(<PI>)  "("  {
                    instruction = unescape(token.image.substring(1, token.image.length() - 1));
                    } ")"
            |   name = WildcardName()
            )
            |   "."
                {
                    axis = Compiler.AXIS_SELF;
                    type = Compiler.NODE_TYPE_NODE;
                }
            | ".."
                {
                    axis = Compiler.AXIS_PARENT;
                    type = Compiler.NODE_TYPE_NODE;
                }
        )
        (
            p = Predicate()
            {
                ps.add(p);
            }
        )*
    )
    {
        if (name != null){
            s = compiler.nodeNameTest(name);
        }
        else if (instruction != null){
            s = compiler.processingInstructionTest(instruction);
        }
        else {
            s = compiler.nodeTypeTest(type);
        }
        steps.add(compiler.step(axis, s, ps.toArray()));
    }
}

/* [5] AxisSpecifier ::=    AxisName '::' | AbbreviatedAxisSpecifier  */

int AxisSpecifier() :
{
    int axis;
}
{
    (
        axis = AxisName()
    |   axis = AbbreviatedAxisSpecifier()
    )
    {
        return axis;
    }
}

/*----------*/
/* 2.2 Axes */
/*----------*/

/* [6] AxisName ::= 'ancestor' | 'ancestor-or-self' | 'attribute'  | 'child' | 'descendant'
                    | 'descendant-or-self' | 'following' | 'following-sibling' | 'namespace'
                       | 'parent' | 'preceding' | 'preceding-sibling' | 'self'
*/

int AxisName() :
{
    int axis = 0;
}
{
    (
            <AXIS_SELF>                 { axis = Compiler.AXIS_SELF; }
        |   <AXIS_CHILD>                { axis = Compiler.AXIS_CHILD; }
        |   <AXIS_PARENT>               { axis = Compiler.AXIS_PARENT; }
        |   <AXIS_ANCESTOR>             { axis = Compiler.AXIS_ANCESTOR; }
        |   <AXIS_ATTRIBUTE>            { axis = Compiler.AXIS_ATTRIBUTE; }
        |   <AXIS_NAMESPACE>            { axis = Compiler.AXIS_NAMESPACE; }
        |   <AXIS_PRECEDING>            { axis = Compiler.AXIS_PRECEDING; }
        |   <AXIS_FOLLOWING>            { axis = Compiler.AXIS_FOLLOWING; }
        |   <AXIS_DESCENDANT>           { axis = Compiler.AXIS_DESCENDANT; }
        |   <AXIS_ANCESTOR_OR_SELF>     { axis = Compiler.AXIS_ANCESTOR_OR_SELF; }
        |   <AXIS_FOLLOWING_SIBLING>    { axis = Compiler.AXIS_FOLLOWING_SIBLING; }
        |   <AXIS_PRECEDING_SIBLING>    { axis = Compiler.AXIS_PRECEDING_SIBLING; }
        |   <AXIS_DESCENDANT_OR_SELF>   { axis = Compiler.AXIS_DESCENDANT_OR_SELF; }
    )
    {
        return axis;
    }
}

/*----------------*/
/* 2.3 Node Tests */
/*----------------*/

/*----------------*/
/* 2.4 Predicates */
/*----------------*/

/* [8] Predicate ::= '[' PredicateExpr ']'  */
/* [9] PredicateExpr ::=  Expr  */

Object Predicate() :
{
    Object ex;
}
{
    "[" ex = Expression() "]"
    {
        return ex;
    }
}

/* [12]    AbbreviatedStep    ::=    '.'  | '..'  */

/* [13]    AbbreviatedAxisSpecifier    ::=    '@'? */
int AbbreviatedAxisSpecifier() :
{
    int axis = Compiler.AXIS_CHILD;
}
{
    ( "@" {axis = Compiler.AXIS_ATTRIBUTE; } )?

    {
        return axis;
    }
}

/*---------------*/
/* 3 Expressions */
/*---------------*/

/*------------*/
/* 3.1 Basics */
/*------------*/

/*
The effect of the grammar is that the order of precedence is (lowest precedence first):
    or
    and
    =, !=
    <=, <, >=, >
and all operators are left associative.
For example, 3 > 2 > 1 is equivalent to (3 > 2) > 1, which evaluates to false.
*/

/* [14] Expr ::= OrExpr */
Object Expression() :
{Object ex;}
{
    ex = OrExpr()
    {
        return ex;
    }
}

/* [15] PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall */

Object PrimaryExpr() :
{
    Object ex = null;
}
{
    (
         ex = VariableReference()
    |    "(" ex = Expression() ")"
    |    <Literal>  { ex = compiler.literal(unescape(token.image.substring(1, token.image.length() - 1))); }
    |    <Number>   { ex = compiler.number(token.image); }
    |    LOOKAHEAD(CoreFunctionName() "(") ex = CoreFunctionCall()
    |    ex = FunctionCall()
    )
    {
        return ex;
    }
}

/*--------------------*/
/* 3.2 Function Calls */
/*--------------------*/

/* [16]    FunctionCall    ::=    FunctionName '(' ( Argument ( ',' Argument)*)? ')'  */
Object FunctionCall() :
{
    Object name;
    ArrayList args;
}
{
    name = FunctionName() args = ArgumentList()
    {
        if (args == null){
            return compiler.function(name, null);
        }
        else {
            return compiler.function(name, args.toArray());
        }
    }
}

Object CoreFunctionCall() :
{
    int code = 0;
    ArrayList args;
}
{
    (
        code = CoreFunctionName()
    )
    args = ArgumentList()
    {
        if (args == null){
            return compiler.function(code, null);
        }
        else {
            return compiler.function(code, args.toArray());
        }
    }
}

ArrayList ArgumentList() :
{
    ArrayList args = null;
    Object arg;
}
{
    "("
        (
            arg  = Argument() { args = new ArrayList(); args.add(arg); }
            (
                "," arg = Argument() { args.add(arg); }
            )*
        )?
    ")"
    {
        return args;
    }
}

/* [17]    Argument    ::=    Expr */
Object Argument() :
{
    Object ex;
}
{
    ex = Expression()
    {
        return ex;
    }
}

/*---------------*/
/* 3.3 Node-sets */
/*---------------*/

/* [18] UnionExpr    ::=    PathExpr | UnionExpr '|' PathExpr */
Object UnionExpr() :
{
    Object ex, r;
    ArrayList list = null;
}
{
    (
        ex = PathExpr() (
            <UNION> r = PathExpr()
            {
                if (list == null){
                    list = new ArrayList();
                    list.add(ex);
                }
                list.add(r);
            }
        )*
    )
    {
        if (list != null){
            ex = compiler.union(list.toArray());
        }
        return ex;
    }
}


/* [19] PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath | FilterExpr '//' RelativeLocationPath  */

Object PathExpr() :
{
    Object ex = null;
    Object[] steps;
}
{
    (
        // Reason for LOOKAHEAD:
        // foo:bar()  - filter path
        // foo:bar    - location path

        LOOKAHEAD(PrimaryExpr()) ex = FilterExpr()
    |   ex = LocationPath()
    )
    {
        return ex;
    }
}

/* [20]    FilterExpr    ::=    PrimaryExpr    | FilterExpr Predicate */
Object FilterExpr() :
{
    Object ex, p;
    ArrayList ps = new ArrayList();
    boolean path = false;
    ArrayList steps = new ArrayList();
}
{
    (
        ex = PrimaryExpr()
        (
            p = Predicate()
            {
                path = true;
                ps.add(p);
            }
        )*
        (
            LocationStep(steps)
            {
                path = true;
            }
        )*
    )
    {
        if (path){
            return compiler.expressionPath(ex, ps.toArray(), steps.toArray());
        }
        else {
            return ex;
        }
    }
}



/*--------------*/
/* 3.4 Booleans */
/*--------------*/

/* [21] OrExpr    ::=    AndExpr | OrExpr 'or' AndExpr */
Object OrExpr() :
{
    Object ex, r;
    ArrayList list = null;
}
{
    (
        ex = AndExpr() (
            <OR> r = AndExpr()
            {
                if (list == null){
                    list = new ArrayList();
                    list.add(ex);
                }
                list.add(r);
            }
        )*
    )
    {
        if (list != null){
            ex = compiler.or(list.toArray());
        }
        return ex;
    }
}

/* [22] AndExpr    ::=    EqualityExpr  | AndExpr 'and' EqualityExpr  */
Object AndExpr() :
{
    Object ex, r;
    ArrayList list = null;
}
{
    (
        ex = EqualityExpr() (
            <AND> r = EqualityExpr()
            {
                if (list == null){
                    list = new ArrayList();
                    list.add(ex);
                }
                list.add(r);
            }
        )*
    )
    {
        if (list != null){
            ex = compiler.and(list.toArray());
        }
        return ex;
    }
}

/* [23] EqualityExpr    ::=    RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr */
Object EqualityExpr() :
{Object ex, r;}
{
    (
        ex = RelationalExpr() ((
             <EQ>  r = RelationalExpr() { ex = compiler.equal(ex, r); }
           | <NEQ> r = RelationalExpr() { ex = compiler.notEqual(ex, r); }
        ))*
    )
    {
        return ex;
    }
}


/* [24] RelationalExpr    ::=    AdditiveExpr | RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr
                       | RelationalExpr '<=' AdditiveExpr  | RelationalExpr '>=' AdditiveExpr */
Object RelationalExpr() :
{Object ex, r;}
{
    (
        ex = AdditiveExpr()  ((
            <LT>   r = AdditiveExpr() { ex = compiler.lessThan(ex, r); }
          | <GT>   r = AdditiveExpr() { ex = compiler.greaterThan(ex, r); }
          | <LTE>  r = AdditiveExpr() { ex = compiler.lessThanOrEqual(ex, r); }
          | <GTE>  r = AdditiveExpr() { ex = compiler.greaterThanOrEqual(ex, r); }
        ))*
    )
    {
        return ex;
    }
}

/*-------------*/
/* 3.5 Numbers */
/*-------------*/

/* [25] AdditiveExpr ::= MultiplicativeExpr  | AdditiveExpr '+' MultiplicativeExpr  | AdditiveExpr '-' MultiplicativeExpr  */
Object AdditiveExpr() :
{
    Object ex, r;
    ArrayList list = null;
}
{
    (
        ex = SubtractiveExpr() ((
            <PLUS>  r = SubtractiveExpr()
            {
                if (list == null){
                    list = new ArrayList();
                    list.add(ex);
                }
                list.add(r);
            }
        ))*
    )
    {
        if (list != null){
            ex = compiler.sum(list.toArray());
        }
        return ex;
    }
}

Object SubtractiveExpr() :
{
    Object ex, r = null;
}
{
    (
        ex = MultiplicativeExpr() (
            <MINUS> r = MultiplicativeExpr() { ex = compiler.minus(ex, r); }
        )*
    )
    {
        return ex;
    }
}

/* [26] MultiplicativeExpr ::= UnaryExpr | MultiplicativeExpr MultiplyOperator UnaryExpr
            | MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr  */
Object MultiplicativeExpr() :
{
    Object ex, r;
}
{
    (
        ex = UnaryExpr() ( (
            "*"   r = UnaryExpr() { ex = compiler.multiply(ex, r); }
        |   <DIV> r = UnaryExpr() { ex = compiler.divide(ex, r); }
        |   <MOD> r = UnaryExpr() { ex = compiler.mod(ex, r); }
        ) )*
    )
    {
        return ex;
    }
}

/* [27]    UnaryExpr    ::=    UnionExpr  | '-' UnaryExpr  */
Object UnaryExpr() :
{
    Object ex;
}
{
    (
        ex = UnionExpr()
    |    <MINUS> ex = UnaryExpr() { ex = compiler.minus(ex);}
    )
    {
        return ex;
    }
}

/*-------------*/
/* 3.6 Strings */
/*-------------*/

/*----------------------------------*/
/* 3.7 Expression Lexical Structure */
/*----------------------------------*/
/*
The following special tokenization rules must be applied in the order
specified to disambiguate the grammar:

1. If there is a preceding token and the preceding token is not one of
   @, ::, (, [, , or an Operator,
   then a * must be recognized as a MultiplyOperator and an NCName must
   be recognized as an OperatorName.

2. If the character following an NCName (possibly after intervening ExprWhitespace)
   is (, then the token must be recognized as a NodeType or a FunctionName.

3. If the two characters following an NCName (possibly after intervening ExprWhitespace)
   are ::, then the token must be recognized as an AxisName.

4. Otherwise, the token must not be recognized as a MultiplyOperator, an OperatorName,
   a NodeType, a FunctionName, or an AxisName.
*/

/*
[28]    ExprToken    ::=    '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
   | WildcardName  | NodeType  | Operator  | FunctionName  | AxisName  | Literal
   | Number  | VariableReference
*/
/* [34]    MultiplyOperator    ::=    '*'  */

/* [35]    FunctionName    ::=    QName - NodeType   */
Object FunctionName() :
{
    Object qname;
}
{
    qname = QName_Without_CoreFunctions()
    {
        return qname;
    }
}

/* [36]    VariableReference    ::=    '$' QName  */

Object VariableReference() :
{
    Object ex;
}
{
    <VARIABLE> ex = QName()
    {
        return compiler.variableReference(ex);
    }
}

/* [37]    WildcardName    ::=    '*'     | NCName ':' '*'     | QName  */
Object WildcardName() :
{
    Object qn;
    String nc1, nc2 = null;
}
{
    (
        ("*" | NCName()) { nc1 = token.image; }
        (":" ("*" | NCName()) {nc2 = token.image;} )?
    )
    {
        if (nc2 != null){
            qn = compiler.qname(nc1, nc2);
        }
        else {
            qn = compiler.qname(null, nc1);
        }
        return qn;
    }
}

/* [38]    NodeType    ::=    'comment' | 'text'  | 'processing-instruction'  | 'node'  */

int NodeType() :
{
    int type;
}
{
    (
         <TEXT>     { type = Compiler.NODE_TYPE_TEXT; }
    |    <NODE>     { type = Compiler.NODE_TYPE_NODE; }
    |    <COMMENT>  { type = Compiler.NODE_TYPE_COMMENT; }
    |    <PI>       { type = Compiler.NODE_TYPE_PI; }
    )
    {
        return type;
    }
}

Other Commons JXPath examples (source code examples)

Here is a short list of links related to this Commons JXPath XPath.jj source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.