/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $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) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtXmlPatterns module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $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 <private/qabstractfloat_p.h>
#include <private/qandexpression_p.h>
#include <private/qanyuri_p.h>
#include <private/qapplytemplate_p.h>
#include <private/qargumentreference_p.h>
#include <private/qarithmeticexpression_p.h>
#include <private/qatomicstring_p.h>
#include <private/qattributeconstructor_p.h>
#include <private/qattributenamevalidator_p.h>
#include <private/qaxisstep_p.h>
#include <private/qbuiltintypes_p.h>
#include <private/qcalltemplate_p.h>
#include <private/qcastableas_p.h>
#include <private/qcastas_p.h>
#include <private/qcombinenodes_p.h>
#include <private/qcommentconstructor_p.h>
#include <private/qcommonnamespaces_p.h>
#include <private/qcommonsequencetypes_p.h>
#include <private/qcommonvalues_p.h>
#include <private/qcomputednamespaceconstructor_p.h>
#include <private/qcontextitem_p.h>
#include <private/qcopyof_p.h>
#include <private/qcurrentitemstore_p.h>
#include <private/qdebug_p.h>
#include <private/qdelegatingnamespaceresolver_p.h>
#include <private/qdocumentconstructor_p.h>
#include <private/qelementconstructor_p.h>
#include <private/qemptysequence_p.h>
#include <private/qemptysequencetype_p.h>
#include <private/qevaluationcache_p.h>
#include <private/qexpressionfactory_p.h>
#include <private/qexpressionsequence_p.h>
#include <private/qexpressionvariablereference_p.h>
#include <private/qexternalvariablereference_p.h>
#include <private/qforclause_p.h>
#include <private/qfunctioncall_p.h>
#include <private/qfunctionfactory_p.h>
#include <private/qfunctionsignature_p.h>
#include <private/qgeneralcomparison_p.h>
#include <private/qgenericpredicate_p.h>
#include <private/qgenericsequencetype_p.h>
#include <private/qifthenclause_p.h>
#include <private/qinstanceof_p.h>
#include <private/qletclause_p.h>
#include <private/qliteral_p.h>
#include <private/qlocalnametest_p.h>
#include <private/qnamespaceconstructor_p.h>
#include <private/qnamespacenametest_p.h>
#include <private/qncnameconstructor_p.h>
#include <private/qnodecomparison_p.h>
#include <private/qnodesort_p.h>
#include <private/qorderby_p.h>
#include <private/qorexpression_p.h>
#include <private/qparsercontext_p.h>
#include <private/qpath_p.h>
#include <private/qpatternistlocale_p.h>
#include <private/qpositionalvariablereference_p.h>
#include <private/qprocessinginstructionconstructor_p.h>
#include <private/qqnameconstructor_p.h>
#include <private/qqnametest_p.h>
#include <private/qqnamevalue_p.h>
#include <private/qquantifiedexpression_p.h>
#include <private/qrangeexpression_p.h>
#include <private/qrangevariablereference_p.h>
#include <private/qreturnorderby_p.h>
#include <private/qschemanumeric_p.h>
#include <private/qschematypefactory_p.h>
#include <private/qsimplecontentconstructor_p.h>
#include <private/qstaticbaseuristore_p.h>
#include <private/qstaticcompatibilitystore_p.h>
#include <private/qtemplateparameterreference_p.h>
#include <private/qtemplate_p.h>
#include <private/qtextnodeconstructor_p.h>
#include <private/qtokenizer_p.h>
#include <private/qtreatas_p.h>
#include <private/qtypechecker_p.h>
#include <private/qunaryexpression_p.h>
#include <private/qunresolvedvariablereference_p.h>
#include <private/quserfunctioncallsite_p.h>
#include <private/qvaluecomparison_p.h>
#include <private/qxpathhelper_p.h>
#include <private/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

#define YYLTYPE_IS_TRIVIAL 0
#define YYINITDEPTH 1
#define yyoverflow parseInfo->handleStackOverflow

