/*
 * @(#)$Id$
 *
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 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;
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;

    /**
     * String representation of the expression being parsed.
     */
    private String _expression;

    /**
     * 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 getQNameIgnoreDefaultNs(String name) {
          return _parser.getQNameIgnoreDefaultNs(name);
    }    

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

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

    /**
     * This method is similar to findNodeType(int, Object) except that it
     * creates a StepPattern instead of just returning a node type. It also 
     * differs in the way it handles "{uri}:*" and "{uri}:@*". The last two 
     * patterns are expanded as "*[namespace-uri() = 'uri']" and 
     * "@*[namespace-uri() = 'uri']", respectively. This expansion considerably 
     * simplifies the grouping of patterns in the Mode class. For this
     * expansion to be correct, the priority of the pattern/template must be
     * set to -0.25 (when no other predicates are present).
     */
    public StepPattern createStepPattern(int axis, Object test, Vector predicates) {
	int nodeType;

	if (test == null) {  // "*"
	    nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE : 
		(axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT;

	    return new StepPattern(axis, nodeType, predicates);
        }
        else if (test instanceof Integer) {
	    nodeType = ((Integer) test).intValue();

	    return new StepPattern(axis, nodeType, predicates);
        }
        else {
	    QName name = (QName)test;
	    boolean setPriority = false;

	    if (axis == Axis.NAMESPACE) {
		nodeType = (name.toString().equals("*")) ? -1
				: _xsltc.registerNamespace(name);
            }
	    else {
		final String uri = name.getNamespace();
		final String local = name.getLocalPart();
		final QName namespace_uri = 
		    _parser.getQNameIgnoreDefaultNs("namespace-uri");

		// Expand {uri}:* to *[namespace-uri() = 'uri'] - same for @*
		if (uri != null && (local.equals("*") || local.equals("@*"))) {
		    if (predicates == null) {
			predicates = new Vector(2);
		    }

		    // Priority is set by hand if no other predicates exist
		    setPriority = (predicates.size() == 0);

		    predicates.add(
			new Predicate(
			    new EqualityExpr(Operators.EQ, 
				new NamespaceUriCall(namespace_uri), 
				new LiteralExpr(uri))));
		}

		if (local.equals("*")) {
		    nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE
			: NodeTest.ELEMENT;
		}
		else if (local.equals("@*")) {
		    nodeType = NodeTest.ATTRIBUTE;
		}
		else {
		    nodeType = (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name)
			: _xsltc.registerElement(name); 
		}
	    }

	    final StepPattern result = new StepPattern(axis, nodeType, predicates); 

	    // Set priority for case prefix:* and prefix:@* (no predicates)
	    if (setPriority) {
		result.setPriority(-0.25);
	    }

	    return result;
	}
    }

    public int findNodeType(int axis, Object test) {
	if (test == null) {  // *
	    return (axis == Axis.ATTRIBUTE) ? 
		NodeTest.ATTRIBUTE :
		(axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT;
        }
        else if (test instanceof Integer) {
            return ((Integer)test).intValue();
        }
        else {
	    QName name = (QName)test;

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

	    if (name.getNamespace() == null) {
		final String local = name.getLocalPart();

		if (local.equals("*")) {
		    return (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE
			: NodeTest.ELEMENT;
		}
		else if (local.equals("@*")) {
		    return NodeTest.ATTRIBUTE;
		}
	    }

	    return (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name)
		: _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(String expression, int lineNumber) throws Exception {
        try {
	    _expression = expression;
	    _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) {
	final ErrorMsg err = new ErrorMsg(ErrorMsg.SYNTAX_ERR, _lineNumber, 
	    _expression);
	_parser.reportError(Constants.FATAL, err);
    }

    public void report_fatal_error(String message, Object info) {
        // empty
    }
    
    public RelativeLocationPath insertStep(Step step, RelativeLocationPath rlp) {
	if (rlp instanceof Step) {
	    return new ParentLocationPath(step, (Step) rlp);
	}
	else if (rlp instanceof ParentLocationPath) {
	    final ParentLocationPath plp = (ParentLocationPath) rlp;
	    final RelativeLocationPath newrlp = insertStep(step, plp.getPath());
	    return new ParentLocationPath(newrlp, plp.getStep());
	}
	else {
	    addError(new ErrorMsg(ErrorMsg.INTERNAL_ERR, "XPathParser.insertStep"));
	    return rlp;
	}
    }

    /**
     * Returns true if the axis applies to elements only. The axes
     * child, attribute, namespace, descendant result in non-empty
     * nodesets only if the context node is of type element.
     */
    public boolean isElementAxis(int axis) {
	return (axis == Axis.CHILD || axis == Axis.ATTRIBUTE ||
		axis == Axis.NAMESPACE || axis == Axis.DESCENDANT);
    }
:}

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); :}

            | 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 = parser.createStepPattern(Axis.CHILD, nt, null);
            :}

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

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

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

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

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

            | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip
            {: 
	       RESULT = pip; 	// TODO: report error if axis is attribute
	    :}

	    | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip 
		Predicates:pp
            {: 
	       // TODO: report error if axis is attribute	
	       RESULT = (ProcessingInstructionPattern)pip.setPredicates(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()/' or
	   // into /descendant-or-self::*/
	   //
	   int nodeType = DOM.NO_TYPE;
	   if (rlp instanceof Step && 
	       parser.isElementAxis(((Step) rlp).getAxis())) 
	   {
	       nodeType = DOM.ELEMENT;
	   }
           final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
           FilterParentPath fpp = new FilterParentPath(fexp, step);
           fpp = new FilterParentPath(fpp, rlp);
           if (fexp instanceof KeyCall == false) {
               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, 
			    DOM.ELEMENT, 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, 
			    DOM.ELEMENT, 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, 
		    DOM.ELEMENT, 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, 
		    DOM.NO_TYPE, null); 
               ParentLocationPath ppl = new ParentLocationPath(middle, right);
	       RESULT = new ParentLocationPath(left, ppl);
	   }
        :};


AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp
        {:
           // 
	   // Expand '//' into '/descendant-or-self::node()/' or
	   // into /descendant-or-self::*/
	   //
	   int nodeType = DOM.NO_TYPE;
	   if (rlp instanceof Step && 
	       parser.isElementAxis(((Step) rlp).getAxis())) 
	   {
	       nodeType = DOM.ELEMENT;
	   }
	   final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
	   RESULT = new AbsoluteLocationPath(parser.insertStep(step, 
				(RelativeLocationPath) rlp));
	:};

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, among
	* others. Also, the default namespace must be ignored.
	*/
	String namespace = null;
	final int index = string.lastIndexOf(':');

	if (index > 0) {
	    final String prefix = string.substring(0, index);
	    namespace = parser._symbolTable.lookupNamespace(prefix);
	}
	RESULT = (namespace == null) ? new LiteralExpr(string)
		     : new LiteralExpr(string, namespace); 
	:}

        | INT:num
        {: 
	   long value = num.longValue();
	   if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
		RESULT = new RealExpr(value);
	   }
	   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.getQNameIgnoreDefaultNs("current")) {
            RESULT = new CurrentCall(fname);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
            RESULT = new NumberCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
            RESULT = new StringCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
            RESULT = new ConcatCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("true")) {
            RESULT = new BooleanExpr(true);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("false")) {
            RESULT = new BooleanExpr(false);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("name")) {
            RESULT = new NameCall(fname);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
            RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
            RESULT = new StringLengthCall(fname, parser.EmptyArgs);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("position")) {
            RESULT = new PositionCall(fname);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("last")) {
            RESULT = new LastCall(fname);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) {
            RESULT = new LocalNameCall(fname);
	  }
          else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
            RESULT = new NamespaceUriCall(fname);
	  }
          else {
            RESULT = new FunctionCall(fname, parser.EmptyArgs);
	  }
        :}

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

VariableName ::= QName:vname
        {: 
	    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.getQNameIgnoreDefaultNs("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);
        :}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

