/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.

%{
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.

#include <limits>

#include <QUrl>

#include "qabstractfloat_p.h"
#include "qandexpression_p.h"
#include "qanyuri_p.h"
#include "qapplytemplate_p.h"
#include "qargumentreference_p.h"
#include "qarithmeticexpression_p.h"
#include "qatomicstring_p.h"
#include "qattributeconstructor_p.h"
#include "qattributenamevalidator_p.h"
#include "qaxisstep_p.h"
#include "qbuiltintypes_p.h"
#include "qcalltemplate_p.h"
#include "qcastableas_p.h"
#include "qcastas_p.h"
#include "qcombinenodes_p.h"
#include "qcommentconstructor_p.h"
#include "qcommonnamespaces_p.h"
#include "qcommonsequencetypes_p.h"
#include "qcommonvalues_p.h"
#include "qcomputednamespaceconstructor_p.h"
#include "qcontextitem_p.h"
#include "qcopyof_p.h"
#include "qcurrentitemstore_p.h"
#include "qdebug_p.h"
#include "qdelegatingnamespaceresolver_p.h"
#include "qdocumentconstructor_p.h"
#include "qelementconstructor_p.h"
#include "qemptysequence_p.h"
#include "qemptysequencetype_p.h"
#include "qevaluationcache_p.h"
#include "qexpressionfactory_p.h"
#include "qexpressionsequence_p.h"
#include "qexpressionvariablereference_p.h"
#include "qexternalvariablereference_p.h"
#include "qforclause_p.h"
#include "qfunctioncall_p.h"
#include "qfunctionfactory_p.h"
#include "qfunctionsignature_p.h"
#include "qgeneralcomparison_p.h"
#include "qgenericpredicate_p.h"
#include "qgenericsequencetype_p.h"
#include "qifthenclause_p.h"
#include "qinstanceof_p.h"
#include "qletclause_p.h"
#include "qliteral_p.h"
#include "qlocalnametest_p.h"
#include "qnamespaceconstructor_p.h"
#include "qnamespacenametest_p.h"
#include "qncnameconstructor_p.h"
#include "qnodecomparison_p.h"
#include "qnodesort_p.h"
#include "qorderby_p.h"
#include "qorexpression_p.h"
#include "qparsercontext_p.h"
#include "qpath_p.h"
#include "qpatternistlocale_p.h"
#include "qpositionalvariablereference_p.h"
#include "qprocessinginstructionconstructor_p.h"
#include "qqnameconstructor_p.h"
#include "qqnametest_p.h"
#include "qqnamevalue_p.h"
#include "qquantifiedexpression_p.h"
#include "qrangeexpression_p.h"
#include "qrangevariablereference_p.h"
#include "qreturnorderby_p.h"
#include "qschemanumeric_p.h"
#include "qschematypefactory_p.h"
#include "qsimplecontentconstructor_p.h"
#include "qstaticbaseuristore_p.h"
#include "qstaticcompatibilitystore_p.h"
#include "qtemplateparameterreference_p.h"
#include "qtemplate_p.h"
#include "qtextnodeconstructor_p.h"
#include "qtokenizer_p.h"
#include "qtreatas_p.h"
#include "qtypechecker_p.h"
#include "qunaryexpression_p.h"
#include "qunresolvedvariablereference_p.h"
#include "quserfunctioncallsite_p.h"
#include "qvaluecomparison_p.h"
#include "qxpathhelper_p.h"
#include "qxsltsimplecontentconstructor_p.h"

/*
 * The cpp generated with bison 2.1 wants to
 * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
 */
#define YYMALLOC malloc
#define YYFREE free

QT_BEGIN_NAMESPACE

/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
 * undocumented reason. */
namespace QPatternist
{

/**
 * "Macro that you define with #define in the Bison declarations
 * section to request verbose, specific error message strings when
 * yyerror is called."
 */
#define YYERROR_VERBOSE 1

#undef YYLTYPE_IS_TRIVIAL
#define YYLTYPE_IS_TRIVIAL 0

/* Suppresses `warning: "YYENABLE_NLS" is not defined`
 * @c YYENABLE_NLS enables Bison internationalization, and we don't
 * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
 */
#define YYENABLE_NLS 0

static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
                                          const ParserContext *const parseInfo)
{
    return QSourceLocation(parseInfo->tokenizer->queryURI(),
                           sourceLocator.first_line,
                           sourceLocator.first_column);
}

/**
 * @internal
 * @relates QXmlQuery
 */
typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;

/**
 * @short Flags invalid expressions and declarations in the currently
 * parsed language.
 *
 * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
 * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
 * identity constraints, it is the union of all the constructs in these
 * languages. However, when dealing with each language individually, we
 * regularly need to disallow some expressions, such as direct element
 * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
 *
 * This is further complicated by that XSLTTokenizer sometimes generates code
 * which is allowed in XQuery but not in XPath. For that reason the token
 * INTERNAL is sometimes generated, which signals that an expression, for
 * instance the @c let clause, should not be flagged as an error, because it's
 * used for internal purposes.
 *
 * Hence, this function is called from each expression and declaration with @p
 * allowedLanguages stating what languages it is allowed in.
 *
 * If @p isInternal is @c true, no error is raised. Otherwise, if the current
 * language is not in @p allowedLanguages, an error is raised.
 */
static void allowedIn(const QueryLanguages allowedLanguages,
                      const ParserContext *const parseInfo,
                      const YYLTYPE &sourceLocator,
                      const bool isInternal = false)
{
    /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
     * and XSL-T is the language, it's ok. */
    if(!isInternal &&
       (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
    {

        QString langName;

        switch(parseInfo->languageAccent)
        {
            case QXmlQuery::XPath20:
                langName = QLatin1String("XPath 2.0");
                break;
            case QXmlQuery::XSLT20:
                langName = QLatin1String("XSL-T 2.0");
                break;
            case QXmlQuery::XQuery10:
                langName = QLatin1String("XQuery 1.0");
                break;
            case QXmlQuery::XmlSchema11IdentityConstraintSelector:
                langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
                break;
            case QXmlQuery::XmlSchema11IdentityConstraintField:
                langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
                break;
        }

        parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
                                                          "which is disallowed in the current language(%1).").arg(langName),
                                        ReportContext::XPST0003,
                                        fromYYLTYPE(sourceLocator, parseInfo));

    }
}

static inline bool isVariableReference(const Expression::ID id)
{
    return    id == Expression::IDExpressionVariableReference
           || id == Expression::IDRangeVariableReference
           || id == Expression::IDArgumentReference;
}

class ReflectYYLTYPE : public SourceLocationReflection
{
public:
    inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
                          const ParserContext *const pi) : m_sl(sourceLocator)
                                                         , m_parseInfo(pi)
    {
    }

    virtual const SourceLocationReflection *actualReflection() const
    {
        return this;
    }

    virtual QSourceLocation sourceLocation() const
    {
        return fromYYLTYPE(m_sl, m_parseInfo);
    }

    virtual QString description() const
    {
        Q_ASSERT(false);
        return QString();
    }

private:
    const YYLTYPE &m_sl;
    const ParserContext *const m_parseInfo;
};

/**
 * @short Centralizes a translation string for the purpose of increasing consistency.
 */
static inline QString unknownType()
{
    return QtXmlPatterns::tr("%1 is an unknown schema type.");
}

static inline Expression::Ptr create(Expression *const expr,
                                     const YYLTYPE &sourceLocator,
                                     const ParserContext *const parseInfo)
{
    parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
    return Expression::Ptr(expr);
}

static inline Template::Ptr create(Template *const expr,
                                   const YYLTYPE &sourceLocator,
                                   const ParserContext *const parseInfo)
{
    parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
    return Template::Ptr(expr);
}

static inline Expression::Ptr create(const Expression::Ptr &expr,
                                     const YYLTYPE &sourceLocator,
                                     const ParserContext *const parseInfo)
{
    parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
    return expr;
}

static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
                                           const YYLTYPE &sourceLocator,
                                           const ParserContext *const parseInfo)
{
    return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
                  sourceLocator,
                  parseInfo);
}

static void loadPattern(const Expression::Ptr &matchPattern,
                        TemplatePattern::Vector &ourPatterns,
                        const TemplatePattern::ID id,
                        const PatternPriority priority,
                        const Template::Ptr &temp)
{
    Q_ASSERT(temp);

    const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;

    ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
}

static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
                                             const SequenceType::Ptr &reqType,
                                             const ParserContext *const parseInfo)
{
    return TypeChecker::applyFunctionConversion(body, reqType,
                                                parseInfo->staticContext,
                                                ReportContext::XTTE0505,
                                                TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
}

static void registerNamedTemplate(const QXmlName &name,
                                  const Expression::Ptr &body,
                                  ParserContext *const parseInfo,
                                  const YYLTYPE &sourceLocator,
                                  const Template::Ptr &temp)
{
    Template::Ptr &e = parseInfo->namedTemplates[name];

    if(e)
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("A template by name %1 "
                                                          "has already been declared.")
                                        .arg(formatKeyword(parseInfo->staticContext->namePool(),
                                                                         name)),
                                        ReportContext::XTSE0660,
                                        fromYYLTYPE(sourceLocator, parseInfo));
    }
    else
    {
        e = temp;
        e->body = body;
    }
}

/**
 * @short Centralizes code for creating numeric literals.
 */
template<typename TNumberClass>
Expression::Ptr createNumericLiteral(const QString &in,
                                     const YYLTYPE &sl,
                                     const ParserContext *const parseInfo)
{
    const Item num(TNumberClass::fromLexical(in));

    if(num.template as<AtomicValue>()->hasError())
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
                                           .arg(formatData(in)),
                                        ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
        return Expression::Ptr(); /* Avoid compiler warning. */
    }
    else
        return create(new Literal(num), sl, parseInfo);
}

/**
 * @short The generated Bison parser calls this function when there is a parse error.
 *
 * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
 * ReportContext::error() is called.
 */
static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
{
    Q_UNUSED(sourceLocator);
    Q_ASSERT(parseInfo);

    parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
    return 1;
}

/**
 * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
 * as @c where and @c let inbetween. We need to continue through them. This function does that.
 */
static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
{
    Q_ASSERT(expr);

    const Expression::ID id = expr->id();
    if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
        return locateReturnClause(expr->operands()[1]);
    else if(id == Expression::IDReturnOrderBy)
        return expr->as<ReturnOrderBy>();
    else
        return 0;
}

static inline bool isPredicate(const Expression::ID id)
{
    return id == Expression::IDGenericPredicate ||
           id == Expression::IDFirstItemPredicate;
}

/**
 * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
 * through the predicates and returns the AxisStep.
 */
static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
                                    const bool throughStructures = true)
{
    Q_ASSERT(expr);

    if(!throughStructures)
        return expr;

    Expression *candidate = expr.data();
    Expression::ID id = candidate->id();

    while(isPredicate(id) || id == Expression::IDPath)
    {
        const Expression::List &children = candidate->operands();
        if(children.isEmpty())
            return Expression::Ptr();
        else
        {
            candidate = children.first().data();
            id = candidate->id();
        }
    }

    if(id == Expression::IDEmptySequence)
        return Expression::Ptr();
    else
    {
        Q_ASSERT(candidate->is(Expression::IDAxisStep));
        return Expression::Ptr(candidate);
    }
}

static void changeToTopAxis(const Expression::Ptr &op)
{
    /* This axis must have been written away by now. */
    Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);

    if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
        op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
}

/**
 * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
 * into an equivalent XPath expression.
 *
 * Essentially, the following rewrite is done:
 *
 * <tt>
 * axis1::test1(a)/axis2::test2(b)
 *              =>
 * child-or-top::test2(b)[parent::test1(a)]
 * </tt>
 *
 * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
 * only the first step in a pattern, but since we're doing rewrites more radically,
 * its line of reasoning cannot be followed.
 *
 * Keep in mind the rewrites that non-terminal PatternStep do.
 *
 * @see createIdPatternPath()
 */
static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
                                                const Expression::Ptr &operand2,
                                                const QXmlNodeModelIndex::Axis axis,
                                                const YYLTYPE &sl,
                                                const ParserContext *const parseInfo)
{
    const Expression::Ptr operandL(findAxisStep(operand1, false));

    if(operandL->is(Expression::IDAxisStep))
        operandL->as<AxisStep>()->setAxis(axis);
    else
        findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);

    return create(GenericPredicate::create(operand2, operandL,
                                           parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
}

/**
 * @short Performs the same role as createPatternPath(), but is tailored
 * for @c fn:key() and @c fn:id().
 *
 * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
 * to be precise) and that poses a challenge to rewriting because what
 * createPatternPath() is not possible to express, since the functions cannot be
 * node tests. E.g, this rewrite is not possible:
 *
 * <tt>
 * id-or-key/abc
 *  =>
 * child-or-top::abc[parent::id-or-key]
 * </tt>
 *
 * Our approach is to rewrite like this:
 *
 * <tt>
 * id-or-key/abc
 * =>
 * child-or-top::abc[parent::node is id-or-key]
 * </tt>
 *
 * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
 * the right operand, and @p axis the target axis to rewrite to.
 *
 * @see createPatternPath()
 */
static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
                                                  const Expression::Ptr &operand2,
                                                  const QXmlNodeModelIndex::Axis axis,
                                                  const YYLTYPE &sl,
                                                  const ParserContext *const parseInfo)
{
    const Expression::Ptr operandR(findAxisStep(operand2));
    Q_ASSERT(operandR);
    changeToTopAxis(operandR);

    const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
                                            sl,
                                            parseInfo));
    const Expression::Ptr isComp(create(new NodeComparison(parentStep,
                                                           QXmlNodeModelIndex::Is,
                                                           operand1),
                                         sl,
                                         parseInfo));

    return create(GenericPredicate::create(operandR, isComp,
                                           parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
}

/**
 * @short Centralizes a translation message, for the
 * purpose of consistency and modularization.
 */
static inline QString prologMessage(const char *const msg)
{
    Q_ASSERT(msg);
    return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
}

/**
 * @short Resolves against the static base URI and checks that @p collation
 * is a supported Unicode Collation.
 *
 * "If a default collation declaration specifies a collation by a
 *  relative URI, that relative URI is resolved to an absolute
 *  URI using the base URI in the static context."
 *
 * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
 */
template<const ReportContext::ErrorCode errorCode>
static QUrl resolveAndCheckCollation(const QString &collation,
                                     const ParserContext *const parseInfo,
                                     const YYLTYPE &sl)
{
    Q_ASSERT(parseInfo);
    const ReflectYYLTYPE ryy(sl, parseInfo);

    QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));

    if(uri.isRelative())
        uri = parseInfo->staticContext->baseURI().resolved(uri);

    XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);

    return uri;
}

/* The Bison generated parser declares macros that aren't used
 * so suppress the warnings by fake usage of them.
 *
 * We do the same for some more defines in the first action. */
#if    defined(YYLSP_NEEDED)    \
    || defined(YYBISON)         \
    || defined(YYBISON_VERSION) \
    || defined(YYPURE)          \
    || defined(yydebug)         \
    || defined(YYSKELETON_NAME)
#endif

/**
 * Wraps @p operand with a CopyOf in case it makes any difference.
 *
 * There is no need to wrap the return value in a call to create(), it's
 * already done.
 */
static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
                                    const ParserContext *const parseInfo,
                                    const YYLTYPE &sl)
{
    return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
                             parseInfo->preserveNamespacesMode), sl, parseInfo);
}

