/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 * @author G. Todd Miller
 *
 */

package org.apache.xalan.xsltc.compiler;

import java.util.Stack;
import java.util.Vector;
import java.io.StringReader;
import java_cup.runtime.*;

import org.apache.xalan.xsltc.dom.Axis;
import org.apache.xalan.xsltc.runtime.Operators;
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;

parser code {:
    /**
     * Used by function calls with no args.
     */
    static public final Vector EmptyArgs = new Vector(0);

    /**
     * Reference to non-existing variable.
     */
    static public final VariableRef DummyVarRef = null;

    /**
     * Reference to the Parser class.
     */
    private Parser _parser;
    private XSLTC  _xsltc;

    /**
     * Line number where this expression/pattern was declared.
     */
    private int _lineNumber = 0;

    /**
     * Reference to the symbol table.
     */
    public SymbolTable _symbolTable;

    public XPathParser(Parser parser) {
        _parser = parser;
	_xsltc = parser.getXSLTC();
        _symbolTable = parser.getSymbolTable();
    }

    public int getLineNumber() {
        return _lineNumber;
    }

    public QName getQName(String name) {
          return _parser.getQName(name);
    }    

    public void setMultiDocument(boolean flag) {
          _xsltc.setMultiDocument(flag);
    }

    public void setCallsNodeset(boolean flag) {
          _xsltc.setCallsNodeset(flag);
    }

    public int findNodeType(int axis, Object test) {

	if (test == null) {  // *
            if (axis == Axis.ATTRIBUTE)
                return NodeTest.ATTRIBUTE;
            else if (axis == Axis.NAMESPACE)
                return -1;
            else
                return NodeTest.ELEMENT;
        }
        else if (test instanceof Integer) {
            return ((Integer)test).intValue();
        }
        else {
	    QName name = (QName)test;

	    if (axis == Axis.NAMESPACE) {
                if (name.toString().equals("*"))
                    return -1;
                else
                    return _xsltc.registerNamespace(name);
            }

            if (name.getPrefix() == null || name.getNamespace() == null) {
                final String local = name.getLocalPart();
	        if (local.equals("*")) {
                    if (axis == Axis.ATTRIBUTE)
                        return(NodeTest.ATTRIBUTE);
                    else
                        return(NodeTest.ELEMENT);
                }
                else if (local.equals("@*"))
                    return(NodeTest.ATTRIBUTE);
                name = new QName(null,null,local);
            }
            if (axis == Axis.ATTRIBUTE) {
                return _xsltc.registerAttribute(name);
            }
            else {
		return _xsltc.registerElement(name);
            }
        }
    }

    /**
     * Parse the expression passed to the current scanner. If this
     * expression contains references to local variables and it will be 
     * compiled in an external module (not in the main class) request 
     * the current template to create a new variable stack frame.
     *
     * @param lineNumber Line where the current expression is defined.
     * @param external   Set to <tt>true</tt> if this expression is
     *                   compiled in a separate module.
     * 
     */
    public Symbol parse(int lineNumber) throws Exception {
        try {
	    _lineNumber = lineNumber;
	    return super.parse();
        }
        catch (IllegalCharException e) {
            ErrorMsg err = new ErrorMsg(ErrorMsg.ILLEGAL_CHAR_ERR,
                                        lineNumber, e.getMessage());
            _parser.reportError(Constants.FATAL, err);
        }
        return null;
    }

    /**
     * Lookup a variable or parameter in the symbol table given its name. 
     *
     * @param name Name of the symbol being looked up.
     */
    final SyntaxTreeNode lookupName(QName name) {
        // Is it a local var or param ?
        final SyntaxTreeNode result = _parser.lookupVariable(name);
	if (result != null)
            return(result);
        else
	    return(_symbolTable.lookupName(name));
    }

    public final void addError(ErrorMsg error) {
	_parser.reportError(Constants.ERROR, error);
    } 
           
    public void report_error(String message, Object info) {
        // empty
    }

    public void report_fatal_error(String message, Object info) {
        // empty
    }
:}

