/*
 * @(#)$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 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);
	  }
          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"); :};