static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
                                         const YYLTYPE &sourceLocator,
                                         const ParserContext *const parseInfo)
{
    return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
}

/**
 * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
 * <tt>fn:root(self::node()) treat as document-node()</tt>.
 */
static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
                                            const YYLTYPE &sl)
{
    Q_ASSERT(parseInfo);
    const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);

    Expression::List args;
    args.append(create(new ContextItem(), sl, parseInfo));

    const ReflectYYLTYPE ryy(sl, parseInfo);

    const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
                                 ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
    Q_ASSERT(fnRoot);

    return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
}

static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
{
#ifdef Patternist_DEBUG_PARSER
    /**
     * "External integer variable set to zero by default. If yydebug
     *  is given a nonzero value, the parser will output information on
     *  input symbols and parser action. See section Debugging Your Parser."
     */
#   define YYDEBUG 1

    extern int XPathdebug;
    XPathdebug = 1;
#endif

    Q_ASSERT(parseInfo);

    const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));

    (*lexVal).sval = tok.value;

    return static_cast<int>(tok.type);
}

/**
 * @short Creates a path expression which contains the step <tt>//</tt> between
 * @p begin and and @p end.
 *
 * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
 *
 * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
 */
static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
                                            const Expression::Ptr &end,
                                            const YYLTYPE &sourceLocator,
                                            const ParserContext *const parseInfo)
{
    const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
    const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));

    return create(new Path(p1, end), sourceLocator, parseInfo);
}

/**
 * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
 */
static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
                                             const Expression::List &args,
                                             const YYLTYPE &sourceLocator)
{
    Q_ASSERT(parseInfo);
    const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
    const ReflectYYLTYPE ryy(sourceLocator, parseInfo);

    return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
                  sourceLocator, parseInfo);
}

static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
                                                      const ParserContext *const parseInfo,
                                                      const YYLTYPE &sourceLocator)
{
    if(content.isEmpty())
        return create(new EmptySequence(), sourceLocator, parseInfo);
    else if(content.size() == 1)
        return content.first();
    else
        return createConcatFN(parseInfo, content, sourceLocator);
}

/**
 * @short Checks for variable initialization circularity.
 *
 * "A recursive function that checks for recursion is full of ironies."
 *
 *      -- The Salsa Master
 *
 * Issues an error via @p parseInfo's StaticContext if the initialization
 * expression @p checkee for the global variable @p var, contains a variable
 * reference to @p var. That is, if there's a circularity.
 *
 * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
 * Query Language, err:XQST0054</a>
 */
static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
                                     const Expression::Ptr &checkee,
                                     const VariableDeclaration::Type type,
                                     FunctionSignature::List &signList,
                                     const ParserContext *const parseInfo)
{
    Q_ASSERT(var);
    Q_ASSERT(checkee);
    Q_ASSERT(parseInfo);

    const Expression::ID id = checkee->id();

    if(id == Expression::IDExpressionVariableReference)
    {
        const ExpressionVariableReference *const ref =
                    static_cast<const ExpressionVariableReference *>(checkee.data());

        if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
                                                              "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
                                            parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
            return;
        }
        else
        {
            /* If the variable we're checking is below another variable, it can be a recursive
             * dependency through functions, so we need to check variable references too. */
            checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
            return;
        }
    }
    else if(id == Expression::IDUserFunctionCallsite)
    {
        const UserFunctionCallsite::Ptr callsite(checkee);
        const FunctionSignature::Ptr sign(callsite->callTargetDescription());
        const FunctionSignature::List::const_iterator end(signList.constEnd());
        FunctionSignature::List::const_iterator it(signList.constBegin());
        bool noMatch = true;

        for(; it != end; ++it)
        {
            if(*it == sign)
            {
                /* The variable we're checking is depending on a function that's recursive. The
                 * user has written a weird query, in other words. Since it's the second time
                 * we've encountered a callsite, we now skip it. */
                noMatch = false;
                break;
            }
        }

        if(noMatch)
        {
            signList.append(sign);
            /* Check the body of the function being called. */
            checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
        }
        /* Continue with the operands, such that we also check the arguments of the callsite. */
    }
    else if(id == Expression::IDUnresolvedVariableReference)
    {
        /* We're called before it has rewritten itself. */
        checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
    }

    /* Check the operands. */
    const Expression::List ops(checkee->operands());
    if(ops.isEmpty())
        return;

    const Expression::List::const_iterator end(ops.constEnd());
    Expression::List::const_iterator it(ops.constBegin());

    for(; it != end; ++it)
        checkVariableCircularity(var, *it, type, signList, parseInfo);
}

static void variableUnavailable(const QXmlName &variableName,
                                const ParserContext *const parseInfo,
                                const YYLTYPE &location)
{
    parseInfo->staticContext->error(QtXmlPatterns::tr("No variable with name %1 exists")
                                       .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
                                    ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
}

/**
 * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
 * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
 *
 * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
 * Cardinality + on range variables</a>
 * @see ParserContext::finalizePushedVariable()
 */
static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
{
    Q_ASSERT(type);
    return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
}

/**
 * @p seqType and @p expr may be @c null.
 */
static Expression::Ptr pushVariable(const QXmlName name,
                                    const SequenceType::Ptr &seqType,
                                    const Expression::Ptr &expr,
                                    const VariableDeclaration::Type type,
                                    const YYLTYPE &sourceLocator,
                                    ParserContext *const parseInfo,
                                    const bool checkSource = true)
{
    Q_ASSERT(!name.isNull());
    Q_ASSERT(parseInfo);

    /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
    VariableSlotID slot = -2;

    switch(type)
    {
        case VariableDeclaration::FunctionArgument:
        /* Fallthrough. */
        case VariableDeclaration::ExpressionVariable:
        {
            slot = parseInfo->allocateExpressionSlot();
            break;
        }
        case VariableDeclaration::GlobalVariable:
        {
            slot = parseInfo->allocateGlobalVariableSlot();
            break;
        }
        case VariableDeclaration::RangeVariable:
        {
            slot = parseInfo->staticContext->allocateRangeSlot();
            break;
        }
        case VariableDeclaration::PositionalVariable:
        {
            slot = parseInfo->allocatePositionalSlot();
            break;
        }
        case VariableDeclaration::TemplateParameter:
            /* Fallthrough. We do nothing, template parameters
             * doesn't use context slots at all, they're hashed
             * on the name. */
        case VariableDeclaration::ExternalVariable:
            /* We do nothing, external variables doesn't use
             *context slots/stack frames at all. */
            ;
    }

    const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));

    Expression::Ptr checked;

    if(checkSource && seqType)
    {
        if(expr)
        {
            /* We only want to add conversion for function arguments, and variables
             * if we're XSL-T.
             *
             * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
             * pass hasn't set up the focus yet, since that's the parent's responsibility. */
            const TypeChecker::Options options((   type == VariableDeclaration::FunctionArgument
                                                || type == VariableDeclaration::TemplateParameter
                                                || parseInfo->isXSLT())
                                               ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());

            checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
                                                           parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
                                                           options);
        }
    }
    else
        checked = expr;

    /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
     * positional variables because in the end they are calls to Iterator::position(). Similarly,
     * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
     *
     * We don't do it for function arguments because the Expression being cached depends -- it depends
     * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
     *
     * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
     * optimizes itself away. */
    if(type == VariableDeclaration::ExpressionVariable)
        checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
    else if(type == VariableDeclaration::GlobalVariable)
        checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);

    var->setExpression(checked);

    parseInfo->variables.push(var);
    return checked;
}

static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
                                                      const ParserContext *const parseInfo)
{
    Q_ASSERT(!name.isNull());
    Q_ASSERT(parseInfo);

    /* We walk the list backwards. */
    const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
    VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());

    while(it != start)
    {
        --it;
        Q_ASSERT(*it);
        if((*it)->name == name)
            return *it;
    }

    return VariableDeclaration::Ptr();
}

static Expression::Ptr resolveVariable(const QXmlName &name,
                                       const YYLTYPE &sourceLocator,
                                       ParserContext *const parseInfo,
                                       const bool raiseErrorOnUnavailability)
{
    const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
    Expression::Ptr retval;

    if(var && var->type != VariableDeclaration::ExternalVariable)
    {
        switch(var->type)
        {
            case VariableDeclaration::RangeVariable:
            {
                retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
                break;
            }
            case VariableDeclaration::GlobalVariable:
            /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
             * a difference between a global and a local expression variable. However, the cache
             * mechanism must. */
            case VariableDeclaration::ExpressionVariable:
            {
                retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
                break;
            }
            case VariableDeclaration::FunctionArgument:
            {
                retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
                break;
            }
            case VariableDeclaration::PositionalVariable:
            {
                retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
                break;
            }
            case VariableDeclaration::TemplateParameter:
            {
                retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
                break;
            }
            case VariableDeclaration::ExternalVariable:
                /* This code path will never be hit, but the case
                 * label silences a warning. See above. */
                ;
        }
        Q_ASSERT(retval);
        var->references.append(retval);
    }
    else
    {
        /* Let's see if your external variable loader can provide us with one. */
        const SequenceType::Ptr varType(parseInfo->staticContext->
                                        externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));

        if(varType)
        {
            const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
            const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
            retval = checked;
        }
        else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
        {
            /* In XSL-T, global variables are in scope for the whole
             * stylesheet, so we must resolve this first at the end. */
            retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
            parseInfo->unresolvedVariableReferences.insert(name, retval);
        }
        else
            variableUnavailable(name, parseInfo, sourceLocator);
    }

    return retval;
}

static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
                                           const Expression::Ptr &returnExpr,
                                           const OrderBy::Stability stability,
                                           const YYLTYPE &sourceLocator,
                                           const ParserContext *const parseInfo)
{
    // TODO do resize(orderSpec.size() + 1)
    Expression::List exprs;
    OrderBy::OrderSpec::Vector orderSpecs;

    exprs.append(returnExpr);

    const int len = orderSpecTransfer.size();

    for(int i = 0; i < len; ++i)
    {
        exprs.append(orderSpecTransfer.at(i).expression);
        orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
    }

    return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
}

%}

/* This grammar shouldn't be compiled with anything older than the Bison version
 * specified below. This '%require' directive was introduced in Bison 2.2. */
%require "2.3a"

%name-prefix="XPath"

/* Specifies the name of the generated parser. */
%output="qquerytransformparser.cpp"

/* Output the .output file. */
%verbose

/* Yes, we want descriptive error messages. */
%error-verbose

/* We'd like to be reentrant/thread-safe */
%pure-parser

/* We want code for line/columns to be generated. */
%locations

/* Create a header file and put declarations there. */
%defines

%parse-param    {ParserContext *const parseInfo}
%lex-param      {ParserContext *const parseInfo}

%expect 4
/* Silences the following:

state 327

  293 SequenceType: ItemType . OccurrenceIndicator

    "+"  shift, and go to state 379
    "*"  shift, and go to state 380
    "?"  shift, and go to state 381

    "+"       [reduce using rule 295 (OccurrenceIndicator)]
    "*"       [reduce using rule 295 (OccurrenceIndicator)]
    $default  reduce using rule 295 (OccurrenceIndicator)

    OccurrenceIndicator  go to state 382

state 45

  200 PathExpr: "/" . RelativePathExpr
  203         | "/" .

    [...]

    "<"       [reduce using rule 203 (PathExpr)]
    "*"       [reduce using rule 203 (PathExpr)]
    $default  reduce using rule 203 (PathExpr)
*/

%token <sval> STRING_LITERAL                "<string literal>"

/**
 * This token is only used in element content and signals content that
 * is not Boundary whitespace. Nevertheless, the token value can be all whitespace,
 * but it was specified using character references or CDATA sections by the user. */
%token <sval> NON_BOUNDARY_WS               "<non-boundary text node>"

/* XPath 2.0 allows quotes and apostrophes to be escaped with "" and ''; this token is
   is used for XPath 2.0 literals such that we can flag syntax errors if running in
   1.0 mode. */
%token <sval> XPATH2_STRING_LITERAL         "<string literal(XPath 2.0)>"
%token <sval> QNAME                         "QName"
%token <sval> NCNAME                        "NCName"

/* A QName as a clark name. See QXmlName::toClarkName(). */
%token <sval> CLARK_NAME                    "ClarkName"

/**
 * Is "ncname:*". The token value does not include the colon and the star.
 */
%token <sval> ANY_LOCAL_NAME

/**
 * Is "*:ncname". The token value does not include the colon and the star.
 */
%token <sval> ANY_PREFIX

/**
 * An XPath 1.0 number literal. It is a string value because
 * Numeric::fromLexical() does the tokenization.
 */
%token <sval> NUMBER                        "<number literal>"

/**
 * XPath 2.0 number literal. It includes the use of 'e'/'E'
 */
%token <sval> XPATH2_NUMBER                 "<number literal(XPath 2.0)>"