terminal SLASH, DOT, LBRACK, RBRACK, VBAR, LPAREN, RPAREN, STAR, COMMA;
terminal DOLLAR, ATSIGN;
terminal DDOT, DCOLON, DSLASH;
terminal EQ, NE;
terminal LT, GT, LE, GE;
terminal PLUS, MINUS, DIV, MOD;
terminal String Literal;
terminal String QNAME;
terminal ID, KEY, TEXT, NODE, OR, AND, COMMENT, PI, PIPARAM, PRECEDINGSIBLING;
terminal SELF, PARENT, CHILD, ATTRIBUTE, ANCESTOR, ANCESTORORSELF, DESCENDANT; 
terminal DESCENDANTORSELF, FOLLOWING, FOLLOWINGSIBLING, NAMESPACE, PRECEDING;
terminal Double REAL;
terminal Long INT;
terminal PATTERN, EXPRESSION;

non terminal SyntaxTreeNode TopLevel;
    
non terminal Expression Expr, Argument, LocationPath;
non terminal Expression Predicate, FilterExpr, Step;
non terminal Expression OrExpr, AndExpr, EqualityExpr;
non terminal Expression RelationalExpr, AdditiveExpr;
non terminal Expression MultiplicativeExpr, UnaryExpr;
non terminal Expression VariableReference, FunctionCall;
non terminal Expression PrimaryExpr, UnionExpr, PathExpr, AbbreviatedStep;
non terminal Expression RelativeLocationPath, AbbreviatedRelativeLocationPath;
non terminal Expression AbsoluteLocationPath, AbbreviatedAbsoluteLocationPath;

non terminal Object NodeTest, NameTest;

non terminal IdKeyPattern IdKeyPattern;
non terminal Pattern Pattern;
non terminal Pattern LocationPathPattern;
non terminal StepPattern ProcessingInstructionPattern;
non terminal RelativePathPattern RelativePathPattern;
non terminal StepPattern StepPattern;
non terminal Object NodeTestPattern, NameTestPattern;

non terminal Vector Predicates, NonemptyArgumentList;
non terminal QName QName, FunctionName, VariableName;
non terminal Integer AxisName, AxisSpecifier;
non terminal Integer ChildOrAttributeAxisSpecifier;

precedence left VBAR;
precedence left OR;
precedence left AND;
precedence nonassoc EQ, NE;
precedence left LT, GT, LE, GE;
    
precedence left PLUS, MINUS;
precedence left DIV, MOD, STAR;
precedence left DOLLAR;
precedence left ATSIGN;
precedence right DCOLON;

start with TopLevel;

TopLevel ::= PATTERN Pattern:pattern
            {: RESULT = pattern; :}

            | EXPRESSION Expr:expr
            {: RESULT = expr; :};

/* --------------------------- Patterns ----------------------------------- */

Pattern ::= LocationPathPattern:lpp
            {: RESULT = lpp; :}

            | LocationPathPattern:lpp VBAR Pattern:p
            {: RESULT = new AlternativePattern(lpp, p);  :};

LocationPathPattern ::= SLASH
            {: RESULT = new AbsolutePathPattern(null); :}

            | SLASH RelativePathPattern:rpp
            {: RESULT = new AbsolutePathPattern(rpp); :}

            | ProcessingInstructionPattern:pip
            {: RESULT = pip; :}

	    | ProcessingInstructionPattern:pip Predicates:pp
            {: RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :}

            | IdKeyPattern:ikp
            {: RESULT = ikp; :}

            | IdKeyPattern:ikp SLASH RelativePathPattern:rpp
            {: RESULT = new ParentPattern(ikp, rpp); :}

            | IdKeyPattern:ikp DSLASH RelativePathPattern:rpp
            {: RESULT = new AncestorPattern(ikp, rpp); :}

            | DSLASH RelativePathPattern:rpp
            {: RESULT = new AncestorPattern(rpp); :}

            | RelativePathPattern:rpp
            {: RESULT = rpp; :};