/* 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 with 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:
        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.data()), 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.data()), 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    {QT_PREPEND_NAMESPACE(QPatternist)::ParserContext *const parseInfo}
%lex-param      {QT_PREPEND_NAMESPACE(QPatternist)::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> T_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> T_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> T_XPATH2_STRING_LITERAL         "<string literal(XPath 2.0)>"
%token <sval> T_QNAME                         "QName"
%token <sval> T_NCNAME                        "NCName"

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

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

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

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

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

%token T_ANCESTOR                             "ancestor"
%token T_ANCESTOR_OR_SELF                     "ancestor-or-self"
%token T_AND                                  "and"
%token T_APOS                                 "'"
%token T_APPLY_TEMPLATE                       "apply-template"
%token T_AS                                   "as"
%token T_ASCENDING                            "ascending"
%token T_ASSIGN                               ":="
%token T_AT                                   "at"
%token T_AT_SIGN                              "@"
%token T_ATTRIBUTE                            "attribute"
%token T_AVT                                  /* Synthetic token. Signals an attribute value template. */
%token T_BAR                                  "|"
%token T_BASEURI                              "base-uri"
%token T_BEGIN_END_TAG                        "</"
%token T_BOUNDARY_SPACE                       "boundary-space"
%token T_BY                                   "by"
%token T_CALL_TEMPLATE                        "call-template"
%token T_CASE                                 "case"
%token T_CASTABLE                             "castable"
%token T_CAST                                 "cast"
%token T_CHILD                                "child"
%token T_COLLATION                            "collation"
%token T_COLONCOLON                           "::"
%token T_COMMA                                ","
%token T_COMMENT                              "comment"
%token T_COMMENT_START                        "<!--"
%token T_CONSTRUCTION                         "construction"
%token T_COPY_NAMESPACES                      "copy-namespaces"
%token T_CURLY_LBRACE                         "{"
%token T_CURLY_RBRACE                         "}"
%token T_DECLARE                              "declare"
%token T_DEFAULT                              "default"
%token T_DESCENDANT                           "descendant"
%token T_DESCENDANT_OR_SELF                   "descendant-or-self"
%token T_DESCENDING                           "descending"
%token T_DIV                                  "div"
%token T_DOCUMENT                             "document"
%token T_DOCUMENT_NODE                        "document-node"
%token T_DOLLAR                               "$"
%token T_DOT                                  "."
%token T_DOTDOT                               ".."
%token T_ELEMENT                              "element"
%token T_ELSE                                 "else"
%token T_EMPTY                                "empty"
%token T_EMPTY_SEQUENCE                       "empty-sequence"
%token T_ENCODING                             "encoding"
%token T_END_OF_FILE 0                        "end of file"
%token T_END_SORT                             "end_sort"
%token T_EQ                                   "eq"
%token T_ERROR                                "unknown keyword" /* Used by the Tokenizer. We use the phrase "keyword" instead of "token" to be less pointy.  */
%token T_EVERY                                "every"
%token T_EXCEPT                               "except"
%token T_EXTERNAL                             "external"
%token T_FOLLOWING                            "following"
%token T_FOLLOWING_SIBLING                    "following-sibling"
%token T_FOLLOWS                              ">>"
%token T_FOR_APPLY_TEMPLATE                   "for-apply-template" /* Synthetic token, used in XSL-T. */
%token T_FOR                                  "for"
%token T_FUNCTION                             "function"
%token T_GE                                   "ge"
%token T_G_EQ                                 "="
%token T_G_GE                                 ">="
%token T_G_GT                                 ">"
%token T_G_LE                                 "<="
%token T_G_LT                                 "<"
%token T_G_NE                                 "!="
%token T_GREATEST                             "greatest"
%token T_GT                                   "gt"
%token T_IDIV                                 "idiv"
%token T_IF                                   "if"
%token T_IMPORT                               "import"
%token T_INHERIT                              "inherit"
%token T_IN                                   "in"
%token T_INSTANCE                             "instance"
%token T_INTERSECT                            "intersect"
%token T_IS                                   "is"
%token T_ITEM                                 "item"
%token T_LAX                                  "lax"
%token T_LBRACKET                             "["
%token T_LEAST                                "least"
%token T_LE                                   "le"
%token T_LET                                  "let"
%token T_LPAREN                               "("
%token T_LT                                   "lt"
%token T_MAP                                  "map" /* Synthetic token, used in XSL-T. */
%token T_MATCHES                              "matches"
%token T_MINUS                                "-"
%token T_MODE                                 "mode" /* Synthetic token, used in XSL-T. */
%token T_MOD                                  "mod"
%token T_MODULE                               "module"
%token T_NAME                                 "name"
%token T_NAMESPACE                            "namespace"
%token T_NE                                   "ne"
%token T_NODE                                 "node"
%token T_NO_INHERIT                           "no-inherit"
%token T_NO_PRESERVE                          "no-preserve"
%token T_OF                                   "of"
%token T_OPTION                               "option"
%token T_ORDERED                              "ordered"
%token T_ORDERING                             "ordering"
%token T_ORDER                                "order"
%token T_OR                                   "or"
%token T_PARENT                               "parent"
%token T_PI_START                             "<?"
%token T_PLUS                                 "+"
%token T_POSITION_SET                         /* Synthetic token. */
%token T_PRAGMA_END                           "#)"
%token T_PRAGMA_START                         "(#"
%token T_PRECEDES                             "<<"
%token T_PRECEDING                            "preceding"
%token T_PRECEDING_SIBLING                    "preceding-sibling"
%token T_PRESERVE                             "preserve"
%token T_PRIORITY                             "priority"
%token T_PROCESSING_INSTRUCTION               "processing-instruction"
%token T_QUESTION                             "?"
%token T_QUICK_TAG_END                        "/>"
%token T_QUOTE                                "\""
%token T_RBRACKET                             "]"
%token T_RETURN                               "return"
%token T_RPAREN                               ")"
%token T_SATISFIES                            "satisfies"
%token T_SCHEMA_ATTRIBUTE                     "schema-attribute"
%token T_SCHEMA_ELEMENT                       "schema-element"
%token T_SCHEMA                               "schema"
%token T_SELF                                 "self"
%token T_SEMI_COLON                           ";"
%token T_SLASH                                "/"
%token T_SLASHSLASH                           "//"
%token T_SOME                                 "some"
%token T_SORT                                 "sort" /* Synthetic token, used in XSL-T. */
%token T_STABLE                               "stable"
%token T_STAR                                 "*"
%token T_STRICT                               "strict"
%token T_STRIP                                "strip"
%token T_SUCCESS                              /* Synthetic token, used by the Tokenizer. */
%token <sval> T_COMMENT_CONTENT
%token <sval> T_PI_CONTENT
%token <sval> T_PI_TARGET
%token <sval> T_XSLT_VERSION                  /* Synthetic token, used in XSL-T. */
%token T_TEMPLATE                             "template"
%token T_TEXT                                 "text"
%token T_THEN                                 "then"
%token T_TO                                   "to"
%token T_TREAT                                "treat"
%token T_TUNNEL                               "tunnel" /* Synthetic token, used in XSL-T. */
%token T_TYPESWITCH                           "typeswitch"
%token T_UNION                                "union"
%token T_UNORDERED                            "unordered"
%token T_VALIDATE                             "validate"
%token T_VARIABLE                             "variable"
%token T_VERSION                              "version"
%token T_WHERE                                "where"
%token T_XQUERY                               "xquery"
%token T_INTERNAL                             "internal" /* Synthetic token, used in XSL-T. */
%token T_INTERNAL_NAME                        "internal-name" /* Synthetic token, used in XSL-T. */
%token T_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 T_STAR T_DIV
%left T_PLUS T_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] */
| T_XQUERY T_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] */
| T_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: T_MODULE T_NAMESPACE T_NCNAME T_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: T_DECLARE T_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();
    }