%token ANCESTOR                             "ancestor"
%token ANCESTOR_OR_SELF                     "ancestor-or-self"
%token AND                                  "and"
%token APOS                                 "'"
%token APPLY_TEMPLATE                       "apply-template"
%token AS                                   "as"
%token ASCENDING                            "ascending"
%token ASSIGN                               ":="
%token AT                                   "at"
%token AT_SIGN                              "@"
%token ATTRIBUTE                            "attribute"
%token AVT                                  /* Synthetic token. Signals an attribute value template. */
%token BAR                                  "|"
%token BASEURI                              "base-uri"
%token BEGIN_END_TAG                        "</"
%token BOUNDARY_SPACE                       "boundary-space"
%token BY                                   "by"
%token CALL_TEMPLATE                        "call-template"
%token CASE                                 "case"
%token CASTABLE                             "castable"
%token CAST                                 "cast"
%token CHILD                                "child"
%token COLLATION                            "collation"
%token COLONCOLON                           "::"
%token COMMA                                ","
%token COMMENT                              "comment"
%token COMMENT_START                        "<!--"
%token CONSTRUCTION                         "construction"
%token COPY_NAMESPACES                      "copy-namespaces"
%token CURLY_LBRACE                         "{"
%token CURLY_RBRACE                         "}"
%token DECLARE                              "declare"
%token DEFAULT                              "default"
%token DESCENDANT                           "descendant"
%token DESCENDANT_OR_SELF                   "descendant-or-self"
%token DESCENDING                           "descending"
%token DIV                                  "div"
%token DOCUMENT                             "document"
%token DOCUMENT_NODE                        "document-node"
%token DOLLAR                               "$"
%token DOT                                  "."
%token DOTDOT                               ".."
%token ELEMENT                              "element"
%token ELSE                                 "else"
%token EMPTY                                "empty"
%token EMPTY_SEQUENCE                       "empty-sequence"
%token ENCODING                             "encoding"
%token END_OF_FILE 0                        "end of file"
%token END_SORT                             "end_sort"
%token EQ                                   "eq"
%token ERROR                                "unknown keyword" /* Used by the Tokenizer. We use the phrase "keyword" instead of "token" to be less pointy.  */
%token EVERY                                "every"
%token EXCEPT                               "except"
%token EXTERNAL                             "external"
%token FOLLOWING                            "following"
%token FOLLOWING_SIBLING                    "following-sibling"
%token FOLLOWS                              ">>"
%token FOR_APPLY_TEMPLATE                   "for-apply-template" /* Synthetic token, used in XSL-T. */
%token FOR                                  "for"
%token FUNCTION                             "function"
%token GE                                   "ge"
%token G_EQ                                 "="
%token G_GE                                 ">="
%token G_GT                                 ">"
%token G_LE                                 "<="
%token G_LT                                 "<"
%token G_NE                                 "!="
%token GREATEST                             "greatest"
%token GT                                   "gt"
%token IDIV                                 "idiv"
%token IF                                   "if"
%token IMPORT                               "import"
%token INHERIT                              "inherit"
%token IN                                   "in"
%token INSTANCE                             "instance"
%token INTERSECT                            "intersect"
%token IS                                   "is"
%token ITEM                                 "item"
%token LAX                                  "lax"
%token LBRACKET                             "["
%token LEAST                                "least"
%token LE                                   "le"
%token LET                                  "let"
%token LPAREN                               "("
%token LT                                   "lt"
%token MAP                                  "map" /* Synthetic token, used in XSL-T. */
%token MATCHES                              "matches"
%token MINUS                                "-"
%token MODE                                 "mode" /* Synthetic token, used in XSL-T. */
%token MOD                                  "mod"
%token MODULE                               "module"
%token NAME                                 "name"
%token NAMESPACE                            "namespace"
%token NE                                   "ne"
%token NODE                                 "node"
%token NO_INHERIT                           "no-inherit"
%token NO_PRESERVE                          "no-preserve"
%token OF                                   "of"
%token OPTION                               "option"
%token ORDERED                              "ordered"
%token ORDERING                             "ordering"
%token ORDER                                "order"
%token OR                                   "or"
%token PARENT                               "parent"
%token PI_START                             "<?"
%token PLUS                                 "+"
%token POSITION_SET                         /* Synthetic token. */
%token PRAGMA_END                           "#)"
%token PRAGMA_START                         "(#"
%token PRECEDES                             "<<"
%token PRECEDING                            "preceding"
%token PRECEDING_SIBLING                    "preceding-sibling"
%token PRESERVE                             "preserve"
%token PRIORITY                             "priority"
%token PROCESSING_INSTRUCTION               "processing-instruction"
%token QUESTION                             "?"
%token QUICK_TAG_END                        "/>"
%token QUOTE                                "\""
%token RBRACKET                             "]"
%token RETURN                               "return"
%token RPAREN                               ")"
%token SATISFIES                            "satisfies"
%token SCHEMA_ATTRIBUTE                     "schema-attribute"
%token SCHEMA_ELEMENT                       "schema-element"
%token SCHEMA                               "schema"
%token SELF                                 "self"
%token SEMI_COLON                           ";"
%token SLASH                                "/"
%token SLASHSLASH                           "//"
%token SOME                                 "some"
%token SORT                                 "sort" /* Synthetic token, used in XSL-T. */
%token STABLE                               "stable"
%token STAR                                 "*"
%token STRICT                               "strict"
%token STRIP                                "strip"
%token SUCCESS                              /* Synthetic token, used by the Tokenizer. */
%token <sval> COMMENT_CONTENT
%token <sval> PI_CONTENT
%token <sval> PI_TARGET
%token <sval> XSLT_VERSION                  /* Synthetic token, used in XSL-T. */
%token TEMPLATE                             "template"
%token TEXT                                 "text"
%token THEN                                 "then"
%token TO                                   "to"
%token TREAT                                "treat"
%token TUNNEL                               "tunnel" /* Synthetic token, used in XSL-T. */
%token TYPESWITCH                           "typeswitch"
%token UNION                                "union"
%token UNORDERED                            "unordered"
%token VALIDATE                             "validate"
%token VARIABLE                             "variable"
%token VERSION                              "version"
%token WHERE                                "where"
%token XQUERY                               "xquery"
%token INTERNAL                             "internal" /* Synthetic token, used in XSL-T. */
%token INTERNAL_NAME                        "internal-name" /* Synthetic token, used in XSL-T. */
%token CURRENT                              "current" /* Synthetic token, used in XSL-T. */

/* Alphabetically. */
%type <attributeHolder>             Attribute
%type <attributeHolders>            DirAttributeList
%type <cardinality>                 OccurrenceIndicator
%type <enums.axis>                  Axis AxisToken
%type <enums.boundarySpacePolicy>   BoundarySpacePolicy
%type <enums.combinedNodeOp>        IntersectOperator
%type <enums.constructionMode>      ConstructionMode
%type <enums.mathOperator>          MultiplyOperator AdditiveOperator UnaryOperator
%type <enums.nodeOperator>          NodeOperator
%type <enums.orderingEmptySequence> OrderingEmptySequence EmptynessModifier
%type <enums.sortDirection>         DirectionModifier

%type <enums.orderingMode>          OrderingMode
%type <enums.slot>                  PositionalVar
%type <enums.validationMode>        ValidationMode
%type <enums.valueOperator>         ValueComparisonOperator GeneralComparisonOperator
%type <expr>                        OrExpr AndExpr ComparisonExpr UnionExpr Literal
                                    AdditiveExpr MultiplicativeExpr PrimaryExpr FilterExpr
                                    StepExpr PathExpr RelativePathExpr Expr ExprSingle
                                    VarRef ContextItemExpr IfExpr CastExpr CastableExpr
                                    TreatExpr InstanceOfExpr ValueExpr UnaryExpr NodeComp
                                    IntersectExceptExpr RangeExpr ParenthesizedExpr
                                    ValueComp FunctionCallExpr GeneralComp ForClause
                                    WhereClause FLWORExpr ForTail QuantifiedExpr QueryBody
                                    SomeQuantificationExpr SomeQuantificationTail
                                    EveryQuantificationExpr EveryQuantificationTail
                                    ExtensionExpr EnclosedOptionalExpr VariableValue
                                    EnclosedExpr FunctionBody ValidateExpr NumericLiteral
                                    OrderingExpr TypeswitchExpr LetClause LetTail
                                    Constructor DirectConstructor DirElemConstructor
                                    ComputedConstructor CompDocConstructor CompElemConstructor
                                    CompTextConstructor CompCommentConstructor CompPIConstructor
                                    DirPIConstructor CompAttrConstructor DirElemConstructorTail
                                    AxisStep ForwardStep ReverseStep AbbrevForwardStep
                                    CaseDefault CaseClause CaseTail CompAttributeName
                                    FilteredAxisStep DirCommentConstructor CompPIName
                                    DirAttributeValue AbbrevReverseStep CompNamespaceConstructor
                                    CompElementName CompNameExpr SatisfiesClause Pattern PathPattern
                                    PatternStep RelativePathPattern IdKeyPattern OptionalAssign
                                    OptionalDefaultValue

%type <orderSpec>                   OrderSpec
%type <expressionList>              ExpressionSequence FunctionArguments
                                    DirElemContent AttrValueContent
%type <orderSpecs>                  OrderSpecList OrderByClause MandatoryOrderByClause
%type <functionArgument>            Param
%type <functionArguments>           ParamList
%type <itemType>                    KindTest ItemType AtomicType NodeTest NameTest WildCard NodeTestInAxisStep
                                    ElementTest AttributeTest SchemaElementTest SchemaAttributeTest
                                    TextTest CommentTest PITest DocumentTest AnyKindTest AnyAttributeTest
%type <qName>                       ElementName QName VarName FunctionName PragmaName TypeName NCName
                                    CaseVariable AttributeName OptionalTemplateName
                                    TemplateName Mode OptionalMode
%type <qNameVector>                 Modes OptionalModes
%type <sequenceType>                SequenceType SingleType TypeDeclaration
%type <sval>                        URILiteral StringLiteral LexicalName
%type <enums.Bool>                  IsInternal IsTunnel
%type <enums.Double>                OptionalPriority
%type <enums.pathKind>              MapOrSlash

/* Operator Precendence
 * See: http://www.w3.org/TR/xpath20/#parse-note-occurrence-indicators */
%left STAR DIV
%left PLUS MINUS

%%

/* Here, the grammar starts. In the brackets on the right you
 * find the number of corresponding EBNF rule in the XQuery 1.0 specification. If it
 * contains an X, it means the non-terminal has no counter part in the grammar, but
 * exists for implementation purposes. */
Module: VersionDecl LibraryModule                                                   /* [1] */
| VersionDecl MainModule

VersionDecl: /* empty */                                                            /* [2] */
| XQUERY VERSION StringLiteral Encoding Separator
    {

/* Suppress more compiler warnings about unused defines. */
#if    defined(YYNNTS)              \
    || defined(yyerrok)             \
    || defined(YYNSTATES)           \
    || defined(YYRHSLOC)            \
    || defined(YYRECOVERING)        \
    || defined(YYFAIL)              \
    || defined(YYERROR)             \
    || defined(YYNRULES)            \
    || defined(YYBACKUP)            \
    || defined(YYMAXDEPTH)          \
    || defined(yyclearin)           \
    || defined(YYERRCODE)           \
    || defined(YY_LOCATION_PRINT)   \
    || defined(YYLLOC_DEFAULT)
#endif

        if($3 != QLatin1String("1.0"))
        {
            const ReflectYYLTYPE ryy(@$, parseInfo);

            parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
                                               "XQuery version is 1.0.")
                                               .arg(formatData($3)),
                                            ReportContext::XQST0031, &ryy);
        }
    }

Encoding: /* empty */                                                               /* [X] */
| ENCODING StringLiteral
    {
        const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));

        if(!encNameRegExp.exactMatch($2))
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
                                               "It must contain Latin characters only, "
                                               "must not contain whitespace, and must match "
                                               "the regular expression %2.")
                                            .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
                                                 formatExpression(encNameRegExp.pattern())),
                                            ReportContext::XQST0087, fromYYLTYPE(@$, parseInfo));
        }
    }

MainModule: Prolog QueryBody                                                        /* [3] */
    {
        /* In XSL-T, we can have dangling variable references, so resolve them
         * before we proceed with other steps, such as checking circularity. */
        if(parseInfo->isXSLT())
        {
            typedef QHash<QXmlName, Expression::Ptr> Hash;
            const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());

            for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
            {
                const Expression::Ptr body(resolveVariable(it.key(), @$, parseInfo, true)); // TODO source locations vaise
                Q_ASSERT(body);
                it.value()->as<UnresolvedVariableReference>()->bindTo(body);
            }
        }

        /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
        {
            const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
            UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
            for(; cit != cend; ++cit) /* For each callsite. */
            {
                const UserFunctionCallsite::Ptr callsite(*cit);
                Q_ASSERT(callsite);
                const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
                UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());

                for(; it != end; ++it) /* For each UserFunction. */
                {
                    const FunctionSignature::Ptr sign((*it)->signature());
                    Q_ASSERT(sign);

                    if(callsite->isSignatureValid(sign))
                    {
                        callsite->setSource((*it),
                                            parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
                        break;
                    }
                }
                if(it == end)
                {
                    parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
                                                       .arg(formatFunction(callsite)),
                                                    ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
                }
            }
        }

        /* Mark callsites in UserFunction bodies as recursive, if they are. */
        {
            const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
            UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
            for(; fit != fend; ++fit)
            {
                CallTargetDescription::List signList;
                signList.append((*fit)->signature());
                CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
            }
        }

        /* Now, check all global variables for circularity.  This is done
         * backwards because global variables are only in scope below them,
         * in XQuery. */
        {
            const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
            VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());

            while(it != start)
            {
                --it;
                if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
                    continue; /* We want to ignore 'external' variables. */

                FunctionSignature::List signList;
                checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
                ExpressionFactory::registerLastPath((*it)->expression());
                parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
            }
        }

        /* Generate code for doing initial template name calling. One problem
         * is that we compilation in the initial template name, since we throw away the
         * code if we don't have the requested template. */
        if(parseInfo->languageAccent == QXmlQuery::XSLT20
           && !parseInfo->initialTemplateName.isNull()
           && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
        {
            parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
                                                           WithParam::Hash()),
                                          @$, parseInfo);
            parseInfo->templateCalls.append(parseInfo->queryBody);
            /* We just discard the template body that XSLTTokenizer generated. */
        }
        else
            parseInfo->queryBody = $2;
    }

LibraryModule: ModuleDecl Prolog                                                    /* [4] */

ModuleDecl: MODULE NAMESPACE NCNAME G_EQ URILiteral Separator                       /* [5] */
    {
        // TODO add to namespace context
        parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace($3);
    }

Prolog: /* Empty. */                                                                /* [6] */
/* First part. */
| Prolog DefaultNamespaceDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        if(parseInfo->hasSecondPrologPart)
            parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
                                               "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
    }
| Prolog Setter
    {
        if(parseInfo->hasSecondPrologPart)
            parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
                                               "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
    }
| Prolog NamespaceDecl
    {
        if(parseInfo->hasSecondPrologPart)
            parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
                                               "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
    }
| Prolog Import
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        if(parseInfo->hasSecondPrologPart)
            parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
                                               "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
    }
| Prolog TemplateDecl

/* Second part. */
| Prolog VarDecl
    {
        parseInfo->hasSecondPrologPart = true;
    }
| Prolog FunctionDecl
    {
        parseInfo->hasSecondPrologPart = true;
    }
| Prolog OptionDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        parseInfo->hasSecondPrologPart = true;
    }

/*
 * declare template name theName
 * {
 *     "expression"
 * };
 *
 * or
 *
 * declare template name theName matches (pattern) mode modeName priority 123
 * {
 *     "expression"
 * };
 *
 */
TemplateDecl: DECLARE TEMPLATE TemplateName
              OptionalTemplateParameters
              TypeDeclaration
              EnclosedOptionalExpr Separator                                        /* [X] */
    {
        Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, $5), @$, parseInfo));

        registerNamedTemplate($3, typeCheckTemplateBody($6, $5, parseInfo),
                              parseInfo, @1, temp);
        temp->templateParameters = parseInfo->templateParameters;
        parseInfo->templateParametersHandled();
    }
| DECLARE TEMPLATE OptionalTemplateName
  MATCHES LPAREN
  {
    parseInfo->isParsingPattern = true;
  }
  Pattern
  {
    parseInfo->isParsingPattern = false;
  }
  RPAREN
  OptionalModes
  OptionalPriority
  OptionalTemplateParameters
  TypeDeclaration
  EnclosedOptionalExpr Separator                                                    /* [X] */
    {
        /* In this grammar branch, we're guaranteed to be a template rule, but
         * may also be a named template. */

        const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
        Expression::Ptr pattern($7);
        const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();

        Template::Ptr templ(create(new Template(ip, $13), @$, parseInfo));
        templ->body = typeCheckTemplateBody($14, $13, parseInfo);
        templ->templateParameters = parseInfo->templateParameters;
        parseInfo->templateParametersHandled();

        TemplatePattern::Vector ourPatterns;
        /* We do it as per 6.4 Conflict Resolution for Template Rules:
         *
         * "If the pattern contains multiple alternatives separated by |, then
         * the template rule is treated equivalently to a set of template
         * rules, one for each alternative. However, it is not an error if a
         * node matches more than one of the alternatives." */
        while(pattern->is(Expression::IDCombineNodes))
        {
            const Expression::List operands(pattern->operands());
            pattern = operands.first();

            loadPattern(operands.at(1), ourPatterns, templateID, $11, templ);
        }

        loadPattern(pattern, ourPatterns, templateID, $11, templ);

        if(!$3.isNull())
            registerNamedTemplate($3, $14, parseInfo, @1, templ);

        /* Now, let's add it to all the relevant templates. */
        for(int i = 0; i < $10.count(); ++i) /* For each mode. */
        {
            const QXmlName &modeName = $10.at(i);

            if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && $10.count() > 1)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
                                                                 .arg(formatKeyword(QLatin1String("#all"))),
                                                ReportContext::XTSE0530,
                                                fromYYLTYPE(@$, parseInfo));
            }

            /* For each pattern the template use. */
            const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
            for(int t = 0; t < ourPatterns.count(); ++t)
                mode->templatePatterns.append(ourPatterns.at(t));
        }
    }