IdKeyPattern ::= ID LPAREN Literal:l RPAREN
            {: RESULT = new IdPattern(l); :}

            | KEY LPAREN Literal:l1 COMMA Literal:l2 RPAREN
            {: RESULT = new KeyPattern(l1, l2); :};

ProcessingInstructionPattern ::= PIPARAM LPAREN Literal:l RPAREN
            {: RESULT = new ProcessingInstructionPattern(l); :};

RelativePathPattern ::= StepPattern:sp
            {: RESULT = sp; :}

            | StepPattern:sp SLASH RelativePathPattern:rpp
            {: RESULT = new ParentPattern(sp, rpp); :}

            | StepPattern:sp DSLASH RelativePathPattern:rpp
            {: RESULT = new AncestorPattern(sp, rpp); :};

StepPattern ::= NodeTestPattern:nt
            {: RESULT = new StepPattern(Axis.CHILD,
                                        parser.findNodeType(Axis.CHILD, nt),
                                        null);
            :}

            | NodeTestPattern:nt Predicates:pp
            {: RESULT = new StepPattern(Axis.CHILD,
                                        parser.findNodeType(Axis.CHILD, nt),
                                        pp);
            :}

            | ChildOrAttributeAxisSpecifier:axis NodeTestPattern:nt
            {: RESULT=new StepPattern(axis.intValue(),
                                      parser.findNodeType(axis.intValue(), nt),
                                      null);
            :}

	    | ChildOrAttributeAxisSpecifier:axis
		  NodeTestPattern:nt Predicates:pp
            {: RESULT = new StepPattern(axis.intValue(),
                                        parser.findNodeType(axis.intValue(),nt),
                                        pp);
            :};

NodeTestPattern ::= NameTestPattern:nt
            {: RESULT = nt; :}

            | NODE
            {: RESULT = new Integer(NodeTest.ANODE); :} 

            | TEXT
            {: RESULT = new Integer(NodeTest.TEXT); :}

            | COMMENT
            {: RESULT = new Integer(NodeTest.COMMENT); :}

            | PI
            {: RESULT = new Integer(NodeTest.PI); :};

NameTestPattern ::= STAR
            {: RESULT = null; :}

            | QName:qn
            {: RESULT = qn; :};

ChildOrAttributeAxisSpecifier ::= ATSIGN
            {: RESULT = new Integer(Axis.ATTRIBUTE); :}

            | CHILD DCOLON
            {: RESULT = new Integer(Axis.CHILD); :}

            | ATTRIBUTE DCOLON
            {: RESULT = new Integer(Axis.ATTRIBUTE); :};

Predicates ::= Predicate:p
            {: 
		Vector temp = new Vector();
		temp.addElement(p);
		RESULT = temp;     
            :}

            | Predicate:p Predicates:pp
            {: pp.insertElementAt(p, 0); RESULT = pp; :}; 

Predicate ::=  LBRACK Expr:e RBRACK
	    {:
		RESULT = new Predicate(e);
	    :};

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

Expr ::= OrExpr:ex
        {: RESULT = ex; :};

OrExpr ::= AndExpr:ae
        {: RESULT = ae; :}

        | OrExpr:oe OR AndExpr:ae
        {: RESULT = new LogicalExpr(LogicalExpr.OR, oe, ae); :};

AndExpr ::= EqualityExpr:e
        {: RESULT = e; :}

        | AndExpr:ae AND EqualityExpr:ee
        {: RESULT = new LogicalExpr(LogicalExpr.AND, ae, ee); :};
    
EqualityExpr ::= RelationalExpr:re
        {: RESULT = re; :}

        | EqualityExpr:ee EQ RelationalExpr:re
        {: RESULT = new EqualityExpr(Operators.EQ, ee, re); :}

        | EqualityExpr:ee NE RelationalExpr:re
        {: RESULT = new EqualityExpr(Operators.NE, ee, re); :};