| T_DECLARE T_TEMPLATE OptionalTemplateName
  T_MATCHES T_LPAREN
  {
    parseInfo->isParsingPattern = true;
  }
  Pattern
  {
    parseInfo->isParsingPattern = false;
  }
  T_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();
    }

| T_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: T_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: T_SEMI_COLON                                                               /* [9] */

NamespaceDecl: T_DECLARE T_NAMESPACE T_NCNAME T_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: T_DECLARE T_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: T_STRIP                                                          /* [X] */
    {
        $$ = StaticContext::BSPStrip;
    }

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

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

DeclareDefaultElementNamespace: T_DECLARE T_DEFAULT T_ELEMENT T_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: T_DECLARE T_DEFAULT T_FUNCTION T_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: T_DECLARE T_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: T_DECLARE T_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: T_ORDERED
    {
        $$ = StaticContext::Ordered;
    }
| T_UNORDERED
    {
        $$ = StaticContext::Unordered;
    }

EmptyOrderDecl: T_DECLARE T_DEFAULT T_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: T_EMPTY T_LEAST                                                  /* [X] */
    {
        $$ = StaticContext::Least;
    }
| T_EMPTY T_GREATEST
    {
        $$ = StaticContext::Greatest;
    }

CopyNamespacesDecl: T_DECLARE T_COPY_NAMESPACES PreserveMode T_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: T_PRESERVE                                                              /* [17] */
    {
        parseInfo->preserveNamespacesMode = true;
    }