OptionalPriority: /* Empty. */                                                      /* [X] */
    {
        $$ = std::numeric_limits<xsDouble>::quiet_NaN();
    }

| PRIORITY StringLiteral
    {
        const AtomicValue::Ptr val(Decimal::fromLexical($2));
        if(val->hasError())
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
                                                             .arg(formatKeyword(QLatin1String("priority")),
                                                                  formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
                                                                  formatData($2)),
                                            ReportContext::XTSE0530,
                                            fromYYLTYPE(@$, parseInfo));
        }
        else
            $$ = val->as<Numeric>()->toDouble();
    }

OptionalTemplateName: /* Empty. */                                                  /* [X] */
    {
        $$ = QXmlName();
    }
| TemplateName

TemplateName: NAME ElementName
    {
        $$ = $2;
    }

Setter: BoundarySpaceDecl                                                           /* [7] */
| DefaultCollationDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }
| BaseURIDecl
| ConstructionDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }
| OrderingModeDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }
| EmptyOrderDecl
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }
| CopyNamespacesDecl

Import: SchemaImport                                                                /* [8] */
| ModuleImport

Separator: SEMI_COLON                                                               /* [9] */

NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator        /* [10] */
    {
        if(!$6)
            allowedIn(QXmlQuery::XQuery10, parseInfo, @$);

        if($3 == QLatin1String("xmlns"))
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
                                               .arg(formatKeyword(QLatin1String("xmlns"))),
                                            ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
        }
        else if ($5 == CommonNamespaces::XML || $3 == QLatin1String("xml"))
        {
             parseInfo->staticContext->error(QtXmlPatterns::tr(
                                            "The prefix %1 can not be bound. By default, it is already bound "
                                            "to the namespace %2.")
                                             .arg(formatKeyword("xml"))
                                             .arg(formatURI(CommonNamespaces::XML)),
                                             ReportContext::XQST0070,
                                             fromYYLTYPE(@$, parseInfo));
        }
        else if(parseInfo->declaredPrefixes.contains($3))
        {
            /* This includes the case where the user has bound a default prefix(such
             * as 'local') and now tries to do it again. */
            parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
                                               .arg(formatKeyword($3)),
                                            ReportContext::XQST0033, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->declaredPrefixes.append($3);

            if($5.isEmpty())
            {
                parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
                                                                                   StandardLocalNames::empty,
                                                                                   parseInfo->staticContext->namePool()->allocatePrefix($3)));
            }
            else
            {
                parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding($3, $5));
            }
        }
    }

BoundarySpaceDecl: DECLARE BOUNDARY_SPACE BoundarySpacePolicy Separator             /* [11] */
    {
        if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare boundary-space"),
                                            ReportContext::XQST0068, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->staticContext->setBoundarySpacePolicy($3);
            parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
        }
    }

BoundarySpacePolicy: STRIP                                                          /* [X] */
    {
        $$ = StaticContext::BSPStrip;
    }

| PRESERVE
    {
        $$ = StaticContext::BSPPreserve;
    }

DefaultNamespaceDecl: DeclareDefaultElementNamespace                                /* [12] */
| DeclareDefaultFunctionNamespace

DeclareDefaultElementNamespace: DECLARE DEFAULT ELEMENT NAMESPACE
                                URILiteral Separator                                /* [X] */
    {
        if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
        {
            parseInfo->staticContext->error(prologMessage("declare default element namespace"),
                                            ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), StandardLocalNames::empty));
            parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
        }
    }

DeclareDefaultFunctionNamespace: DECLARE DEFAULT FUNCTION NAMESPACE
                                 URILiteral Separator                               /* [X] */
    {
        if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
        {
            parseInfo->staticContext->error(prologMessage("declare default function namespace"),
                                            ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->staticContext->setDefaultFunctionNamespace($5);
            parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
        }
    }

OptionDecl: DECLARE OPTION ElementName StringLiteral Separator                     /* [13] */
    {
        if($3.prefix() == StandardPrefixes::empty)
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
                                               "There is no default namespace for options."),
                                            ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
        }
    }

OrderingModeDecl: DECLARE ORDERING OrderingMode Separator                           /* [14] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare ordering"),
                                            ReportContext::XQST0065, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
            parseInfo->staticContext->setOrderingMode($3);
        }
    }

OrderingMode: ORDERED
    {
        $$ = StaticContext::Ordered;
    }
| UNORDERED
    {
        $$ = StaticContext::Unordered;
    }

EmptyOrderDecl: DECLARE DEFAULT ORDER OrderingEmptySequence Separator               /* [15] */
    {
        if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare default order"),
                                            ReportContext::XQST0069, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
            parseInfo->staticContext->setOrderingEmptySequence($4);
        }
    }

OrderingEmptySequence: EMPTY LEAST                                                  /* [X] */
    {
        $$ = StaticContext::Least;
    }
| EMPTY GREATEST
    {
        $$ = StaticContext::Greatest;
    }

CopyNamespacesDecl: DECLARE COPY_NAMESPACES PreserveMode COMMA
                    InheritMode Separator                                           /* [16] */
    {
        if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
                                            ReportContext::XQST0055, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
        }
    }

PreserveMode: PRESERVE                                                              /* [17] */
    {
        parseInfo->preserveNamespacesMode = true;
    }

| NO_PRESERVE
    {
        parseInfo->preserveNamespacesMode = false;
    }

InheritMode: INHERIT                                                                /* [18] */
    {
        parseInfo->inheritNamespacesMode = true;
    }

| NO_INHERIT
    {
        parseInfo->inheritNamespacesMode = false;
    }

DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator             /* [19] */
    {
        if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare default collation"),
                                            ReportContext::XQST0038, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>($4, parseInfo, @$));

            parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
            parseInfo->staticContext->setDefaultCollation(coll);
        }
    }

BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator                        /* [20] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3);
        if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare base-uri"),
                                            ReportContext::XQST0032, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
            const ReflectYYLTYPE ryy(@$, parseInfo);

            QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>($4, parseInfo->staticContext, &ryy));
            /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */

            if(toBeBase.isRelative())
                toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);

            parseInfo->staticContext->setBaseURI(toBeBase);
        }
    }

SchemaImport: IMPORT SCHEMA SchemaPrefix URILiteral FileLocations Separator         /* [21] */
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
                                           "and therefore %1 declarations cannot occur.")
                                           .arg(formatKeyword("import schema")),
                                        ReportContext::XQST0009, fromYYLTYPE(@$, parseInfo));
    }

SchemaPrefix: /* empty */                                                           /* [22] */
| DEFAULT ELEMENT NAMESPACE
| NAMESPACE NCNAME G_EQ

ModuleImport: IMPORT MODULE ModuleNamespaceDecl URILiteral FileLocations Separator  /* [23] */
    {
        if($4.isEmpty())
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
                                               .arg(formatKeyword("module import")),
                                           ReportContext::XQST0088, fromYYLTYPE(@$, parseInfo));

        }
        else
        {
            /* This is temporary until we have implemented it. */
            parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
                                            ReportContext::XQST0016, fromYYLTYPE(@$, parseInfo));
        }
    }

ModuleNamespaceDecl: /* empty */                                                    /* [X] */
| NAMESPACE NCNAME G_EQ

FileLocations: /* empty */                                                          /* [X] */
| AT FileLocation

FileLocation: URILiteral                                                            /* [X] */
| FileLocation COMMA URILiteral

VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration
         VariableValue OptionalDefaultValue Separator                               /* [24] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
        if(variableByName($5, parseInfo))
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already "
                                                              "been declared.")
                                               .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical($5))),
                                            parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
                                            fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            if($7) /* We got a value assigned. */
            {
                const Expression::Ptr checked
                        (TypeChecker::applyFunctionConversion($7, $6, parseInfo->staticContext,
                                                              $3 ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
                                                              $3 ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));

                pushVariable($5, $6, checked, VariableDeclaration::GlobalVariable, @$, parseInfo);
                parseInfo->declaredVariables.append(parseInfo->variables.last());
            }
            else /* We got an 'external' declaration. */
            {
                const SequenceType::Ptr varType(parseInfo->staticContext->
                                                externalVariableLoader()->announceExternalVariable($5, $6));

                if(varType)
                {
                    /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
                     * any references to it. */
                    pushVariable($5, varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, @$, parseInfo);
                }
                else if($8)
                {
                    /* Ok, the xsl:param got a default value, we make it
                     * available as a regular variable declaration. */
                    // TODO turn into checked
                    pushVariable($5, $6, $8, VariableDeclaration::GlobalVariable, @$, parseInfo);
                    // TODO ensure that duplicates are trapped.
                }
                else
                {
                    parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
                                                                      "variable by name %1.")
                                                       .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                                    parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
                                                    fromYYLTYPE(@$, parseInfo));
                }
            }
        }
    }

VariableValue: EXTERNAL                                                             /* [X] */
    {
        $$.reset();
    }
| ASSIGN ExprSingle
    {
        $$ = $2;
    }

OptionalDefaultValue: /* Empty. */                                                  /* [X] */
    {
        $$.reset();
    }
| ASSIGN ExprSingle
    {
        $$ = $2;
    }

ConstructionDecl: DECLARE CONSTRUCTION ConstructionMode Separator                   /* [25] */
    {
        if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
        {
            parseInfo->staticContext->error(prologMessage("declare ordering"),
                                            ReportContext::XQST0067, fromYYLTYPE(@$, parseInfo));
        }
        else
        {
            parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
            parseInfo->staticContext->setConstructionMode($3);
        }
    }

ConstructionMode: STRIP                                                             /* [X] */
    {
        $$ = StaticContext::CMStrip;
    }
| PRESERVE
    {
        $$ = StaticContext::CMPreserve;
    }

FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN
              {
                $<enums.slot>$ = parseInfo->currentExpressionSlot() - $6.count();
              }
              TypeDeclaration FunctionBody Separator                                /* [26] */
    {
        if(!$3)
            allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);

        /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
        const QXmlName::NamespaceCode ns($4.namespaceURI());

        if(parseInfo->isXSLT() && !$4.hasPrefix())
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
                                            ReportContext::XTSE0740,
                                            fromYYLTYPE(@$, parseInfo));
        }

        if($10) /* We got a function body. */
        {
            if(ns == StandardNamespaces::empty)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
                                                   "cannot be empty (try the predefined "
                                                   "prefix %1 which exists for cases "
                                                   "like this)")
                                                   .arg(formatKeyword("local")),
                                                ReportContext::XQST0060, fromYYLTYPE(@$, parseInfo));
            }
            else if(XPathHelper::isReservedNamespace(ns))
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr(
                                                   "The namespace %1 is reserved; therefore "
                                                   "user defined functions may not use it. "
                                                   "Try the predefined prefix %2, which "
                                                   "exists for these cases.")
                                                .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
                                                parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
                                                fromYYLTYPE(@$, parseInfo));
            }
            else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
                    ns != parseInfo->moduleNamespace)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr(
                                                   "The namespace of a user defined "
                                                   "function in a library module must be "
                                                   "equivalent to the module namespace. "
                                                   "In other words, it should be %1 instead "
                                                   "of %2")
                                                .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
                                                     formatURI(parseInfo->staticContext->namePool(), ns)),
                                                ReportContext::XQST0048, fromYYLTYPE(@$, parseInfo));
            }
            else
            {
                /* Apply function conversion such that the body matches the declared
                 * return type. */
                const Expression::Ptr checked(TypeChecker::applyFunctionConversion($10, $9,
                                                                                   parseInfo->staticContext,
                                                                                   ReportContext::XPTY0004,
                                                                                   TypeChecker::Options(TypeChecker::AutomaticallyConvert |
                                                                                                        TypeChecker::CheckFocus |
                                                                                                        TypeChecker::GeneratePromotion)));

                const int argCount = $6.count();
                const FunctionSignature::Ptr sign(new FunctionSignature($4 /* name */,
                                                                        argCount /* minArgs */,
                                                                        argCount /* maxArgs */,
                                                                        $9 /* returnType */));
                sign->setArguments($6);
                const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
                UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());

                for(; it != end; ++it)
                {
                    if(*(*it)->signature() == *sign)
                    {
                        parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
                                                           "the signature %1.")
                                                           .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
                                                        parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE(@$, parseInfo));
                    }
                }

                VariableDeclaration::List argDecls;

                for(int i = 0; i < argCount; ++i)
                    argDecls.append(parseInfo->variables.at(i));

                if($<enums.slot>8 > -1)
                {
                    /* We have allocated slots, so now push them out of scope. */
                    parseInfo->finalizePushedVariable(argCount);
                }

                parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, $<enums.slot>8, argDecls)));
            }
        }
        else /* We got an 'external' declaration. */
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
                                               "All supported functions can be used directly, "
                                               "without first declaring them as external"),
                                            ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
        }
    }

ParamList: /* empty */                                                              /* [27] */
    {
        $$ = FunctionArgument::List();
    }
| Param
    {
        FunctionArgument::List l;
        l.append($1);
        $$ = l;
    }
| ParamList COMMA Param
    {
        FunctionArgument::List::const_iterator it($1.constBegin());
        const FunctionArgument::List::const_iterator end($1.constEnd());

        for(; it != end; ++it)
        {
            if((*it)->name() == $3->name())
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("An argument by name %1 has already "
                                                   "been declared. Every argument name "
                                                   "must be unique.")
                                                   .arg(formatKeyword(parseInfo->staticContext->namePool(), $3->name())),
                                                ReportContext::XQST0039, fromYYLTYPE(@$, parseInfo));
            }
        }

        $1.append($3);
        $$ = $1;
    }

Param: DOLLAR VarName TypeDeclaration                                               /* [28] */
    {
        pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
        $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
    }

FunctionBody: EXTERNAL                                                              /* [X] */
    {
        $$.reset();
    }
| EnclosedExpr

EnclosedExpr: CURLY_LBRACE Expr CURLY_RBRACE                                        /* [29] */
    {
        $$ = $2;
    }

QueryBody: Expr                                                                     /* [30] */

/**
 * A pattern as found in for instance xsl:template/@match.
 *
 * @note When using this pattern, remember to set ParserContext::isParsingPattern.
 *
 * @see <a href="http://www.w3.org/TR/xslt20/#dt-pattern">XSL Transformations
 * (XSLT) Version 2.0, 5.5.2 Syntax of Patterns</a>
 */
Pattern: PathPattern                                                                /* [XSLT20-1] */
| Pattern BAR PathPattern
    {
        $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
    }

PathPattern: RelativePathPattern                                                    /* [XSLT20-2] */
| SLASH
    {
        /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
         * "Similarly, / matches a document node, and only a document node,
         * because the result of the expression root(.)//(/) returns the root
         * node of the tree containing the context node if and only if it is a
         * document node." */
        $$ = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), @$, parseInfo);
    }