RelationalExpr ::= AdditiveExpr:ae
        {: RESULT = ae; :}

        | RelationalExpr:re LT AdditiveExpr:ae
        {: RESULT = new RelationalExpr(Operators.LT, re, ae); :}

        | RelationalExpr:re GT AdditiveExpr:ae
        {: RESULT = new RelationalExpr(Operators.GT, re, ae); :}

        | RelationalExpr:re LE AdditiveExpr:ae
        {: RESULT = new RelationalExpr(Operators.LE, re, ae); :}

        | RelationalExpr:re GE AdditiveExpr:ae
        {: RESULT = new RelationalExpr(Operators.GE, re, ae); :};

AdditiveExpr ::= MultiplicativeExpr:me
        {: RESULT = me; :}

        | AdditiveExpr:ae PLUS  MultiplicativeExpr:me
        {: RESULT = new BinOpExpr(BinOpExpr.PLUS, ae, me); :}

        | AdditiveExpr:ae MINUS MultiplicativeExpr:me
        {: RESULT = new BinOpExpr(BinOpExpr.MINUS, ae, me); :};

MultiplicativeExpr ::= UnaryExpr:ue
        {: RESULT = ue; :}

        | MultiplicativeExpr:me STAR UnaryExpr:ue
        {: RESULT = new BinOpExpr(BinOpExpr.TIMES, me, ue); :}

        | MultiplicativeExpr:me DIV UnaryExpr:ue
        {: RESULT = new BinOpExpr(BinOpExpr.DIV, me, ue); :}

        | MultiplicativeExpr:me MOD UnaryExpr:ue
        {: RESULT = new BinOpExpr(BinOpExpr.MOD, me, ue); :};

UnaryExpr ::= UnionExpr:ue
        {: RESULT = ue; :}

        | MINUS UnaryExpr:ue
        {: RESULT = new UnaryOpExpr(ue); :};

UnionExpr ::= PathExpr:pe
        {: RESULT = pe; :}
 
        | PathExpr:pe VBAR UnionExpr:rest
        {: RESULT = new UnionPathExpr(pe, rest); :};

PathExpr ::= LocationPath:lp
        {: RESULT = lp; :}

        | FilterExpr:fexp
        {: RESULT = fexp; :}

        | FilterExpr:fexp SLASH RelativeLocationPath:rlp
        {: RESULT = new FilterParentPath(fexp, rlp); :}

        | FilterExpr:fexp DSLASH RelativeLocationPath:rlp
        {:
           // Expand '//' into '/descendant-or-self::node()/'
           Step step = new Step(Axis.DESCENDANTORSELF, NodeTest.ANODE, null);
           FilterParentPath fpp = new FilterParentPath(fexp, step);
           fpp = new FilterParentPath(fpp, rlp);
           if (!(fexp instanceof KeyCall))
               fpp.setDescendantAxis();
           RESULT = fpp;
        :};

LocationPath ::= RelativeLocationPath:rlp
        {: RESULT = rlp; :}

        | AbsoluteLocationPath:alp
        {: RESULT = alp; :};

RelativeLocationPath ::= Step:step
        {: RESULT = step; :}

        | RelativeLocationPath:rlp SLASH Step:step
        {:     
        if (rlp instanceof Step && ((Step) rlp).isAbbreviatedDot()) {
              RESULT = step;       // Remove './' from the middle
        }
        else if (((Step) step).isAbbreviatedDot()) {
              RESULT = rlp;        // Remove '/.' from the end
        }
        else {
             RESULT =
                new ParentLocationPath((RelativeLocationPath) rlp, step); 
           }
        :}

        | AbbreviatedRelativeLocationPath:arlp
        {: RESULT = arlp; :};

AbsoluteLocationPath ::= SLASH
        {: RESULT = new AbsoluteLocationPath(); :}

        | SLASH RelativeLocationPath:rlp
        {: RESULT = new AbsoluteLocationPath(rlp); :}

        | AbbreviatedAbsoluteLocationPath:aalp
        {: RESULT = aalp; :};