| T_NO_PRESERVE
    {
        parseInfo->preserveNamespacesMode = false;
    }

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

| T_NO_INHERIT
    {
        parseInfo->inheritNamespacesMode = false;
    }

DefaultCollationDecl: T_DECLARE T_DEFAULT T_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: T_DECLARE T_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: T_IMPORT T_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] */
| T_DEFAULT T_ELEMENT T_NAMESPACE
| T_NAMESPACE T_NCNAME T_G_EQ

ModuleImport: T_IMPORT T_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] */
| T_NAMESPACE T_NCNAME T_G_EQ

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

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

VarDecl: T_DECLARE T_VARIABLE IsInternal T_DOLLAR VarName TypeDeclaration
         VariableValue OptionalDefaultValue Separator                               /* [24] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
        if(variableByName($5, parseInfo))
        {
            parseInfo->staticContext->error(QtXmlPatterns::tr("A variable with 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 with name %1.")
                                                       .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
                                                    parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
                                                    fromYYLTYPE(@$, parseInfo));
                }
            }
        }
    }

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

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

ConstructionDecl: T_DECLARE T_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: T_STRIP                                                             /* [X] */
    {
        $$ = StaticContext::CMStrip;
    }
| T_PRESERVE
    {
        $$ = StaticContext::CMPreserve;
    }

FunctionDecl: T_DECLARE T_FUNCTION IsInternal FunctionName T_LPAREN ParamList T_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 T_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 with 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: T_DOLLAR VarName TypeDeclaration                                               /* [28] */
    {
        pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
        $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
    }

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

EnclosedExpr: T_CURLY_LBRACE Expr T_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 T_BAR PathPattern
    {
        $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
    }

PathPattern: RelativePathPattern                                                    /* [XSLT20-2] */
| T_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);
    }
| T_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;
        }
    }
| T_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 T_SLASH RelativePathPattern
    {
        createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
    }
| IdKeyPattern T_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 T_SLASH PatternStep
    {
        $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
    }
| RelativePathPattern T_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 T_COMMA ExprSingle                                     /* [X] */
    {
        Expression::List l;
        l.append($1);
        l.append($3);
        $$ = l;
    }
| ExpressionSequence T_COMMA ExprSingle
    {
        $1.append($3);
        $$ = $1;
    }

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

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

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

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

Mode: QName                                                                         /* [X] */
    {
        $$ = $1;
    }
| T_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: T_FOR T_DOLLAR VarName TypeDeclaration
           PositionalVar T_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: T_COMMA T_DOLLAR VarName TypeDeclaration
         PositionalVar T_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;
    }

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