| SLASH RelativePathPattern
    {
        /* /axis::node-test
         *       =>
         * axis::node-test[parent::document-node()]
         *
         * In practice it looks like this. $2 is:
         *
         *     TruthPredicate
         *          AxisStep    self::element(c)
         *          TruthPredicate
         *              AxisStep    parent::element(b)
         *              AxisStep    parent::element(a)
         *
         * and we want this:
         *
         *      TruthPredicate
         *          AxisStep    self::element(c)
         *          TruthPredicate
         *              AxisStep    self::element(b)
         *              TruthPredicate
         *                  AxisStep    parent::element(a)
         *                  AxisStep    parent::document()
         *
         * So we want to rewrite the predicate deepest down into a
         * another TruthPredicate containing the AxisStep.
         *
         * The simplest case where $2 is only an axis step is special. When $2 is:
         *
         *  AxisStep self::element(a)
         *
         * we want:
         *
         *  TruthPredicate
         *      AxisStep self::element(a)
         *      AxisStep parent::document()
         */

        /* First, find the target. */
        Expression::Ptr target($2);

        while(isPredicate(target->id()))
        {
            const Expression::Ptr candidate(target->operands().at(1));

            if(isPredicate(candidate->id()))
                target = candidate;
            else
                break; /* target is now the last predicate. */
        }

        if(target->is(Expression::IDAxisStep))
        {
            $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
                                                 parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
        }
        else
        {
            const Expression::List targetOperands(target->operands());
            Expression::List newOps;
            newOps.append(targetOperands.at(0));

            newOps.append(create(GenericPredicate::create(targetOperands.at(1),
                                                          create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
                                                          parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo));

            target->setOperands(newOps);
            $$ = $2;
        }
    }
| SLASHSLASH RelativePathPattern
    {
        /* //axis::node-test
         *        =>
         * axis::node-test[parent::node()]
         *
         * Spec says: "//para matches any para element that has a parent node."
         */
        $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo),
                                             parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
    }
| IdKeyPattern
| IdKeyPattern SLASH RelativePathPattern
    {
        createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
    }
| IdKeyPattern SLASHSLASH RelativePathPattern
    {
        createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
    }

IdKeyPattern: FunctionCallExpr
    {
        const Expression::List ands($1->operands());
        const FunctionSignature::Ptr signature($1->as<FunctionCall>()->signature());
        const QXmlName name(signature->name());
        const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
        const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);

        if(name == id)
        {
            const Expression::ID id = ands.first()->id();
            if(!isVariableReference(id) && id != Expression::IDStringValue)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
                                                                  "the argument must be a variable reference or a string literal.")
                                                                  .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
                                                ReportContext::XPST0003,
                                                fromYYLTYPE(@$, parseInfo));
            }
        }
        else if(name == key)
        {
            if(ands.first()->id() != Expression::IDStringValue)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
                                                                  "must be a string literal, when used for matching.")
                                                                  .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
                                                ReportContext::XPST0003,
                                                fromYYLTYPE(@$, parseInfo));
            }

            const Expression::ID id2 = ands.at(1)->id();
            if(!isVariableReference(id2) &&
               id2 != Expression::IDStringValue &&
               id2 != Expression::IDIntegerValue &&
               id2 != Expression::IDBooleanValue &&
               id2 != Expression::IDFloat)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
                                                                  "must be a literal or a variable reference, when used for matching.")
                                                                  .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
                                                ReportContext::XPST0003,
                                                fromYYLTYPE(@$, parseInfo));
            }

            if(ands.count() == 3)
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
                                                                  .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
                                                ReportContext::XPST0003,
                                                fromYYLTYPE(@$, parseInfo));
            }

        }
        else
        {
            const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
            parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
                                                              "and %2, not %3, can be used for matching.")
                                                              .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
                                                                   formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
                                                                   formatFunction(parseInfo->staticContext->namePool(), signature)),
                                            ReportContext::XPST0003,
                                            fromYYLTYPE(@$, parseInfo));
        }

        $$ = $1;
    }

RelativePathPattern: PatternStep                                                    /* [XSLT20-3] */
| RelativePathPattern SLASH PatternStep
    {
        $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
    }
| RelativePathPattern SLASHSLASH PatternStep
    {
        $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
    }

PatternStep: FilteredAxisStep
    {
        const Expression::Ptr expr(findAxisStep($1));

        const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
        AxisStep *const axisStep = expr->as<AxisStep>();

        /* Here we constrain the possible axes, and we rewrite the axes as according
         * to 5.5.3 The Meaning of a Pattern.
         *
         * However, we also rewrite axis child and attribute to axis self. The
         * reason for this is that if we don't, we will match the children of
         * the context node, instead of the context node itself. The formal
         * definition of a pattern, root(.)//EE is insensitive to context,
         * while the way we implement pattern, "the other way of seeing it",
         * e.g from right to left, are very much. */

        if(axisStep->nodeTest() == BuiltinTypes::document
           || axis == QXmlNodeModelIndex::AxisChild)
            axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
        else if(axis == QXmlNodeModelIndex::AxisAttribute)
        {
            axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
            /* Consider that the user write attribute::node().  This is
             * semantically equivalent to attribute::attribute(), but since we have changed
             * the axis to axis self, we also need to change the node test, such that we
             * have self::attribute(). */
            if(*axisStep->nodeTest() == *BuiltinTypes::node)
                axisStep->setNodeTest(BuiltinTypes::attribute);
        }
        else
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
                                                              "only axis %2 or %3 can.")
                                            .arg(formatKeyword(AxisStep::axisName(axis)),
                                                 formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
                                                 formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
                                            ReportContext::XPST0003,
                                            fromYYLTYPE(@$, parseInfo));
        }

        $$ = $1;
    }

Expr: ExprSingle                                                                    /* [31] */
| ExpressionSequence
    {
        $$ = create(new ExpressionSequence($1), @$, parseInfo);
    }

ExpressionSequence: ExprSingle COMMA ExprSingle                                     /* [X] */
    {
        Expression::List l;
        l.append($1);
        l.append($3);
        $$ = l;
    }
| ExpressionSequence COMMA ExprSingle
    {
        $1.append($3);
        $$ = $1;
    }

ExprSingle: OrExpr                                                                  /* [32] */
| FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| AVT LPAREN AttrValueContent RPAREN
    {
        $$ = createDirAttributeValue($3, parseInfo, @$);
    }

OptionalModes: /* Empty. */                                                         /* [X] */
    {
        QVector<QXmlName> result;
        result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
        $$ = result;
    }
| MODE Modes
    {
        $$ = $2;
    }

OptionalMode: /* Empty. */                                                          /* [X] */
    {
            $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
    }
| MODE Mode
    {
        $$ = $2;
    }

Modes: Mode
    {
        QVector<QXmlName> result;
        result.append($1);
        $$ = result;
    }
| Modes COMMA Mode
    {
        $1.append($3);
        $$ = $1;
    }

Mode: QName                                                                         /* [X] */
    {
        $$ = $1;
    }
| NCNAME
    {
        if($1 == QLatin1String("#current"))
            $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
        else if($1 == QLatin1String("#default"))
            $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
        else if($1 == QLatin1String("#all"))
            $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
        else
        {
            const ReflectYYLTYPE ryy(@$, parseInfo);

            if(!QXmlUtils::isNCName($1))
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
                                                                  .arg(formatKeyword($1)),
                                                ReportContext::XTSE0550,
                                                fromYYLTYPE(@$, parseInfo));
            }

            $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
        }
    }


FLWORExpr: ForClause                                                                /* [33] */
| LetClause

ForClause: FOR DOLLAR VarName TypeDeclaration
           PositionalVar IN ExprSingle
           {
               /* We're pushing the range variable here, not the positional. */
               $<expr>$ = pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
           }
           {
               /* It is ok this appears after PositionalVar, because currentRangeSlot()
                * uses a different "channel" than currentPositionSlot(), so they can't trash
                * each other. */
               $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
           }
           ForTail                                                                  /* [34] */
    {
        Q_ASSERT($7);
        Q_ASSERT($10);

        /* We want the next last pushed variable, since we push the range variable after the
         * positional variable. */
        if($5 != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == $3)
        {
            /* Ok, a positional variable is used since its slot is not -1, and its name is equal
             * to our range variable. This is an error. */
            parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
                                               "from the positional variable. Hence, the two variables named %1 collide.")
                                               .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
                                            ReportContext::XQST0089,
                                            fromYYLTYPE(@$, parseInfo));

        }

        const Expression::Ptr retBody(create(new ForClause($<enums.slot>9, $<expr>8, $10, $5), @$, parseInfo));
        ReturnOrderBy *const rob = locateReturnClause($10);

        if(rob)
            $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), @$, parseInfo);
        else
            $$ = retBody;

        parseInfo->finalizePushedVariable();

        if($5 != -1) /* We also have a positional variable to remove from the scope. */
            parseInfo->finalizePushedVariable();
    }

ForTail: COMMA DOLLAR VarName TypeDeclaration
         PositionalVar IN ExprSingle
         {
             pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
         }
         {
             /* It is ok this appears after PositionalVar, because currentRangeSlot()
              * uses a different "channel" than currentPositionSlot(), so they can't trash
              * each other. */
             $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
         }
         ForTail                                                                    /* [X] */
    {
        $$ = create(new ForClause($<enums.slot>9, $<expr>7, $10, $5), @$, parseInfo);

        parseInfo->finalizePushedVariable();

        if($5 != -1) /* We also have a positional variable to remove from the scope. */
            parseInfo->finalizePushedVariable();
    }

| WhereClause
| ForClause
| LetClause

PositionalVar: /* empty */                                                          /* [35] */
    {
        $$ = -1;
    }

| AT DOLLAR VarName
    {
        pushVariable($3, CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
                     VariableDeclaration::PositionalVariable, @$, parseInfo);
        $$ = parseInfo->currentPositionSlot();
    }

LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
           {
                $<expr>$ = pushVariable($4, quantificationType($5), $7, VariableDeclaration::ExpressionVariable, @$, parseInfo);
           }
           LetTail                                                                  /* [36] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        Q_ASSERT(parseInfo->variables.top()->name == $4);
        $$ = create(new LetClause($<expr>8, $9, parseInfo->variables.top()), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

LetTail: COMMA DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
         { $<expr>$ = pushVariable($3, quantificationType($4), $6, VariableDeclaration::ExpressionVariable, @$, parseInfo);}
         LetTail                                                                    /* [X] */
    {
        Q_ASSERT(parseInfo->variables.top()->name == $3);
        $$ = create(new LetClause($<expr>7, $8, parseInfo->variables.top()), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

| WhereClause
| ForClause
| LetClause

WhereClause: OrderByClause RETURN ExprSingle                                        /* [37] */
    {
        if($1.isEmpty())
            $$ = $3;
        else
            $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
    }

| WHERE ExprSingle OrderByClause RETURN ExprSingle
    {
        if($3.isEmpty())
            $$ = create(new IfThenClause($2, $5, create(new EmptySequence, @$, parseInfo)), @$, parseInfo);
        else
            $$ = create(new IfThenClause($2, createReturnOrderBy($3, $5, parseInfo->orderStability.pop(), @$, parseInfo),
                                         create(new EmptySequence, @$, parseInfo)),
                        @$, parseInfo);
    }

OrderByClause: /* Empty. */                                                         /* [38] */
    {
        $$ = OrderSpecTransfer::List();
    }
| MandatoryOrderByClause

MandatoryOrderByClause: OrderByInputOrder OrderSpecList
    {
        $$ = $2;
    }

OrderSpecList: OrderSpecList COMMA OrderSpec                                        /* [39] */
    {
        OrderSpecTransfer::List list;
        list += $1;
        list.append($3);
        $$ = list;
    }
| OrderSpec
    {
        OrderSpecTransfer::List list;
        list.append($1);
        $$ = list;
    }

OrderSpec: ExprSingle DirectionModifier EmptynessModifier CollationModifier         /* [40] */
    {
        $$ = OrderSpecTransfer($1, OrderBy::OrderSpec($2, $3));
    }

DirectionModifier: /* Empty. */                                                     /* [X] */
    {
        /* Where does the specification state the default value is ascending?
         *
         * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
         *
         * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
         *  of values encountered when evaluating their orderspecs from left to right for
         *  which one value is greater-than the other (as defined above), then:
         *
         *      1. If V1 is greater-than V2: If the orderspec specifies descending,
         *         then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
         *      2. If V2 is greater-than V1: If the orderspec specifies descending,
         *         then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
         *
         * which means that if you don't specify anything, or you
         * specify ascending, you get the same result.
         */
        $$ = OrderBy::OrderSpec::Ascending;
    }

| ASCENDING
    {
        $$ = OrderBy::OrderSpec::Ascending;
    }

| DESCENDING
    {
        $$ = OrderBy::OrderSpec::Descending;
    }

EmptynessModifier: /* Empty. */                                                     /* [X] */
    {
        $$ = parseInfo->staticContext->orderingEmptySequence();
    }
| OrderingEmptySequence

CollationModifier: /* Empty. */                                                     /* [X] */
| COLLATION URILiteral
    {
        if(parseInfo->isXSLT())
            resolveAndCheckCollation<ReportContext::XTDE1035>($2, parseInfo, @$);
        else
            resolveAndCheckCollation<ReportContext::XQST0076>($2, parseInfo, @$);
    }
| INTERNAL COLLATION ExprSingle
    {
        /* We do nothing. We don't use collations, and we have this non-terminal
         * in order to accept expressions. */
    }

OrderByInputOrder: STABLE ORDER BY                                                  /* [X] */
    {
        parseInfo->orderStability.push(OrderBy::StableOrder);
    }
| ORDER BY
    {
        parseInfo->orderStability.push(OrderBy::UnstableOrder);
    }

QuantifiedExpr: SomeQuantificationExpr                                              /* [42] */
| EveryQuantificationExpr

SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle
                        {
                            pushVariable($3, quantificationType($4), $6,
                                         VariableDeclaration::RangeVariable, @$, parseInfo);
                        }
                        {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
                        SomeQuantificationTail                                      /* [X] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new QuantifiedExpression($<enums.slot>8,
                                             QuantifiedExpression::Some, $<expr>6, $9), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

SomeQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
                        {
                            $<expr>$ = pushVariable($3, quantificationType($4), $6,
                                                    VariableDeclaration::RangeVariable, @$, parseInfo);
                        }
                        {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
                        SomeQuantificationTail                                      /* [X] */
    {
        $$ = create(new QuantifiedExpression($<enums.slot>8,
                                             QuantifiedExpression::Some, $<expr>7, $9), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

| SatisfiesClause

EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle
                         {
                            pushVariable($3, quantificationType($4), $6,
                                         VariableDeclaration::RangeVariable, @$, parseInfo);
                         }
                         {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
                         EveryQuantificationTail                                    /* [X] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new QuantifiedExpression($<enums.slot>8,
                                             QuantifiedExpression::Every, $<expr>6, $9), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

EveryQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
                         {
                            $<expr>$ = pushVariable($3, quantificationType($4), $6,
                                                    VariableDeclaration::RangeVariable, @$, parseInfo);
                         }
                         {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
                         EveryQuantificationTail                                    /* [X] */
    {
        $$ = create(new QuantifiedExpression($<enums.slot>8,
                                             QuantifiedExpression::Every, $<expr>7, $9), @$, parseInfo);
        parseInfo->finalizePushedVariable();
    }

| SatisfiesClause

SatisfiesClause: SATISFIES ExprSingle                                               /* [X] */
    {
        $$ = $2;
    }

/*
 * Typeswitches are re-written to a combination between @c if clauses, <tt>instance of</tt>, and
 * @c let bindings. For example, the query:
 *
 * @code
 * typeswitch(input)
 * case element()             return <!-- a comment -->
 * case $i as attribute(name) return name($i)
 * default                    return "Didn't match"
 * @endcode
 *
 * becomes:
 *
 * @code
 * if(input instance of element())
 * then <!-- a comment -->
 * else if(input instance of attribute(name))
 *      then let $i as attribute(name) := input return name($i)
 *      else "Didn't match"
 * @endcode
 */

TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN
                {
                    parseInfo->typeswitchSource.push($3);
                }
                CaseClause                                                          /* [43] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        parseInfo->typeswitchSource.pop();
        $$ = $6;
    }

CaseClause: CASE CaseVariable SequenceType                                          /* [44] */
    {
        if(!$2.isNull())
        {
            pushVariable($2, $3, parseInfo->typeswitchSource.top(),
                         VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
        }
    }
    RETURN ExprSingle
    {
        /* The variable shouldn't be in-scope for other case branches. */
        if(!$2.isNull())
            parseInfo->finalizePushedVariable();
    }
    CaseTail
    {
        const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), $3), @$, parseInfo));
        $$ = create(new IfThenClause(instanceOf, $6, $8), @$, parseInfo);
    }

CaseTail: CaseClause                                                                /* [X] */
| CaseDefault

CaseVariable: /* Empty. */                                                          /* [X] */
    {
        $$ = QXmlName();
    }

| DOLLAR ElementName AS
    {
        $$ = $2;
    }

CaseDefault: DEFAULT RETURN ExprSingle                                              /* [X] */
    {
        $$ = $3;
    }
| DEFAULT DOLLAR ElementName
    {
        if(!$3.isNull())
        {
            pushVariable($3, parseInfo->typeswitchSource.top()->staticType(),
                         parseInfo->typeswitchSource.top(),
                         VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
        }
    }
  RETURN ExprSingle
    {
        if(!$3.isNull())
            parseInfo->finalizePushedVariable();
        $$ = $6;
    }

IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle                       /* [45] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
    }

OrExpr: AndExpr                                                                     /* [46] */
| OrExpr OR AndExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new OrExpression($1, $3), @$, parseInfo);
    }

AndExpr: ComparisonExpr                                                             /* [47] */
| AndExpr AND ComparisonExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new AndExpression($1, $3), @$, parseInfo);
    }