AbbreviatedRelativeLocationPath ::= RelativeLocationPath:rlp DSLASH Step:step
        {: 
	   final Step right  = (Step)step;
           final int  axis   = right.getAxis();
           final int  type   = right.getNodeType();
           final Vector predicates = right.getPredicates();

           if ((axis == Axis.CHILD) && (type != NodeTest.ATTRIBUTE)) {
               // Compress './/child:E' into 'descendant::E' - if possible
               if (predicates == null) {
                   right.setAxis(Axis.DESCENDANT);
                   if (rlp instanceof Step && ((Step)rlp).isAbbreviatedDot()) {
	               RESULT = right;
                   }
                   else {
                       // Expand 'rlp//child::E' into 'rlp/descendant::E'
                       RelativeLocationPath left = (RelativeLocationPath)rlp;
	               RESULT = new ParentLocationPath(left, right);
                   }
               }
               else {
                   // Expand './/step' -> 'descendant-or-self::*/step'
                   if (rlp instanceof Step && ((Step)rlp).isAbbreviatedDot()) {
                       Step left = new Step(Axis.DESCENDANTORSELF, -1, null);
                       RESULT = new ParentLocationPath(left, right);
                   }
                   else {
                       // Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step'
                       RelativeLocationPath left = (RelativeLocationPath)rlp;
                       Step mid = new Step(Axis.DESCENDANTORSELF, -1, null);
                       ParentLocationPath ppl = new ParentLocationPath(mid, right);
                       RESULT = new ParentLocationPath(left, ppl);
                   }
               }
           }
           else if ((axis == Axis.ATTRIBUTE) || (type == NodeTest.ATTRIBUTE)) {
               // Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step'
               RelativeLocationPath left = (RelativeLocationPath)rlp;
               Step middle = new Step(Axis.DESCENDANTORSELF, -1, null);
               ParentLocationPath ppl = new ParentLocationPath(middle, right);
               RESULT = new ParentLocationPath(left, ppl);
	   }
	   else {
	       // Expand 'rlp//step' -> 'rlp/descendant-or-self::node()/step'
               RelativeLocationPath left = (RelativeLocationPath)rlp;
	       Step middle = new Step(Axis.DESCENDANTORSELF, -1, null); 
               ParentLocationPath ppl = new ParentLocationPath(middle, right);
	       RESULT = new ParentLocationPath(left, ppl);
	   }
        :};


AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp
        {:

	AbsoluteLocationPath alp = null;

        Step left = new Step(Axis.DESCENDANTORSELF, -1, null);

	if (rlp instanceof ParentLocationPath) {
	    ParentLocationPath plp = new ParentLocationPath(left, rlp);
	    alp = new AbsoluteLocationPath(plp);
	}
	else if (rlp instanceof Step) {
            Step right = (Step)rlp;
            alp = new AbsoluteLocationPath(new ParentLocationPath(left, right));
	}
	else {
            // Don't think we'll ever get here...
            Step right = new Step(Axis.CHILD, NodeTest.ELEMENT, null);
	    alp = new AbsoluteLocationPath(new ParentLocationPath(left, right));
        }

	RESULT = new FilteredAbsoluteLocationPath(alp);
	:};



Step ::= NodeTest:ntest
        {:
            if (ntest instanceof Step) {
                RESULT = (Step)ntest;
            }
            else {
		RESULT = new Step(Axis.CHILD,
                             parser.findNodeType(Axis.CHILD, ntest),
                             null);
            }
        :}

        | NodeTest:ntest Predicates:pp
        {: 
            if (ntest instanceof Step) {
                Step step = (Step)ntest;
                step.addPredicates(pp);
                RESULT = (Step)ntest;
            }
            else {
                RESULT = new Step(Axis.CHILD,
                             parser.findNodeType(Axis.CHILD, ntest), pp);
            }
        :}

        | AxisSpecifier:axis NodeTest:ntest Predicates:pp
        {: RESULT = new Step(axis.intValue(),
                             parser.findNodeType(axis.intValue(), ntest),
                             pp);
        :}

        | AxisSpecifier:axis NodeTest:ntest
        {: RESULT = new Step(axis.intValue(),
                             parser.findNodeType(axis.intValue(), ntest),
                             null);
        :}

        | AbbreviatedStep:abbrev
        {: RESULT = abbrev; :};