LetClause: T_LET IsInternal T_DOLLAR VarName TypeDeclaration T_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: T_COMMA T_DOLLAR VarName TypeDeclaration T_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 T_RETURN ExprSingle                                        /* [37] */
    {
        if($1.isEmpty())
            $$ = $3;
        else
            $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
    }

| T_WHERE ExprSingle OrderByClause T_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 T_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;
    }

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

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

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

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

OrderByInputOrder: T_STABLE T_ORDER T_BY                                                  /* [X] */
    {
        parseInfo->orderStability.push(OrderBy::StableOrder);
    }
| T_ORDER T_BY
    {
        parseInfo->orderStability.push(OrderBy::UnstableOrder);
    }

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

SomeQuantificationExpr: T_SOME T_DOLLAR VarName TypeDeclaration T_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: T_COMMA T_DOLLAR VarName TypeDeclaration T_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: T_EVERY T_DOLLAR VarName TypeDeclaration T_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: T_COMMA T_DOLLAR VarName TypeDeclaration T_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: T_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: T_TYPESWITCH T_LPAREN Expr T_RPAREN
                {
                    parseInfo->typeswitchSource.push($3);
                }
                CaseClause                                                          /* [43] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
        parseInfo->typeswitchSource.pop();
        $$ = $6;
    }

CaseClause: T_CASE CaseVariable SequenceType                                          /* [44] */
    {
        if(!$2.isNull())
        {
            pushVariable($2, $3, parseInfo->typeswitchSource.top(),
                         VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
        }
    }
    T_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();
    }

| T_DOLLAR ElementName T_AS
    {
        $$ = $2;
    }

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

IfExpr: T_IF T_LPAREN Expr T_RPAREN T_THEN ExprSingle T_ELSE ExprSingle                       /* [45] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
    }

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

AndExpr: ComparisonExpr                                                             /* [47] */
| AndExpr T_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 T_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: T_PLUS  {$$ = AtomicMathematician::Add;}                            /* [X] */
| T_MINUS                 {$$ = AtomicMathematician::Substract;}

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

MultiplyOperator: T_STAR  {$$ = AtomicMathematician::Multiply;}                       /* [X] */
| T_DIV                   {$$ = AtomicMathematician::Div;}
| T_IDIV                  {$$ = AtomicMathematician::IDiv;}
| T_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: T_UNION                                                                /* [X] */
| T_BAR

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

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

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

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

CastExpr: UnaryExpr                                                                 /* [57] */
| UnaryExpr T_CAST T_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: T_PLUS                                                                 /* [X] */
    {
        $$ = AtomicMathematician::Add;
    }
| T_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: T_G_EQ {$$ = AtomicComparator::OperatorEqual;}             /* [X] */
| T_G_NE                          {$$ = AtomicComparator::OperatorNotEqual;}
| T_G_GE                          {$$ = AtomicComparator::OperatorGreaterOrEqual;}
| T_G_GT                          {$$ = AtomicComparator::OperatorGreaterThan;}
| T_G_LE                          {$$ = AtomicComparator::OperatorLessOrEqual;}
| T_G_LT                          {$$ = AtomicComparator::OperatorLessThan;}

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

ValueComparisonOperator: T_EQ {$$ = AtomicComparator::OperatorEqual;}
| T_NE                        {$$ = AtomicComparator::OperatorNotEqual;}
| T_GE                        {$$ = AtomicComparator::OperatorGreaterOrEqual;}
| T_GT                        {$$ = AtomicComparator::OperatorGreaterThan;}
| T_LE                        {$$ = AtomicComparator::OperatorLessOrEqual;}
| T_LT                        {$$ = AtomicComparator::OperatorLessThan;}

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

NodeOperator: T_IS    {$$ = QXmlNodeModelIndex::Is;}                                  /* [X] */
| T_PRECEDES          {$$ = QXmlNodeModelIndex::Precedes;}
| T_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: T_VALIDATE    {$$ = Validate::Strict;}                                /* [64] */
| T_VALIDATE T_STRICT           {$$ = Validate::Strict;}
| T_VALIDATE T_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: T_CURLY_LBRACE /* empty */ T_CURLY_RBRACE                         /* [X] */
    {
        $$.reset();
    }