ComparisonExpr: RangeExpr                                                           /* [48] */
| ValueComp
| GeneralComp
| NodeComp

RangeExpr: AdditiveExpr                                                             /* [49] */
| AdditiveExpr TO AdditiveExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new RangeExpression($1, $3), @$, parseInfo);
    }

AdditiveExpr: MultiplicativeExpr                                                    /* [50] */
| AdditiveExpr AdditiveOperator MultiplicativeExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
    }

AdditiveOperator: PLUS  {$$ = AtomicMathematician::Add;}                            /* [X] */
| MINUS                 {$$ = AtomicMathematician::Substract;}

MultiplicativeExpr: UnionExpr                                                       /* [51] */
| MultiplicativeExpr MultiplyOperator UnionExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
    }

MultiplyOperator: STAR  {$$ = AtomicMathematician::Multiply;}                       /* [X] */
| DIV                   {$$ = AtomicMathematician::Div;}
| IDIV                  {$$ = AtomicMathematician::IDiv;}
| MOD                   {$$ = AtomicMathematician::Mod;}

UnionExpr: IntersectExceptExpr                                                      /* [52] */
| UnionExpr UnionOperator IntersectExceptExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10
                                 | QXmlQuery::XPath20
                                 | QXmlQuery::XmlSchema11IdentityConstraintField
                                 | QXmlQuery::XmlSchema11IdentityConstraintSelector),
                  parseInfo, @$);
        $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
    }

IntersectExceptExpr: InstanceOfExpr                                                 /* [53] */
| IntersectExceptExpr IntersectOperator InstanceOfExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo);
    }

UnionOperator: UNION                                                                /* [X] */
| BAR

IntersectOperator: INTERSECT                                                        /* [X] */
    {
        $$ = CombineNodes::Intersect;
    }
| EXCEPT
    {
        $$ = CombineNodes::Except;
    }

InstanceOfExpr: TreatExpr                                                           /* [54] */
| TreatExpr INSTANCE OF SequenceType
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new InstanceOf($1,
                    SequenceType::Ptr($4)), @$, parseInfo);
    }

TreatExpr: CastableExpr                                                             /* [55] */
| CastableExpr TREAT AS SequenceType
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new TreatAs($1, $4), @$, parseInfo);
    }

CastableExpr: CastExpr                                                              /* [56] */
| CastExpr CASTABLE AS SingleType
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new CastableAs($1, $4), @$, parseInfo);
    }

CastExpr: UnaryExpr                                                                 /* [57] */
| UnaryExpr CAST AS SingleType
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new CastAs($1, $4), @$, parseInfo);
    }

UnaryExpr: ValueExpr                                                                /* [58] */
| UnaryOperator UnaryExpr
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo);
    }

UnaryOperator: PLUS                                                                 /* [X] */
    {
        $$ = AtomicMathematician::Add;
    }
| MINUS
    {
        $$ = AtomicMathematician::Substract;
    }

ValueExpr: ValidateExpr                                                             /* [59] */
| PathExpr
| ExtensionExpr

GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr                          /* [60] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo);
    }

GeneralComparisonOperator: G_EQ {$$ = AtomicComparator::OperatorEqual;}             /* [X] */
| G_NE                          {$$ = AtomicComparator::OperatorNotEqual;}
| G_GE                          {$$ = AtomicComparator::OperatorGreaterOrEqual;}
| G_GT                          {$$ = AtomicComparator::OperatorGreaterThan;}
| G_LE                          {$$ = AtomicComparator::OperatorLessOrEqual;}
| G_LT                          {$$ = AtomicComparator::OperatorLessThan;}

ValueComp: RangeExpr ValueComparisonOperator RangeExpr                              /* [61] */
    {
        $$ = create(new ValueComparison($1, $2, $3), @$, parseInfo);
    }

ValueComparisonOperator: EQ {$$ = AtomicComparator::OperatorEqual;}
| NE                        {$$ = AtomicComparator::OperatorNotEqual;}
| GE                        {$$ = AtomicComparator::OperatorGreaterOrEqual;}
| GT                        {$$ = AtomicComparator::OperatorGreaterThan;}
| LE                        {$$ = AtomicComparator::OperatorLessOrEqual;}
| LT                        {$$ = AtomicComparator::OperatorLessThan;}

NodeComp: RangeExpr NodeOperator RangeExpr                                          /* [62] */
    {
        $$ = create(new NodeComparison($1, $2, $3), @$, parseInfo);
    }

NodeOperator: IS    {$$ = QXmlNodeModelIndex::Is;}                                  /* [X] */
| PRECEDES          {$$ = QXmlNodeModelIndex::Precedes;}
| FOLLOWS           {$$ = QXmlNodeModelIndex::Follows;}

ValidateExpr: ValidationMode EnclosedExpr                                           /* [63] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
                                                          "Hence, %1-expressions may not be used.")
                                           .arg(formatKeyword("validate")),
                                        ReportContext::XQST0075, fromYYLTYPE(@$, parseInfo));
        /*
        $$ = Validate::create($2, $1, parseInfo->staticContext);
        */
    }

/* "A validate expression may optionally specify a validation mode. The
    default validation mode is strict." */
ValidationMode: VALIDATE    {$$ = Validate::Strict;}                                /* [64] */
| VALIDATE STRICT           {$$ = Validate::Strict;}
| VALIDATE LAX              {$$ = Validate::Lax;}

ExtensionExpr: Pragmas EnclosedOptionalExpr                                         /* [65] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        /* We don't support any pragmas, so we only do the
         * necessary validation and use the fallback expression. */

        if($2)
            $$ = $2;
        else
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
                                               "Therefore, a fallback expression "
                                               "must be present"),
                                            ReportContext::XQST0079, fromYYLTYPE(@$, parseInfo));
        }
    }

EnclosedOptionalExpr: CURLY_LBRACE /* empty */ CURLY_RBRACE                         /* [X] */
    {
        $$.reset();
    }
| CURLY_LBRACE Expr CURLY_RBRACE
    {
        $$ = $2;
    }

Pragmas: Pragmas Pragma                                                             /* [X] */
| Pragma

Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END                           /* [66] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }

PragmaContents: /* empty */                                                         /* [67] */
| StringLiteral

PathExpr: SLASH RelativePathExpr                                                    /* [68] */
    {
        /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
        $$ = create(new Path(createRootExpression(parseInfo, @$), $2), @$, parseInfo);
    }

| SLASHSLASH RelativePathExpr
    {
        $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
    }
| SLASH
    {
        /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
        $$ = createRootExpression(parseInfo, @$);
    }

| RelativePathExpr
    /* This is "step", simply. We let bison generate "$$ = $1". */

RelativePathExpr: StepExpr                                                          /* [69] */
| RelativePathExpr MapOrSlash StepExpr
    {
        $$ = create(new Path($1, $3, $2), @$, parseInfo);
    }
| RelativePathExpr MapOrSlash SORT MandatoryOrderByClause RETURN StepExpr END_SORT
    {
        const Expression::Ptr orderBy(createReturnOrderBy($4, $6, parseInfo->orderStability.pop(), @$, parseInfo));

        ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
        const Expression::Ptr path(create(new Path($1, orderBy, $2), @$, parseInfo));

        $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), @$, parseInfo);
    }
| RelativePathExpr SLASHSLASH StepExpr
    {
        $$ = createSlashSlashPath($1, $3, @$, parseInfo);
    }

StepExpr: FilteredAxisStep                                                          /* [70] */
    {
        $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
    }
| FilterExpr
| CURRENT EnclosedExpr
    {
        $$ = create(new CurrentItemStore($2), @$, parseInfo);
    }
| XSLT_VERSION
    {
        const xsDouble version = $1.toDouble();

        parseInfo->isBackwardsCompat.push(version != 2);

        $<enums.Double>$ = version;
    }
    EnclosedExpr
    {
        if($<enums.Double>2 < 2)
            $$ = createCompatStore($3, @$, parseInfo);
        else
            $$ = $3;
    }
| BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE                              /* [X] */
{
    allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
    Q_ASSERT(!$2.isEmpty());
    $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
}

| DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE                         /* [X] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$);
        parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
        const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
        resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5),
                                      StandardLocalNames::empty,
                                      parseInfo->staticContext->namePool()->allocatePrefix($3)));
        parseInfo->staticContext->setNamespaceBindings(resolver);
    }
    Expr
    CURLY_RBRACE
    {
        parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
        $$ = $8;
    }
| CALL_TEMPLATE ElementName LPAREN TemplateWithParameters RPAREN
    {
        $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
        parseInfo->templateWithParametersHandled();
        parseInfo->templateCalls.append($$);
    }

TemplateWithParameters:
    {
        parseInfo->startParsingWithParam();
    }
    TemplateParameters
    {
        parseInfo->endParsingWithParam();
    }

TemplateParameters: /* Empty. */                                                    /* [X] */
    {
    }
| TemplateParameter
    {
    }
| TemplateParameters COMMA TemplateParameter
    {
    }

OptionalTemplateParameters: /* Empty. */                                            /* [X] */
    {
    }
| LPAREN TemplateParameters RPAREN
    {
    }

TemplateParameter: IsTunnel DOLLAR VarName TypeDeclaration OptionalAssign
    {
        /* Note, this grammar rule is invoked for @c xsl:param @em and @c
         * xsl:with-param. */
        const bool isParsingWithParam = parseInfo->isParsingWithParam();

        /**
         * @c xsl:param doesn't make life easy:
         *
         * If it only has @c name, it's default value is an empty
         * string(hence has type @c xs:string), but the value that
         * (maybe) is supplied can be anything, typically a node.
         *
         * Therefore, for that very common case we can't rely on
         * the Expression's type, but have to force it to item()*.
         *
         * So if we're supplied the type item()*, we pass a null
         * SequenceType. TemplateParameterReference recognizes this
         * and has item()* as its static type, regardless of if the
         * expression has a more specific type.
         */
        SequenceType::Ptr type;

        if(!$4->is(CommonSequenceTypes::ZeroOrMoreItems))
            type = $4;

        Expression::Ptr expr;

        /* The default value is an empty sequence. */
        if(!$5 && ((type && $4->cardinality().allowsEmpty())
                   || isParsingWithParam))
            expr = create(new EmptySequence, @$, parseInfo);
        else
            expr = $5;

        /* We ensure we have some type, so CallTemplate, Template and friends
         * are happy. */
        if(!isParsingWithParam && !type)
            type = CommonSequenceTypes::ZeroOrMoreItems;

        if($1)
            /* TODO, handle tunnel parameters. */;
        else
        {
            if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, $3)) ||
               (isParsingWithParam && parseInfo->templateWithParams.contains($3)))
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
                                                                 .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
                                                isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE(@$, parseInfo));
            }
            else
            {
                if(isParsingWithParam)
                    parseInfo->templateWithParams[$3] = WithParam::Ptr(new WithParam($3, $4, expr));
                else
                {
                    Q_ASSERT(type);
                    pushVariable($3, type, expr, VariableDeclaration::TemplateParameter, @$, parseInfo);
                    parseInfo->templateParameters.append(parseInfo->variables.top());
                }
            }
        }
    }

IsTunnel: /* Empty. */
    {
        $$ = false;
    }
| TUNNEL
    {
        $$ = true;
    }

OptionalAssign: /* Empty. */                                                        /* [X] */
    {
        $$ = Expression::Ptr();
    }
| ASSIGN ExprSingle
    {
        $$ = $2;
    }

/**
 * Controls whethers a path expression should sort its result. Used for
 * implementing XSL-T's for-each.
 */
MapOrSlash: SLASH                                                                   /* [X] */
    {
        $$ = Path::RegularPath;
    }
| MAP
    {
        $$ = Path::XSLTForEach;
    }
| FOR_APPLY_TEMPLATE
    {
        $$ = Path::ForApplyTemplate;
    }

FilteredAxisStep: AxisStep                                                          /* [X] */
| FilteredAxisStep LBRACKET Expr RBRACKET
    {
        $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@$, parseInfo)), @$, parseInfo);
    }

AxisStep: ForwardStep                                                               /* [71] */
| ReverseStep

ForwardStep: Axis
             {
                if($1 == QXmlNodeModelIndex::AxisAttribute)
                    parseInfo->nodeTestSource = BuiltinTypes::attribute;
             }
             NodeTestInAxisStep                                                     /* [72] */
    {
        if($3)
        {
            /* A node test was explicitly specified. The un-abbreviated syntax was used. */
            $$ = create(new AxisStep($1, $3), @$, parseInfo);
        }
        else
        {
            /* Quote from 3.2.1.1 Axes
             *
             * [Definition: Every axis has a principal node kind. If an axis
             *  can contain elements, then the principal node kind is element;
             *  otherwise, it is the kind of nodes that the axis can contain.] Thus:
             * - For the attribute axis, the principal node kind is attribute.
             * - For all other axes, the principal node kind is element. */

            if($1 == QXmlNodeModelIndex::AxisAttribute)
                $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), @$, parseInfo);
            else
                $$ = create(new AxisStep($1, BuiltinTypes::element), @$, parseInfo);
        }

        parseInfo->restoreNodeTestSource();
    }
| AbbrevForwardStep

NodeTestInAxisStep: NodeTest
| AnyAttributeTest