AxisSpecifier ::= AxisName:an DCOLON
        {: RESULT = an; :}

        | ATSIGN
        {: RESULT = new Integer(Axis.ATTRIBUTE); :};

AxisName ::=    ANCESTOR
        {: RESULT = new Integer(Axis.ANCESTOR); :}

        | ANCESTORORSELF
        {: RESULT = new Integer(Axis.ANCESTORORSELF); :}

        | ATTRIBUTE
        {: RESULT = new Integer(Axis.ATTRIBUTE); :}

        | CHILD
        {: RESULT = new Integer(Axis.CHILD); :}

        | DESCENDANT
        {: RESULT = new Integer(Axis.DESCENDANT); :}

        | DESCENDANTORSELF
        {: RESULT = new Integer(Axis.DESCENDANTORSELF); :}

        | FOLLOWING
        {: RESULT = new Integer(Axis.FOLLOWING); :}

        | FOLLOWINGSIBLING
        {: RESULT = new Integer(Axis.FOLLOWINGSIBLING); :}

        | NAMESPACE
        {: RESULT = new Integer(Axis.NAMESPACE); :}

        | PARENT
        {: RESULT = new Integer(Axis.PARENT); :}

        | PRECEDING
        {: RESULT = new Integer(Axis.PRECEDING); :}

        | PRECEDINGSIBLING
        {: RESULT = new Integer(Axis.PRECEDINGSIBLING); :}

        | SELF
        {: RESULT = new Integer(Axis.SELF); :};

AbbreviatedStep ::= DOT
        {: RESULT = new Step(Axis.SELF, NodeTest.ANODE, null); :}

        | DDOT
        {: RESULT = new Step(Axis.PARENT, NodeTest.ANODE, null); :};

FilterExpr ::=  PrimaryExpr:primary
        {: RESULT = primary; :}

        | PrimaryExpr:primary Predicates:pp
        {: RESULT = new FilterExpr(primary, pp); :};

PrimaryExpr ::= VariableReference:vr
        {: RESULT = vr; :}

        | LPAREN Expr:ex RPAREN
        {: RESULT = ex; :}

	| Literal:string
	{: 
	/*
	* If the string appears to have the syntax of a QName, store 
	* namespace info in the literal expression. This is used for
	* element-available and function-available functions.
	*/
	final int index = string.lastIndexOf(':');
	final String prefix = index >= 0
                                     ? string.substring(0, index)
                                     : Constants.EMPTYSTRING;
	String namespace = parser._symbolTable.lookupNamespace(prefix);
	RESULT = namespace == null
                         ? new LiteralExpr(string)
                         : new LiteralExpr(string, namespace); 
	:}

        | INT:num
        {: 
	   // bug fix 3592, num comes in as a Long rather than an Integer
	   //               see xpath.lex, {Digit}+ rule. 
	   long value = num.longValue();
	   if ((value < Integer.MIN_VALUE) || (value > Integer.MAX_VALUE)) {
		RESULT = new LongExpr(num.longValue());
	   }
	   else {
               if (num.doubleValue() == -0)
                   RESULT = new RealExpr(num.doubleValue());
               else if (num.intValue() == 0)
                   RESULT = new IntExpr(num.intValue());
               else if (num.doubleValue() == 0.0)
                   RESULT = new RealExpr(num.doubleValue());
               else
                   RESULT = new IntExpr(num.intValue());
	   }
        :}

        | REAL:num
        {: RESULT = new RealExpr(num.doubleValue()); :}

        | FunctionCall:fc
        {: RESULT = fc; :};