| T_CURLY_LBRACE Expr T_CURLY_RBRACE
    {
        $$ = $2;
    }

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

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

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

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

| T_SLASHSLASH RelativePathExpr
    {
        $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
    }
| T_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 T_SORT MandatoryOrderByClause T_RETURN StepExpr T_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 T_SLASHSLASH StepExpr
    {
        $$ = createSlashSlashPath($1, $3, @$, parseInfo);
    }

StepExpr: FilteredAxisStep                                                          /* [70] */
    {
        $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
    }
| FilterExpr
| T_CURRENT EnclosedExpr
    {
        $$ = create(new CurrentItemStore($2), @$, parseInfo);
    }
| T_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;
    }
| T_BASEURI StringLiteral T_CURLY_LBRACE Expr T_CURLY_RBRACE                              /* [X] */
{
    allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
    Q_ASSERT(!$2.isEmpty());
    $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
}

| T_DECLARE T_NAMESPACE T_NCNAME T_G_EQ T_STRING_LITERAL T_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
    T_CURLY_RBRACE
    {
        parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
        $$ = $8;
    }
| T_CALL_TEMPLATE ElementName T_LPAREN TemplateWithParameters T_RPAREN
    {
        $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
        parseInfo->templateWithParametersHandled();
        parseInfo->templateCalls.append($$);
    }

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

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

OptionalTemplateParameters: /* Empty. */                                            /* [X] */
    {
    }
| T_LPAREN TemplateParameters T_RPAREN
    {
    }

TemplateParameter: IsTunnel T_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;
    }
| T_TUNNEL
    {
        $$ = true;
    }

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

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

FilteredAxisStep: AxisStep                                                          /* [X] */
| FilteredAxisStep T_LBRACKET Expr T_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 T_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: T_ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf  ;}
| T_ANCESTOR                  {$$ = QXmlNodeModelIndex::AxisAncestor        ;}
| T_ATTRIBUTE                 {$$ = QXmlNodeModelIndex::AxisAttribute       ;}
| T_CHILD                     {$$ = QXmlNodeModelIndex::AxisChild           ;}
| T_DESCENDANT_OR_SELF        {$$ = QXmlNodeModelIndex::AxisDescendantOrSelf;}
| T_DESCENDANT                {$$ = QXmlNodeModelIndex::AxisDescendant      ;}
| T_FOLLOWING                 {$$ = QXmlNodeModelIndex::AxisFollowing       ;}
| T_PRECEDING                 {$$ = QXmlNodeModelIndex::AxisPreceding       ;}
| T_FOLLOWING_SIBLING         {$$ = QXmlNodeModelIndex::AxisFollowingSibling;}
| T_PRECEDING_SIBLING         {$$ = QXmlNodeModelIndex::AxisPrecedingSibling;}
| T_PARENT                    {$$ = QXmlNodeModelIndex::AxisParent          ;}
| T_SELF                      {$$ = QXmlNodeModelIndex::AxisSelf            ;}

AbbrevForwardStep: T_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: T_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: T_STAR                                                                      /* [80] */
    {
        $$ = parseInfo->nodeTestSource;
    }
| T_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);
    }
| T_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 T_LBRACKET Expr T_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
| T_APPLY_TEMPLATE OptionalMode T_LPAREN TemplateWithParameters T_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: T_XPATH2_NUMBER                                                       /* [86] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = createNumericLiteral<Double>($1, @$, parseInfo);
    }
| T_NUMBER
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
        $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
    }

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

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

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

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

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

FunctionCallExpr: FunctionName T_LPAREN FunctionArguments T_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 with 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: T_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);
                    }
                    T_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 with 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: T_QUICK_TAG_END
    {
        $$ = create(new EmptySequence(), @$, parseInfo);
    }
| T_G_GT DirElemContent T_BEGIN_END_TAG ElementName T_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 T_G_EQ DirAttributeValue                                       /* [X] */
    {
        $$ = qMakePair($1, $3);
    }

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