Axis: AxisToken COLONCOLON                                                          /* [73] */
    {
        if($1 == QXmlNodeModelIndex::AxisNamespace)
        {
            /* We don't raise XPST0010 here because the namespace axis isn't an optional
             * axis. It simply is not part of the XQuery grammar. */
            parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
                                               .arg(formatKeyword("namespace")),
                                            ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
        }
        else
            $$ = $1;

        switch($1)
        {
            case QXmlNodeModelIndex::AxisAttribute:
            {
                allowedIn(QueryLanguages(  QXmlQuery::XPath20
                                         | QXmlQuery::XQuery10
                                         | QXmlQuery::XmlSchema11IdentityConstraintField
                                         | QXmlQuery::XSLT20),
                          parseInfo, @$);
                break;
            }
            case QXmlNodeModelIndex::AxisChild:
            {
                allowedIn(QueryLanguages(  QXmlQuery::XPath20
                                         | QXmlQuery::XQuery10
                                         | QXmlQuery::XmlSchema11IdentityConstraintField
                                         | QXmlQuery::XmlSchema11IdentityConstraintSelector
                                         | QXmlQuery::XSLT20),
                          parseInfo, @$);
                break;
            }
            default:
            {
                allowedIn(QueryLanguages(  QXmlQuery::XPath20
                                         | QXmlQuery::XQuery10
                                         | QXmlQuery::XSLT20),
                          parseInfo, @$);
            }
        }
    }

AxisToken: ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf  ;}
| ANCESTOR                  {$$ = QXmlNodeModelIndex::AxisAncestor        ;}
| ATTRIBUTE                 {$$ = QXmlNodeModelIndex::AxisAttribute       ;}
| CHILD                     {$$ = QXmlNodeModelIndex::AxisChild           ;}
| DESCENDANT_OR_SELF        {$$ = QXmlNodeModelIndex::AxisDescendantOrSelf;}
| DESCENDANT                {$$ = QXmlNodeModelIndex::AxisDescendant      ;}
| FOLLOWING                 {$$ = QXmlNodeModelIndex::AxisFollowing       ;}
| PRECEDING                 {$$ = QXmlNodeModelIndex::AxisPreceding       ;}
| FOLLOWING_SIBLING         {$$ = QXmlNodeModelIndex::AxisFollowingSibling;}
| PRECEDING_SIBLING         {$$ = QXmlNodeModelIndex::AxisPrecedingSibling;}
| PARENT                    {$$ = QXmlNodeModelIndex::AxisParent          ;}
| SELF                      {$$ = QXmlNodeModelIndex::AxisSelf            ;}

AbbrevForwardStep: AT_SIGN
                   {
                        parseInfo->nodeTestSource = BuiltinTypes::attribute;
                   }
                   NodeTest                                                         /* [72] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$);
        $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo);

        parseInfo->restoreNodeTestSource();
    }
| NodeTest
    {
        ItemType::Ptr nodeTest;

        if(parseInfo->isParsingPattern && *$1 == *BuiltinTypes::node)
            nodeTest = BuiltinTypes::xsltNodeTest;
        else
            nodeTest = $1;

        $$ = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), @$, parseInfo);
    }
| AnyAttributeTest
    {
        $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $1), @$, parseInfo);
    }

ReverseStep: AbbrevReverseStep                                                      /* [75] */

AbbrevReverseStep: DOTDOT                                                           /* [77] */
    {
        $$ = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo);
    }

NodeTest: NameTest                                                                  /* [78] */
| KindTest
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
    }

NameTest: ElementName                                                               /* [79] */
    {
        $$ = QNameTest::create(parseInfo->nodeTestSource, $1);
    }
| WildCard

WildCard: STAR                                                                      /* [80] */
    {
        $$ = parseInfo->nodeTestSource;
    }
| ANY_LOCAL_NAME
    {
        const NamePool::Ptr np(parseInfo->staticContext->namePool());
        const ReflectYYLTYPE ryy(@$, parseInfo);

        const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix($1), parseInfo->staticContext, &ryy));

        $$ = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
    }
| ANY_PREFIX
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
        $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
    }

FilterExpr: PrimaryExpr                                                             /* [81] */
| FilterExpr LBRACKET Expr RBRACKET
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo);
    }

PrimaryExpr: Literal                                                                /* [84] */
| VarRef
| ParenthesizedExpr
| ContextItemExpr
| FunctionCallExpr
| OrderingExpr
| Constructor
| APPLY_TEMPLATE OptionalMode LPAREN TemplateWithParameters RPAREN
    {
        $$ = create(new ApplyTemplate(parseInfo->modeFor($2),
                                      parseInfo->templateWithParams,
                                      parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
                                                                  StandardLocalNames::Default))),
                    @1, parseInfo);
        parseInfo->templateWithParametersHandled();
    }

Literal: NumericLiteral                                                             /* [85] */
| StringLiteral
    {
        $$ = create(new Literal(AtomicString::fromValue($1)), @$, parseInfo);
    }

NumericLiteral: XPATH2_NUMBER                                                       /* [86] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = createNumericLiteral<Double>($1, @$, parseInfo);
    }
| NUMBER
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
    }

VarRef: DOLLAR VarName                                                              /* [87] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = resolveVariable($2, @$, parseInfo, false);
    }

VarName: NCNAME                                                                     /* [88] */
    {
        /* See: http://www.w3.org/TR/xpath20/#id-variables */
        $$ = parseInfo->staticContext->namePool()->allocateQName(QString(), $1);
    }
| QName
    {
        $$ = $1;
    }

ParenthesizedExpr: LPAREN Expr RPAREN                                               /* [89] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = $2;
    }
| LPAREN RPAREN
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new EmptySequence, @$, parseInfo);
    }

ContextItemExpr: DOT                                                                /* [90] */
    {
        $$ = create(new ContextItem(), @$, parseInfo);
    }

OrderingExpr: OrderingMode EnclosedExpr                                             /* [X] */
    {
        $$ = $2;
    }

FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN                      /* [93] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        if(XPathHelper::isReservedNamespace($1.namespaceURI()) || $1.namespaceURI() == StandardNamespaces::InternalXSLT)
        { /* We got a call to a builtin function. */
            const ReflectYYLTYPE ryy(@$, parseInfo);

            const Expression::Ptr
                func(parseInfo->staticContext->
                functionSignatures()->createFunctionCall($1, $3, parseInfo->staticContext, &ryy));

            if(func)
                $$ = create(func, @$, parseInfo);
            else
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("No function by name %1 is available.")
                                                   .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)),
                                                ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
            }
        }
        else /* It's a call to a function created with 'declare function'.*/
        {
            $$ = create(new UserFunctionCallsite($1, $3.count()), @$, parseInfo);

            $$->setOperands($3);
            parseInfo->userFunctionCallsites.append($$);
        }
    }

FunctionArguments: /* empty */                                                      /* [X] */
    {
        $$ = Expression::List();
    }

| ExprSingle
    {
        Expression::List list;
        list.append($1);
        $$ = list;
    }

| ExpressionSequence

Constructor: DirectConstructor                                                      /* [94] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
    }
| ComputedConstructor
/* The reason we cannot call alloweIn() as the action for ComputedConstructor,
 * is that we use the computed constructors for XSL-T, and therefore generate
 * INTERNAL tokens. */

DirectConstructor: DirElemConstructor                                               /* [95] */
| DirCommentConstructor
| DirPIConstructor

/*
 * Direct attribute constructors can contain embedded expressions, and for those namespace bindings
 * on the same element needs to be in scope. For example:
 *
 * @code
 * <element attribute="{prefix:nameTest}" xmlns:prefix="http://example.com/"/>
 * @endcode
 *
 * Patternist is designed to do all name resolution at parse time so the subsequent code only has to
 * deal with expanded QNames(which the QName class represents), and this presents a problem since
 * the parser haven't even encountered the @c xmlns:prefix when resolving @c prefix in the name test.
 *
 * This is solved as follows:
 *
 * <ol>
 *  <li>Just before starting parsing the attributes, we call Tokenizer::commenceScanOnly().
 *      This switches the tokenizer to not tokenize embedded expressions in attributes,
 *      but to return them as strings, token type STRING_LITERAL.</li>
 *  <li>We parse all the attributes, and iterates over them, only caring about
 *      namespace bindings, and validates and adds them to the context.</li>
 *  <li>We call Tokenizer::resumeTokenizationFrom() from the previous position
 *      returned from Tokenizer::commenceScanOnly() and parses the attributes once more,
 *      but this time with tokenization of embedded expressions. Since we this time
 *      have the namespace bindings in place, everything resolves.</li>
 * </ol>
 *
 * Saxon does this in a similar way. Study net.sf.saxon.expr.QueryParser::parseDirectElementConstructor().
 *
 * @see XQueryTokenizer::attributeAsRaw()
 */
DirElemConstructor: G_LT
                    LexicalName
                    {
                        $<enums.tokenizerPosition>$ = parseInfo->tokenizer->commenceScanOnly();
                        parseInfo->scanOnlyStack.push(true);
                    }

                    /* This list contains name/string pairs. No embedded
                     * expressions has been parsed. */
                    DirAttributeList

                    {
                        ++parseInfo->elementConstructorDepth;
                        Expression::List constructors;

                        parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());

                        /* Fix up attributes and namespace declarations. */
                        const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
                        const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
                        const int len = $4.size();
                        QSet<QXmlName::PrefixCode> usedDeclarations;

                        /* Whether xmlns="" has been encountered. */
                        bool hasDefaultDeclaration = false;

                        /* For each attribute & namespace declaration, do: */
                        for(int i = 0; i < len; ++i)
                        {
                            QString strLocalName;
                            QString strPrefix;

                            XPathHelper::splitQName($4.at(i).first, strPrefix, strLocalName);
                            const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);

                            /* This can seem a bit weird. However, this name is ending up in a QXmlName
                             * which consider its prefix a... prefix. So, a namespace binding name can in some cases
                             * be a local name, but that's just as the initial syntactical construct. */
                            const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);

                            /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */

                            if(prefix == StandardPrefixes::xmlns ||
                               (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
                            {
                                if(localName == StandardPrefixes::xmlns)
                                    hasDefaultDeclaration = true;

                                /* We have a namespace declaration. */

                                const Expression::Ptr nsExpr($4.at(i).second);

                                const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());

                                const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);

                                if(ns == StandardNamespaces::empty)
                                {
                                    if(localName != StandardPrefixes::xmlns)
                                    {
                                        parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
                                                                           .arg(formatURI(strPrefix)),
                                                                        ReportContext::XQST0085, fromYYLTYPE(@$, parseInfo));
                                    }
                                }
                                else if(!AnyURI::isValid(strNamespace))
                                {
                                    parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
                                                                    ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
                                }

                                if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
                                {
                                    parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
                                                                       .arg(formatKeyword("xmlns")),
                                                                    ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
                                }

                                if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
                                {
                                    parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
                                                                       .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
                                                                       .arg(formatKeyword("xml")),
                                                                    ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
                                }

                                if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
                                {
                                    parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
                                                                       .arg(formatKeyword("xml"))
                                                                       .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
                                                                    ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
                                }

                                QXmlName nb;

                                if(localName == StandardPrefixes::xmlns)
                                    nb = QXmlName(ns, StandardLocalNames::empty);
                                else
                                    nb = QXmlName(ns, StandardLocalNames::empty, localName);

                                if(usedDeclarations.contains(nb.prefix()))
                                {
                                    parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
                                                                       .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
                                                                    ReportContext::XQST0071, fromYYLTYPE(@$, parseInfo));

                                }
                                else
                                    usedDeclarations.insert(nb.prefix());

                                /* If the user has bound the XML namespace correctly, we in either
                                 * case don't want to output it.
                                 *
                                 * We only have to check the namespace parts since the above checks has ensured
                                 * consistency in the prefix parts. */
                                if(ns != StandardNamespaces::xml)
                                {
                                    /* We don't want default namespace declarations when the
                                     * default namespace already is empty. */
                                    if(!(ns == StandardNamespaces::empty          &&
                                         localName == StandardNamespaces::xmlns   &&
                                         resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
                                    {
                                        constructors.append(create(new NamespaceConstructor(nb), @$, parseInfo));
                                        resolver->addBinding(nb);
                                    }
                                }
                            }
                        }

                        if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
                        {
                            /* TODO But mostly this isn't needed, since the default element
                             * namespace is empty? How does this at all work? */
                            const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
                            constructors.append(create(new NamespaceConstructor(def), @$, parseInfo));
                        }

                        parseInfo->staticContext->setNamespaceBindings(resolver);
                        $<expressionList>$ = constructors;

                        /* Resolve the name of the element, now that the namespace attributes are read. */
                        {
                            const ReflectYYLTYPE ryy(@$, parseInfo);

                            const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
                                                                               ReportContext::XPST0081,
                                                                               ReportContext::XPST0081>($2, parseInfo->staticContext, resolver, &ryy);
                            parseInfo->tagStack.push(ele);
                        }

                        parseInfo->tokenizer->resumeTokenizationFrom($<enums.tokenizerPosition>3);
                    }
                    POSITION_SET
                    DirAttributeList
                    DirElemConstructorTail                         /* [96] */
    {
        /* We add the content constructor after the attribute constructors. This might result
         * in nested ExpressionSequences, but it will be optimized away later on. */

        Expression::List attributes($<expressionList>5);
        const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
        const int len = $7.size();
        QSet<QXmlName> declaredAttributes;
        declaredAttributes.reserve(len);

        /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
         * turn it into an attribute constructor. */
        for(int i = 0; i < len; ++i)
        {
            QString strLocalName;
            QString strPrefix;

            XPathHelper::splitQName($7.at(i).first, strPrefix, strLocalName);
            const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
            const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);

            if(prefix == StandardPrefixes::xmlns ||
               (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
            {
                const Expression::ID id = $7.at(i).second->id();

                if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
                {
                    /* It's a namespace declaration, and we've already handled those above. */
                    continue;
                }
                else
                {
                    parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
                                                       "use enclosed expressions."),
                                                    ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
                }

            }
            else
            {
                const ReflectYYLTYPE ryy(@$, parseInfo);
                const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
                                                                   ReportContext::XPST0081,
                                                                   ReportContext::XPST0081>($7.at(i).first, parseInfo->staticContext,
                                                                                            parseInfo->staticContext->namespaceBindings(),
                                                                                            &ryy, true);
                if(declaredAttributes.contains(att))
                {
                    parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute by name %1 has already appeared on this element.")
                                                      .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
                                            ReportContext::XQST0040, fromYYLTYPE(@$, parseInfo));

                }
                else
                    declaredAttributes.insert(att);

                /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
                 * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
                 * it twice.
                 *
                 * The AttributeConstructor's arguments are just dummies. */
                const Expression::Ptr ctor(create(new AttributeConstructor($7.at(i).second, $7.at(i).second), @$, parseInfo));

                Expression::List ops;
                ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
                ops.append($7.at(i).second);
                ctor->setOperands(ops);

                attributes.append(ctor);
            }
        }

        Expression::Ptr contentOp;

        if(attributes.isEmpty())
            contentOp = $8;
        else
        {
            attributes.append($8);
            contentOp = create(new ExpressionSequence(attributes), @$, parseInfo);
        }

        const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), @$, parseInfo));
        $$ = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), @$, parseInfo);

        /* Restore the old context. We don't want the namespaces
         * to be in-scope for expressions appearing after the
         * element they appeared on. */
        parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
        parseInfo->tagStack.pop();

        --parseInfo->elementConstructorDepth;
    }

DirElemConstructorTail: QUICK_TAG_END
    {
        $$ = create(new EmptySequence(), @$, parseInfo);
    }