VariableReference ::= DOLLAR VariableName:varName
        {: 
            // An empty qname prefix for a variable or parameter reference
            // should map to the null namespace and not the default URI.
            SyntaxTreeNode node = parser.lookupName(varName);

            if (node != null) {
                if (node instanceof Variable) {
                    RESULT = new VariableRef((Variable)node);
                }
                else if (node instanceof Param) {
                    RESULT = new ParameterRef((Param)node);
                } 
                else {
                    RESULT = new UnresolvedRef(varName);
                }
            }

            if (node == null) {
                RESULT = new UnresolvedRef(varName);
            }

        :};

FunctionCall ::= FunctionName:fname LPAREN RPAREN
        {: 

          if (fname == parser.getQName("current")) {
            RESULT = new CurrentCall(fname);
	  }
          else if (fname == parser.getQName("number")) {
            RESULT = new NumberCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQName("string")) {
            RESULT = new StringCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQName("concat")) {
            RESULT = new ConcatCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQName("true")) {
            RESULT = new BooleanExpr(true);
	  }
          else if (fname == parser.getQName("false")) {
            RESULT = new BooleanExpr(false);
	  }
          else if (fname == parser.getQName("name")) {
            RESULT = new NameCall(fname);
	  }
          else if (fname == parser.getQName("generate-id")) {
            RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQName("string-length")) {
            RESULT = new StringLengthCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQName("position")) {
            RESULT = new PositionCall(fname);
	  }
          else if (fname == parser.getQName("last")) {
            RESULT = new LastCall(fname);
	  }
          else if (fname == parser.getQName("local-name")) {
            RESULT = new LocalNameCall(fname);
	  }
          else if (fname == parser.getQName("namespace-uri")) {
            RESULT = new NamespaceUriCall(fname);
	  }
          else {
            RESULT = new FunctionCall(fname, parser.EmptyArgs);
	  }
        :}

        | FunctionName:fname LPAREN NonemptyArgumentList:argl RPAREN
        {:
          if (fname == parser.getQName("concat")) {
            RESULT = new ConcatCall(fname, argl);
	  }
          else if (fname == parser.getQName("number")) {
            RESULT = new NumberCall(fname, argl);
	  }
          else if (fname == parser.getQName("document")) {
	    parser.setMultiDocument(true);
            RESULT = new DocumentCall(fname, argl);
	  }
          else if (fname == parser.getQName("string")) {
            RESULT = new StringCall(fname, argl);
	  }
          else if (fname == parser.getQName("boolean")) {
            RESULT = new BooleanCall(fname, argl);
	  }
          else if (fname == parser.getQName("name")) {
            RESULT = new NameCall(fname, argl);
	  }
          else if (fname == parser.getQName("generate-id")) {
            RESULT = new GenerateIdCall(fname, argl);
	  }
          else if (fname == parser.getQName("not")) {
            RESULT = new NotCall(fname, argl);
	  }
          else if (fname == parser.getQName("format-number")) {
            RESULT = new FormatNumberCall(fname, argl);
	  }
          else if (fname == parser.getQName("unparsed-entity-uri")) {
            RESULT = new UnparsedEntityUriCall(fname, argl);
	  }
          else if (fname == parser.getQName("key")) {
            RESULT = new KeyCall(fname, argl);
	  }
          else if (fname == parser.getQName("id")) {
            RESULT = new KeyCall(fname, argl);
	  }
          else if (fname == parser.getQName("ceiling")) {
            RESULT = new CeilingCall(fname, argl);
	  }
          else if (fname == parser.getQName("round")) {
            RESULT = new RoundCall(fname, argl);
	  }
          else if (fname == parser.getQName("floor")) {
            RESULT = new FloorCall(fname, argl);
	  }
          else if (fname == parser.getQName("contains")) {
            RESULT = new ContainsCall(fname, argl);
	  }
          else if (fname == parser.getQName("string-length")) {
            RESULT = new StringLengthCall(fname, argl);
	  }
          else if (fname == parser.getQName("starts-with")) {
            RESULT = new StartsWithCall(fname, argl);
	  }
          else if (fname == parser.getQName("function-available")) {
            RESULT = new FunctionAvailableCall(fname, argl);
	  }
          else if (fname == parser.getQName("element-available")) {
            RESULT = new ElementAvailableCall(fname, argl);
	  }
          else if (fname == parser.getQName("local-name")) {
            RESULT = new LocalNameCall(fname, argl);
	  }
          else if (fname == parser.getQName("lang")) {
            RESULT = new LangCall(fname, argl);
	  }
          else if (fname == parser.getQName("namespace-uri")) {
            RESULT = new NamespaceUriCall(fname, argl);
	  }
	  // Special case for extension function nodeset()
          else if (fname.getLocalPart().equals("nodeset")) {
	    parser.setCallsNodeset(true);  // implies MultiDOM
            RESULT = new FunctionCall(fname, argl);
	  }
          else {
            RESULT = new FunctionCall(fname, argl);
	  }
    :};