| T_APOS AttrValueContent T_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 T_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: T_COMMENT_START T_COMMENT_CONTENT                                /* [103] */
    {
        $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
    }

DirPIConstructor: T_PI_START T_PI_TARGET T_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: T_DOCUMENT IsInternal EnclosedExpr                                /* [110] */
    {
        allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);

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

CompElemConstructor: T_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;
    }
| T_INTERNAL
    {
        $$ = true;
    }

CompAttrConstructor: T_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: T_TEXT IsInternal EnclosedExpr                                 /* [114] */
    {
        $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
    }

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

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

CompPIConstructor: T_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: T_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: T_NAMESPACE EnclosedExpr EnclosedExpr                       /* [X] */
{
    $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
}

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

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

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

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

OccurrenceIndicator: /* empty */    {$$ = Cardinality::exactlyOne();}               /* [120] */
| T_PLUS                              {$$ = Cardinality::oneOrMore();}
| T_STAR                              {$$ = Cardinality::zeroOrMore();}
| T_QUESTION                          {$$ = Cardinality::zeroOrOne();}

ItemType: AtomicType                                                                /* [121] */
| KindTest
| AnyAttributeTest
| T_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: T_NODE EmptyParanteses                                               /* [124] */
    {
        $$ = BuiltinTypes::node;
    }

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

| T_DOCUMENT_NODE T_LPAREN AnyElementTest T_RPAREN
    {
        // TODO support for document element testing
        $$ = BuiltinTypes::document;
    }

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

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

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

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

| T_PROCESSING_INSTRUCTION T_LPAREN T_NCNAME T_RPAREN
    {
        $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
    }

| T_PROCESSING_INSTRUCTION T_LPAREN StringLiteral T_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: T_ATTRIBUTE EmptyParanteses                                            /* [129] */
    {
        $$ = BuiltinTypes::attribute;
    }

| T_ATTRIBUTE T_LPAREN T_STAR T_RPAREN
    {
        $$ = BuiltinTypes::attribute;
    }

| T_ATTRIBUTE T_LPAREN AttributeName T_RPAREN
    {
        $$ = QNameTest::create(BuiltinTypes::attribute, $3);
    }
| T_ATTRIBUTE T_LPAREN AttributeName T_COMMA TypeName T_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));
        }
    }
| T_ATTRIBUTE T_LPAREN T_STAR T_COMMA TypeName T_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: T_SCHEMA_ATTRIBUTE T_LPAREN ElementName T_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: T_ELEMENT EmptyParanteses                                                /* [133] */
    {
        $$ = BuiltinTypes::element;
    }

| T_ELEMENT T_LPAREN T_STAR T_RPAREN
    {
        $$ = BuiltinTypes::element;
    }

| T_ELEMENT T_LPAREN ElementName T_RPAREN
    {
        $$ = QNameTest::create(BuiltinTypes::element, $3);
    }

| T_ELEMENT T_LPAREN ElementName T_COMMA TypeName OptionalQuestionMark T_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));
        }
    }

| T_ELEMENT T_LPAREN T_STAR T_COMMA TypeName OptionalQuestionMark T_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. */
| T_QUESTION

SchemaElementTest: T_SCHEMA_ELEMENT T_LPAREN ElementName T_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: T_LPAREN T_RPAREN                                                      /* [X] */

AttributeName: T_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: T_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: T_NCNAME
    {
        $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
    }
| T_INTERNAL_NAME T_NCNAME
    {
        $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
    }

LexicalName: T_NCNAME
| T_QNAME

PragmaName: T_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: T_STRING_LITERAL                                                       /* [144] */
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
    }
| T_XPATH2_STRING_LITERAL
    {
        allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
    }

QName: T_QNAME                                                      /* [154] */
    {

        const ReflectYYLTYPE ryy(@$, parseInfo);

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

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

%%

QString Tokenizer::tokenToString(const Token &token)
{
    switch(token.type)
    {
        case T_NCNAME:
        case T_QNAME:
        case T_NUMBER:
        case T_XPATH2_NUMBER:
            return token.value;
        case T_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