| G_GT DirElemContent BEGIN_END_TAG ElementName G_GT
    {
        if(!$4.isLexicallyEqual(parseInfo->tagStack.top()))
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
                                               "well-formed. %1 is ended with %2.")
                                               .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
                                                    formatKeyword(parseInfo->staticContext->namePool()->toLexical($4))),
                                            ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
        }

        if($2.isEmpty())
            $$ = create(new EmptySequence(), @$, parseInfo);
        else if($2.size() == 1)
            $$ = $2.first();
        else
            $$ = create(new ExpressionSequence($2), @$, parseInfo);
    }

DirAttributeList: /* empty */                                                       /* [97] */
    {
        $$ = AttributeHolderVector();
    }
| DirAttributeList Attribute
    {
        $1.append($2);
        $$ = $1;
    }

Attribute: LexicalName G_EQ DirAttributeValue                                       /* [X] */
    {
        $$ = qMakePair($1, $3);
    }

DirAttributeValue: QUOTE AttrValueContent QUOTE                                     /* [98] */
    {
        $$ = createDirAttributeValue($2, parseInfo, @$);
    }

| APOS AttrValueContent APOS
    {
        $$ = createDirAttributeValue($2, parseInfo, @$);
    }

AttrValueContent: /* Empty. */                                                      /* [X] */
    {
        $$ = Expression::List();
    }
| EnclosedExpr AttrValueContent
    {
        Expression::Ptr content($1);

        if(parseInfo->isBackwardsCompat.top())
            content = create(GenericPredicate::createFirstItem(content), @$, parseInfo);

        $2.prepend(createSimpleContent(content, @$, parseInfo));
        $$ = $2;
    }
| StringLiteral AttrValueContent
    {
        $2.prepend(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo));
        $$ = $2;
    }

DirElemContent: /* empty */                                                         /* [101] */
    {
        $$ = Expression::List();
        parseInfo->isPreviousEnclosedExpr = false;
    }
| DirElemContent DirectConstructor
    {
        $1.append($2);
        $$ = $1;
        parseInfo->isPreviousEnclosedExpr = false;
    }
| DirElemContent StringLiteral
    {
        if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
           XPathHelper::isWhitespaceOnly($2))
        {
            $$ = $1;
        }
        else
        {
            $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
            $$ = $1;
            parseInfo->isPreviousEnclosedExpr = false;
        }
    }
| DirElemContent NON_BOUNDARY_WS
    {
        $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
        $$ = $1;
        parseInfo->isPreviousEnclosedExpr = false;
    }
| DirElemContent EnclosedExpr
    {
        /* We insert a text node constructor that send an empty text node between
         * the two enclosed expressions, in order to ensure that no space is inserted.
         *
         * However, we only do it when we have no node constructors. */
        if(parseInfo->isPreviousEnclosedExpr &&
           BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($2->staticType()->itemType()) &&
           BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($1.last()->staticType()->itemType()))
            $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), @$, parseInfo)), @$, parseInfo));
        else
            parseInfo->isPreviousEnclosedExpr = true;

        $1.append(createCopyOf($2, parseInfo, @$));
        $$ = $1;
    }

DirCommentConstructor: COMMENT_START COMMENT_CONTENT                                /* [103] */
    {
        $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
    }

DirPIConstructor: PI_START PI_TARGET PI_CONTENT                                     /* [105] */
    {
        const ReflectYYLTYPE ryy(@$, parseInfo);
        NCNameConstructor::validateTargetName<StaticContext::Ptr,
                                              ReportContext::XPST0003,
                                              ReportContext::XPST0003>($2,
                                                                       parseInfo->staticContext, &ryy);

        $$ = create(new ProcessingInstructionConstructor(
                             create(new Literal(AtomicString::fromValue($2)), @$, parseInfo),
                             create(new Literal(AtomicString::fromValue($3)), @$, parseInfo)), @$, parseInfo);
    }

ComputedConstructor: CompDocConstructor                                             /* [109] */
| CompElemConstructor
| CompAttrConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
| CompNamespaceConstructor

CompDocConstructor: DOCUMENT IsInternal EnclosedExpr                                /* [110] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        $$ = create(new DocumentConstructor($3), @$, parseInfo);
    }

CompElemConstructor: ELEMENT IsInternal CompElementName
                     {
                        /* This value is incremented before the action below is executed. */
                        ++parseInfo->elementConstructorDepth;
                     }
                     EnclosedOptionalExpr                                           /* [111] */
    {
        Q_ASSERT(5);
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        Expression::Ptr effExpr;

        if($5)
            effExpr = createCopyOf($5, parseInfo, @$);
        else
            effExpr = create(new EmptySequence(), @$, parseInfo);

        const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);

        /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
         * a child of another constructor, it has already been done. */
        if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
        {
            Expression::List exprList;

            /* We append the namespace constructor before the body, in order to
             * comply with QAbstractXmlPushHandler's contract. */
            const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
            exprList.append(create(new NamespaceConstructor(def), @$, parseInfo));

            exprList.append(effExpr);

            effExpr = create(new ExpressionSequence(exprList), @$, parseInfo);
        }

        --parseInfo->elementConstructorDepth;
        $$ = create(new ElementConstructor($3, effExpr, parseInfo->isXSLT()), @$, parseInfo);
    }

IsInternal: /* Empty. */                                                          /* [X] */
    {
        $$ = false;
    }
| INTERNAL
    {
        $$ = true;
    }

CompAttrConstructor: ATTRIBUTE
                     IsInternal
                     CompAttributeName
                     EnclosedOptionalExpr                                           /* [113] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo));

        if($4)
            $$ = create(new AttributeConstructor(name, createSimpleContent($4, @$, parseInfo)), @$, parseInfo);
        else
            $$ = create(new AttributeConstructor(name, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
    }

CompTextConstructor: TEXT IsInternal EnclosedExpr                                 /* [114] */
    {
        $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
    }

CompCommentConstructor: COMMENT IsInternal EnclosedExpr                           /* [115] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
    }

CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr           /* [116] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

        if($3)
        {
            $$ = create(new ProcessingInstructionConstructor($2, createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
        }
        else
            $$ = create(new ProcessingInstructionConstructor($2, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
    }

CompAttributeName: {
                        parseInfo->nodeTestSource = BuiltinTypes::attribute;
                   }
                   ElementName
                   {
                        parseInfo->restoreNodeTestSource();
                   }                                                                /* [X] */
    {
        $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $2))), @$, parseInfo);
    }
| CompNameExpr

CompElementName: ElementName                                                        /* [X] */
    {
        $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $1))), @$, parseInfo);
    }
| CompNameExpr

CompNameExpr: EnclosedExpr
    {
        if(BuiltinTypes::xsQName->xdtTypeMatches($1->staticType()->itemType()))
            $$ = $1;
        else
        {
            $$ = create(new QNameConstructor($1,
                                             parseInfo->staticContext->namespaceBindings()),
                        @$, parseInfo);
        }
    }

/*
 * We always create an NCNameConstructor here. If will be rewritten away if not needed.
 */
CompPIName: NCNAME
    {
        $$ = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo)), @$, parseInfo);
    }
| EnclosedExpr
    {
        $$ = create(new NCNameConstructor($1), @$, parseInfo);
    }

/*
 * This expression is used for implementing XSL-T 2.0's xsl:namespace
 * instruction.
 */
CompNamespaceConstructor: NAMESPACE EnclosedExpr EnclosedExpr                       /* [X] */
{
    $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
}

SingleType: AtomicType                                                              /* [117] */
    {
        $$ = makeGenericSequenceType($1, Cardinality::exactlyOne());
    }
| AtomicType QUESTION
    {
        $$ = makeGenericSequenceType($1, Cardinality::zeroOrOne());
    }

TypeDeclaration: /* empty */                                                        /* [118] */
    {
        $$ = CommonSequenceTypes::ZeroOrMoreItems;
    }
| AS SequenceType
    {
        $$ = $2;
    }

SequenceType: ItemType OccurrenceIndicator                                          /* [119] */
    {
        $$ = makeGenericSequenceType($1, $2);
    }

| EMPTY_SEQUENCE EmptyParanteses
    {
        $$ = CommonSequenceTypes::Empty;
    }

OccurrenceIndicator: /* empty */    {$$ = Cardinality::exactlyOne();}               /* [120] */
| PLUS                              {$$ = Cardinality::oneOrMore();}
| STAR                              {$$ = Cardinality::zeroOrMore();}
| QUESTION                          {$$ = Cardinality::zeroOrOne();}

ItemType: AtomicType                                                                /* [121] */
| KindTest
| AnyAttributeTest
| ITEM EmptyParanteses
    {
        $$ = BuiltinTypes::item;
    }

AtomicType: ElementName                                                             /* [122] */
    {
        const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($1));

        if(!t)
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
                                               .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)), ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
        }
        else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
            $$ = AtomicType::Ptr(t);
        else
        {
            /* Try to give an intelligent message. */
            if(t->isComplexType())
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
                                                   "types is not possible. However, casting "
                                                   "to atomic types such as %2 works.")
                                                   .arg(formatType(parseInfo->staticContext->namePool(), t))
                                                   .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
                                                ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
            }
            else
            {
                parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
                                                   "is only possible to atomic types.")
                                                   .arg(formatType(parseInfo->staticContext->namePool(), t)),
                                                ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
            }
        }
    }

/* This non-terminal does not contain SchemaAttributeTest and AttributeTest.
   Those are in the AnyAttributeTest non-terminal. This is in order to get the axis
   right for attribute tests in the abbreviated syntax. */
KindTest: DocumentTest                                                          /* [123] */
| ElementTest
| SchemaElementTest
| PITest
| CommentTest
| TextTest
| AnyKindTest

AnyKindTest: NODE EmptyParanteses                                               /* [124] */
    {
        $$ = BuiltinTypes::node;
    }

DocumentTest: DOCUMENT_NODE EmptyParanteses                                     /* [125] */
    {
        $$ = BuiltinTypes::document;
    }

| DOCUMENT_NODE LPAREN AnyElementTest RPAREN
    {
        // TODO support for document element testing
        $$ = BuiltinTypes::document;
    }

AnyElementTest: ElementTest                                                     /* [X] */
| SchemaElementTest

TextTest: TEXT EmptyParanteses                                                  /* [126] */
    {
        $$ = BuiltinTypes::text;
    }

CommentTest: COMMENT EmptyParanteses                                            /* [127] */
    {
        $$ = BuiltinTypes::comment;
    }

PITest: PROCESSING_INSTRUCTION EmptyParanteses                                  /* [128] */
    {
        $$ = BuiltinTypes::pi;
    }

| PROCESSING_INSTRUCTION LPAREN NCNAME RPAREN
    {
        $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
    }

| PROCESSING_INSTRUCTION LPAREN StringLiteral RPAREN
    {
        if(QXmlUtils::isNCName($3))
        {
            $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
        }
        else
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
                                                              "processing-instruction.")
                                                 .arg(formatKeyword($3)),
                                            ReportContext::XPTY0004,
                                            fromYYLTYPE(@$, parseInfo));
        }
    }

AnyAttributeTest: AttributeTest
| SchemaAttributeTest

AttributeTest: ATTRIBUTE EmptyParanteses                                            /* [129] */
    {
        $$ = BuiltinTypes::attribute;
    }

| ATTRIBUTE LPAREN STAR RPAREN
    {
        $$ = BuiltinTypes::attribute;
    }

| ATTRIBUTE LPAREN AttributeName RPAREN
    {
        $$ = QNameTest::create(BuiltinTypes::attribute, $3);
    }
| ATTRIBUTE LPAREN AttributeName COMMA TypeName RPAREN
    {
        const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));

        if(t)
            $$ = BuiltinTypes::attribute;
        else
        {
            parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                            ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        }
    }
| ATTRIBUTE LPAREN STAR COMMA TypeName RPAREN
    {
        const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));

        if(t)
            $$ = BuiltinTypes::attribute;
        else
        {
            parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                            ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        }
    }

SchemaAttributeTest: SCHEMA_ATTRIBUTE LPAREN ElementName RPAREN                     /* [131] */
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
                                           "declarations. Note that the schema import "
                                           "feature is not supported.")
                                           .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
                                        ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        $$.reset();
    }

ElementTest: ELEMENT EmptyParanteses                                                /* [133] */
    {
        $$ = BuiltinTypes::element;
    }

| ELEMENT LPAREN STAR RPAREN
    {
        $$ = BuiltinTypes::element;
    }

| ELEMENT LPAREN ElementName RPAREN
    {
        $$ = QNameTest::create(BuiltinTypes::element, $3);
    }

| ELEMENT LPAREN ElementName COMMA TypeName OptionalQuestionMark RPAREN
    {
        const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));

        if(t)
            $$ = BuiltinTypes::element;
        else
        {
            parseInfo->staticContext->error(unknownType()
                                               .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                            ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        }
    }

| ELEMENT LPAREN STAR COMMA TypeName OptionalQuestionMark RPAREN
    {
        const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));

        if(t)
            $$ = BuiltinTypes::element;
        else
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
                                               .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                            ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        }
    }

OptionalQuestionMark: /* Empty. */
| QUESTION

SchemaElementTest: SCHEMA_ELEMENT LPAREN ElementName RPAREN                         /* [135] */
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
                                           "declarations. Note that the schema import "
                                           "feature is not supported.")
                                           .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
                                        ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
        $$.reset();
    }

EmptyParanteses: LPAREN RPAREN                                                      /* [X] */

AttributeName: NCNAME                                                               /* [137] */
    {
        $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
    }

| QName

/*
 * When a QName appear with no prefix, it uses a certain default namespace
 * depending on where the QName occurs. These two rules, invoked in the appropriate
 * contexts, performs this distinction.
 */
ElementName: NCNAME                                                                 /* [138] */
    {
        if(parseInfo->nodeTestSource == BuiltinTypes::element)
            $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), $1);
        else
            $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
    }
| QName

TypeName: ElementName                                                               /* [139] */

FunctionName: NCName                                                                /* [X] */
| QName

NCName: NCNAME
    {
        $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
    }
| INTERNAL_NAME NCNAME
    {
        $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
    }

LexicalName: NCNAME
| QNAME

PragmaName: NCNAME                                                                  /* [X] */
    {
        parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
                                                          "a namespace."),
                                        ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
    }
| QName

URILiteral: StringLiteral                                                           /* [140] */

StringLiteral: STRING_LITERAL                                                       /* [144] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
    }
| XPATH2_STRING_LITERAL
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
    }

QName: QNAME                                                      /* [154] */
    {

        const ReflectYYLTYPE ryy(@$, parseInfo);

        $$ = QNameConstructor::
             expandQName<StaticContext::Ptr,
                         ReportContext::XPST0081,
                         ReportContext::XPST0081>($1, parseInfo->staticContext,
                                                  parseInfo->staticContext->namespaceBindings(), &ryy);

    }
| CLARK_NAME
    {
        $$ = parseInfo->staticContext->namePool()->fromClarkName($1);
    }

%%

QString Tokenizer::tokenToString(const Token &token)
{
    switch(token.type)
    {
        case NCNAME:
        /* Fallthrough. */
        case QNAME:
        /* Fallthrough. */
        case NUMBER:
        /* Fallthrough. */
        case XPATH2_NUMBER:
            return token.value;
        case STRING_LITERAL:
            return QLatin1Char('"') + token.value + QLatin1Char('"');
        default:
        {
            const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));

            /* Remove the quotes. */
            if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
                return raw.mid(1, raw.length() - 2);
            else
                return raw;
        }
    }
}

} /* namespace Patternist */

QT_END_NAMESPACE

// vim: et:ts=4:sw=4:sts=4:syntax=yacc