NonemptyArgumentList ::= Argument:arg
        {: 
            Vector temp = new Vector();
            temp.addElement(arg);
            RESULT = temp;
        :}

        | Argument:arg COMMA NonemptyArgumentList:argl
        {: argl.insertElementAt(arg, 0); RESULT = argl; :};

FunctionName ::= QName:fname
        {:
            fname.clearDefaultNamespace();
            RESULT = fname; 
        :};

VariableName ::= QName:vname
        {:
            vname.clearDefaultNamespace();
            RESULT = vname; 
        :};

Argument ::=    Expr:ex
        {: RESULT = ex; :};

NodeTest ::= NameTest:nt
        {: RESULT = nt; :}

        | NODE
        {: RESULT = new Integer(NodeTest.ANODE); :}

        | TEXT
        {: RESULT = new Integer(NodeTest.TEXT); :}

        | COMMENT
        {: RESULT = new Integer(NodeTest.COMMENT); :}

        | PIPARAM LPAREN Literal:l RPAREN
        {:
           QName name = parser.getQName("name");
           Expression exp = new EqualityExpr(Operators.EQ,
                                             new NameCall(name),
                                             new LiteralExpr(l));
           Vector predicates = new Vector();
           predicates.addElement(new Predicate(exp));
           RESULT = new Step(Axis.CHILD, NodeTest.PI, predicates);
	           //RESULT = new Integer(NodeTest.PI);
        :}

        | PI
        {: RESULT = new Integer(NodeTest.PI); :};

NameTest ::= STAR
             {: RESULT = null; :}

             | QName:qn
             {: RESULT = qn; :};

QName ::= QNAME:qname
        {: RESULT = parser.getQName(qname); :}

        | DIV
        {: RESULT = parser.getQName("div"); :}

        | MOD
        {: RESULT = parser.getQName("mod"); :}

        | KEY
        {: RESULT = parser.getQName("key"); :}

        | ANCESTOR
        {: RESULT = parser.getQName("child"); :}

        | ANCESTORORSELF
        {: RESULT = parser.getQName("ancestor-or-self"); :}

        | ATTRIBUTE
        {: RESULT = parser.getQName("attribute"); :}

        | CHILD
        {: RESULT = parser.getQName("child"); :}

        | DESCENDANT
        {: RESULT = parser.getQName("decendant"); :}

        | DESCENDANTORSELF
        {: RESULT = parser.getQName("decendant-or-self"); :}

        | FOLLOWING
        {: RESULT = parser.getQName("following"); :}

        | FOLLOWINGSIBLING
        {: RESULT = parser.getQName("following-sibling"); :}

        | NAMESPACE
        {: RESULT = parser.getQName("namespace"); :}

        | PARENT
        {: RESULT = parser.getQName("parent"); :}

        | PRECEDING
        {: RESULT = parser.getQName("preceding"); :}

        | PRECEDINGSIBLING
        {: RESULT = parser.getQName("preceding-sibling"); :}

        | SELF
        {: RESULT = parser.getQName("self"); :}

        | ID
        {: RESULT = parser.getQName("id"); :};

