src/xmlpatterns/parser/querytransformparser.ypp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 //
       
    43 //  W A R N I N G
       
    44 //  -------------
       
    45 //
       
    46 // This file is not part of the Qt API.  It exists purely as an
       
    47 // implementation detail.  This header file may change from version to
       
    48 // version without notice, or even be removed.
       
    49 //
       
    50 // We mean it.
       
    51 
       
    52 %{
       
    53 /****************************************************************************
       
    54 **
       
    55 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
    56 ** All rights reserved.
       
    57 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
    58 **
       
    59 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
       
    60 **
       
    61 ** $QT_BEGIN_LICENSE:LGPL$
       
    62 ** No Commercial Usage
       
    63 ** This file contains pre-release code and may not be distributed.
       
    64 ** You may use this file in accordance with the terms and conditions
       
    65 ** contained in the Technology Preview License Agreement accompanying
       
    66 ** this package.
       
    67 **
       
    68 ** GNU Lesser General Public License Usage
       
    69 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    70 ** General Public License version 2.1 as published by the Free Software
       
    71 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    72 ** packaging of this file.  Please review the following information to
       
    73 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    74 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    75 **
       
    76 ** In addition, as a special exception, Nokia gives you certain additional
       
    77 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    78 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    79 **
       
    80 ** If you have questions regarding the use of this file, please contact
       
    81 ** Nokia at qt-info@nokia.com.
       
    82 **
       
    83 **
       
    84 **
       
    85 **
       
    86 **
       
    87 **
       
    88 **
       
    89 **
       
    90 ** $QT_END_LICENSE$
       
    91 **
       
    92 ****************************************************************************/
       
    93 
       
    94 //
       
    95 //  W A R N I N G
       
    96 //  -------------
       
    97 //
       
    98 // This file is not part of the Qt API.  It exists purely as an
       
    99 // implementation detail.  This header file may change from version to
       
   100 // version without notice, or even be removed.
       
   101 //
       
   102 // We mean it.
       
   103 
       
   104 #include <limits>
       
   105 
       
   106 #include <QUrl>
       
   107 
       
   108 #include "qabstractfloat_p.h"
       
   109 #include "qandexpression_p.h"
       
   110 #include "qanyuri_p.h"
       
   111 #include "qapplytemplate_p.h"
       
   112 #include "qargumentreference_p.h"
       
   113 #include "qarithmeticexpression_p.h"
       
   114 #include "qatomicstring_p.h"
       
   115 #include "qattributeconstructor_p.h"
       
   116 #include "qattributenamevalidator_p.h"
       
   117 #include "qaxisstep_p.h"
       
   118 #include "qbuiltintypes_p.h"
       
   119 #include "qcalltemplate_p.h"
       
   120 #include "qcastableas_p.h"
       
   121 #include "qcastas_p.h"
       
   122 #include "qcombinenodes_p.h"
       
   123 #include "qcommentconstructor_p.h"
       
   124 #include "qcommonnamespaces_p.h"
       
   125 #include "qcommonsequencetypes_p.h"
       
   126 #include "qcommonvalues_p.h"
       
   127 #include "qcomputednamespaceconstructor_p.h"
       
   128 #include "qcontextitem_p.h"
       
   129 #include "qcopyof_p.h"
       
   130 #include "qcurrentitemstore_p.h"
       
   131 #include "qdebug_p.h"
       
   132 #include "qdelegatingnamespaceresolver_p.h"
       
   133 #include "qdocumentconstructor_p.h"
       
   134 #include "qelementconstructor_p.h"
       
   135 #include "qemptysequence_p.h"
       
   136 #include "qemptysequencetype_p.h"
       
   137 #include "qevaluationcache_p.h"
       
   138 #include "qexpressionfactory_p.h"
       
   139 #include "qexpressionsequence_p.h"
       
   140 #include "qexpressionvariablereference_p.h"
       
   141 #include "qexternalvariablereference_p.h"
       
   142 #include "qforclause_p.h"
       
   143 #include "qfunctioncall_p.h"
       
   144 #include "qfunctionfactory_p.h"
       
   145 #include "qfunctionsignature_p.h"
       
   146 #include "qgeneralcomparison_p.h"
       
   147 #include "qgenericpredicate_p.h"
       
   148 #include "qgenericsequencetype_p.h"
       
   149 #include "qifthenclause_p.h"
       
   150 #include "qinstanceof_p.h"
       
   151 #include "qletclause_p.h"
       
   152 #include "qliteral_p.h"
       
   153 #include "qlocalnametest_p.h"
       
   154 #include "qnamespaceconstructor_p.h"
       
   155 #include "qnamespacenametest_p.h"
       
   156 #include "qncnameconstructor_p.h"
       
   157 #include "qnodecomparison_p.h"
       
   158 #include "qnodesort_p.h"
       
   159 #include "qorderby_p.h"
       
   160 #include "qorexpression_p.h"
       
   161 #include "qparsercontext_p.h"
       
   162 #include "qpath_p.h"
       
   163 #include "qpatternistlocale_p.h"
       
   164 #include "qpositionalvariablereference_p.h"
       
   165 #include "qprocessinginstructionconstructor_p.h"
       
   166 #include "qqnameconstructor_p.h"
       
   167 #include "qqnametest_p.h"
       
   168 #include "qqnamevalue_p.h"
       
   169 #include "qquantifiedexpression_p.h"
       
   170 #include "qrangeexpression_p.h"
       
   171 #include "qrangevariablereference_p.h"
       
   172 #include "qreturnorderby_p.h"
       
   173 #include "qschemanumeric_p.h"
       
   174 #include "qschematypefactory_p.h"
       
   175 #include "qsimplecontentconstructor_p.h"
       
   176 #include "qstaticbaseuristore_p.h"
       
   177 #include "qstaticcompatibilitystore_p.h"
       
   178 #include "qtemplateparameterreference_p.h"
       
   179 #include "qtemplate_p.h"
       
   180 #include "qtextnodeconstructor_p.h"
       
   181 #include "qtokenizer_p.h"
       
   182 #include "qtreatas_p.h"
       
   183 #include "qtypechecker_p.h"
       
   184 #include "qunaryexpression_p.h"
       
   185 #include "qunresolvedvariablereference_p.h"
       
   186 #include "quserfunctioncallsite_p.h"
       
   187 #include "qvaluecomparison_p.h"
       
   188 #include "qxpathhelper_p.h"
       
   189 #include "qxsltsimplecontentconstructor_p.h"
       
   190 
       
   191 /*
       
   192  * The cpp generated with bison 2.1 wants to
       
   193  * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
       
   194  */
       
   195 #define YYMALLOC malloc
       
   196 #define YYFREE free
       
   197 
       
   198 QT_BEGIN_NAMESPACE
       
   199 
       
   200 /* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
       
   201  * undocumented reason. */
       
   202 namespace QPatternist
       
   203 {
       
   204 
       
   205 /**
       
   206  * "Macro that you define with #define in the Bison declarations
       
   207  * section to request verbose, specific error message strings when
       
   208  * yyerror is called."
       
   209  */
       
   210 #define YYERROR_VERBOSE 1
       
   211 
       
   212 #undef YYLTYPE_IS_TRIVIAL
       
   213 #define YYLTYPE_IS_TRIVIAL 0
       
   214 
       
   215 /* Suppresses `warning: "YYENABLE_NLS" is not defined`
       
   216  * @c YYENABLE_NLS enables Bison internationalization, and we don't
       
   217  * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
       
   218  */
       
   219 #define YYENABLE_NLS 0
       
   220 
       
   221 static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
       
   222                                           const ParserContext *const parseInfo)
       
   223 {
       
   224     return QSourceLocation(parseInfo->tokenizer->queryURI(),
       
   225                            sourceLocator.first_line,
       
   226                            sourceLocator.first_column);
       
   227 }
       
   228 
       
   229 /**
       
   230  * @internal
       
   231  * @relates QXmlQuery
       
   232  */
       
   233 typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
       
   234 
       
   235 /**
       
   236  * @short Flags invalid expressions and declarations in the currently
       
   237  * parsed language.
       
   238  *
       
   239  * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
       
   240  * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
       
   241  * identity constraints, it is the union of all the constructs in these
       
   242  * languages. However, when dealing with each language individually, we
       
   243  * regularly need to disallow some expressions, such as direct element
       
   244  * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
       
   245  *
       
   246  * This is further complicated by that XSLTTokenizer sometimes generates code
       
   247  * which is allowed in XQuery but not in XPath. For that reason the token
       
   248  * INTERNAL is sometimes generated, which signals that an expression, for
       
   249  * instance the @c let clause, should not be flagged as an error, because it's
       
   250  * used for internal purposes.
       
   251  *
       
   252  * Hence, this function is called from each expression and declaration with @p
       
   253  * allowedLanguages stating what languages it is allowed in.
       
   254  *
       
   255  * If @p isInternal is @c true, no error is raised. Otherwise, if the current
       
   256  * language is not in @p allowedLanguages, an error is raised.
       
   257  */
       
   258 static void allowedIn(const QueryLanguages allowedLanguages,
       
   259                       const ParserContext *const parseInfo,
       
   260                       const YYLTYPE &sourceLocator,
       
   261                       const bool isInternal = false)
       
   262 {
       
   263     /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
       
   264      * and XSL-T is the language, it's ok. */
       
   265     if(!isInternal &&
       
   266        (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
       
   267     {
       
   268 
       
   269         QString langName;
       
   270 
       
   271         switch(parseInfo->languageAccent)
       
   272         {
       
   273             case QXmlQuery::XPath20:
       
   274                 langName = QLatin1String("XPath 2.0");
       
   275                 break;
       
   276             case QXmlQuery::XSLT20:
       
   277                 langName = QLatin1String("XSL-T 2.0");
       
   278                 break;
       
   279             case QXmlQuery::XQuery10:
       
   280                 langName = QLatin1String("XQuery 1.0");
       
   281                 break;
       
   282             case QXmlQuery::XmlSchema11IdentityConstraintSelector:
       
   283                 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
       
   284                 break;
       
   285             case QXmlQuery::XmlSchema11IdentityConstraintField:
       
   286                 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
       
   287                 break;
       
   288         }
       
   289 
       
   290         parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
       
   291                                                           "which is disallowed in the current language(%1).").arg(langName),
       
   292                                         ReportContext::XPST0003,
       
   293                                         fromYYLTYPE(sourceLocator, parseInfo));
       
   294 
       
   295     }
       
   296 }
       
   297 
       
   298 static inline bool isVariableReference(const Expression::ID id)
       
   299 {
       
   300     return    id == Expression::IDExpressionVariableReference
       
   301            || id == Expression::IDRangeVariableReference
       
   302            || id == Expression::IDArgumentReference;
       
   303 }
       
   304 
       
   305 class ReflectYYLTYPE : public SourceLocationReflection
       
   306 {
       
   307 public:
       
   308     inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
       
   309                           const ParserContext *const pi) : m_sl(sourceLocator)
       
   310                                                          , m_parseInfo(pi)
       
   311     {
       
   312     }
       
   313 
       
   314     virtual const SourceLocationReflection *actualReflection() const
       
   315     {
       
   316         return this;
       
   317     }
       
   318 
       
   319     virtual QSourceLocation sourceLocation() const
       
   320     {
       
   321         return fromYYLTYPE(m_sl, m_parseInfo);
       
   322     }
       
   323 
       
   324     virtual QString description() const
       
   325     {
       
   326         Q_ASSERT(false);
       
   327         return QString();
       
   328     }
       
   329 
       
   330 private:
       
   331     const YYLTYPE &m_sl;
       
   332     const ParserContext *const m_parseInfo;
       
   333 };
       
   334 
       
   335 /**
       
   336  * @short Centralizes a translation string for the purpose of increasing consistency.
       
   337  */
       
   338 static inline QString unknownType()
       
   339 {
       
   340     return QtXmlPatterns::tr("%1 is an unknown schema type.");
       
   341 }
       
   342 
       
   343 static inline Expression::Ptr create(Expression *const expr,
       
   344                                      const YYLTYPE &sourceLocator,
       
   345                                      const ParserContext *const parseInfo)
       
   346 {
       
   347     parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
       
   348     return Expression::Ptr(expr);
       
   349 }
       
   350 
       
   351 static inline Template::Ptr create(Template *const expr,
       
   352                                    const YYLTYPE &sourceLocator,
       
   353                                    const ParserContext *const parseInfo)
       
   354 {
       
   355     parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
       
   356     return Template::Ptr(expr);
       
   357 }
       
   358 
       
   359 static inline Expression::Ptr create(const Expression::Ptr &expr,
       
   360                                      const YYLTYPE &sourceLocator,
       
   361                                      const ParserContext *const parseInfo)
       
   362 {
       
   363     parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
       
   364     return expr;
       
   365 }
       
   366 
       
   367 static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
       
   368                                            const YYLTYPE &sourceLocator,
       
   369                                            const ParserContext *const parseInfo)
       
   370 {
       
   371     return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
       
   372                   sourceLocator,
       
   373                   parseInfo);
       
   374 }
       
   375 
       
   376 static void loadPattern(const Expression::Ptr &matchPattern,
       
   377                         TemplatePattern::Vector &ourPatterns,
       
   378                         const TemplatePattern::ID id,
       
   379                         const PatternPriority priority,
       
   380                         const Template::Ptr &temp)
       
   381 {
       
   382     Q_ASSERT(temp);
       
   383 
       
   384     const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
       
   385 
       
   386     ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
       
   387 }
       
   388 
       
   389 static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
       
   390                                              const SequenceType::Ptr &reqType,
       
   391                                              const ParserContext *const parseInfo)
       
   392 {
       
   393     return TypeChecker::applyFunctionConversion(body, reqType,
       
   394                                                 parseInfo->staticContext,
       
   395                                                 ReportContext::XTTE0505,
       
   396                                                 TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
       
   397 }
       
   398 
       
   399 static void registerNamedTemplate(const QXmlName &name,
       
   400                                   const Expression::Ptr &body,
       
   401                                   ParserContext *const parseInfo,
       
   402                                   const YYLTYPE &sourceLocator,
       
   403                                   const Template::Ptr &temp)
       
   404 {
       
   405     Template::Ptr &e = parseInfo->namedTemplates[name];
       
   406 
       
   407     if(e)
       
   408     {
       
   409         parseInfo->staticContext->error(QtXmlPatterns::tr("A template by name %1 "
       
   410                                                           "has already been declared.")
       
   411                                         .arg(formatKeyword(parseInfo->staticContext->namePool(),
       
   412                                                                          name)),
       
   413                                         ReportContext::XTSE0660,
       
   414                                         fromYYLTYPE(sourceLocator, parseInfo));
       
   415     }
       
   416     else
       
   417     {
       
   418         e = temp;
       
   419         e->body = body;
       
   420     }
       
   421 }
       
   422 
       
   423 /**
       
   424  * @short Centralizes code for creating numeric literals.
       
   425  */
       
   426 template<typename TNumberClass>
       
   427 Expression::Ptr createNumericLiteral(const QString &in,
       
   428                                      const YYLTYPE &sl,
       
   429                                      const ParserContext *const parseInfo)
       
   430 {
       
   431     const Item num(TNumberClass::fromLexical(in));
       
   432 
       
   433     if(num.template as<AtomicValue>()->hasError())
       
   434     {
       
   435         parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
       
   436                                            .arg(formatData(in)),
       
   437                                         ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
       
   438         return Expression::Ptr(); /* Avoid compiler warning. */
       
   439     }
       
   440     else
       
   441         return create(new Literal(num), sl, parseInfo);
       
   442 }
       
   443 
       
   444 /**
       
   445  * @short The generated Bison parser calls this function when there is a parse error.
       
   446  *
       
   447  * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
       
   448  * ReportContext::error() is called.
       
   449  */
       
   450 static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
       
   451 {
       
   452     Q_UNUSED(sourceLocator);
       
   453     Q_ASSERT(parseInfo);
       
   454 
       
   455     parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
       
   456     return 1;
       
   457 }
       
   458 
       
   459 /**
       
   460  * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
       
   461  * as @c where and @c let inbetween. We need to continue through them. This function does that.
       
   462  */
       
   463 static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
       
   464 {
       
   465     Q_ASSERT(expr);
       
   466 
       
   467     const Expression::ID id = expr->id();
       
   468     if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
       
   469         return locateReturnClause(expr->operands()[1]);
       
   470     else if(id == Expression::IDReturnOrderBy)
       
   471         return expr->as<ReturnOrderBy>();
       
   472     else
       
   473         return 0;
       
   474 }
       
   475 
       
   476 static inline bool isPredicate(const Expression::ID id)
       
   477 {
       
   478     return id == Expression::IDGenericPredicate ||
       
   479            id == Expression::IDFirstItemPredicate;
       
   480 }
       
   481 
       
   482 /**
       
   483  * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
       
   484  * through the predicates and returns the AxisStep.
       
   485  */
       
   486 static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
       
   487                                     const bool throughStructures = true)
       
   488 {
       
   489     Q_ASSERT(expr);
       
   490 
       
   491     if(!throughStructures)
       
   492         return expr;
       
   493 
       
   494     Expression *candidate = expr.data();
       
   495     Expression::ID id = candidate->id();
       
   496 
       
   497     while(isPredicate(id) || id == Expression::IDPath)
       
   498     {
       
   499         const Expression::List &children = candidate->operands();
       
   500         if(children.isEmpty())
       
   501             return Expression::Ptr();
       
   502         else
       
   503         {
       
   504             candidate = children.first().data();
       
   505             id = candidate->id();
       
   506         }
       
   507     }
       
   508 
       
   509     if(id == Expression::IDEmptySequence)
       
   510         return Expression::Ptr();
       
   511     else
       
   512     {
       
   513         Q_ASSERT(candidate->is(Expression::IDAxisStep));
       
   514         return Expression::Ptr(candidate);
       
   515     }
       
   516 }
       
   517 
       
   518 static void changeToTopAxis(const Expression::Ptr &op)
       
   519 {
       
   520     /* This axis must have been written away by now. */
       
   521     Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
       
   522 
       
   523     if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
       
   524         op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
       
   525 }
       
   526 
       
   527 /**
       
   528  * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
       
   529  * into an equivalent XPath expression.
       
   530  *
       
   531  * Essentially, the following rewrite is done:
       
   532  *
       
   533  * <tt>
       
   534  * axis1::test1(a)/axis2::test2(b)
       
   535  *              =>
       
   536  * child-or-top::test2(b)[parent::test1(a)]
       
   537  * </tt>
       
   538  *
       
   539  * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
       
   540  * only the first step in a pattern, but since we're doing rewrites more radically,
       
   541  * its line of reasoning cannot be followed.
       
   542  *
       
   543  * Keep in mind the rewrites that non-terminal PatternStep do.
       
   544  *
       
   545  * @see createIdPatternPath()
       
   546  */
       
   547 static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
       
   548                                                 const Expression::Ptr &operand2,
       
   549                                                 const QXmlNodeModelIndex::Axis axis,
       
   550                                                 const YYLTYPE &sl,
       
   551                                                 const ParserContext *const parseInfo)
       
   552 {
       
   553     const Expression::Ptr operandL(findAxisStep(operand1, false));
       
   554 
       
   555     if(operandL->is(Expression::IDAxisStep))
       
   556         operandL->as<AxisStep>()->setAxis(axis);
       
   557     else
       
   558         findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
       
   559 
       
   560     return create(GenericPredicate::create(operand2, operandL,
       
   561                                            parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
       
   562 }
       
   563 
       
   564 /**
       
   565  * @short Performs the same role as createPatternPath(), but is tailored
       
   566  * for @c fn:key() and @c fn:id().
       
   567  *
       
   568  * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
       
   569  * to be precise) and that poses a challenge to rewriting because what
       
   570  * createPatternPath() is not possible to express, since the functions cannot be
       
   571  * node tests. E.g, this rewrite is not possible:
       
   572  *
       
   573  * <tt>
       
   574  * id-or-key/abc
       
   575  *  =>
       
   576  * child-or-top::abc[parent::id-or-key]
       
   577  * </tt>
       
   578  *
       
   579  * Our approach is to rewrite like this:
       
   580  *
       
   581  * <tt>
       
   582  * id-or-key/abc
       
   583  * =>
       
   584  * child-or-top::abc[parent::node is id-or-key]
       
   585  * </tt>
       
   586  *
       
   587  * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
       
   588  * the right operand, and @p axis the target axis to rewrite to.
       
   589  *
       
   590  * @see createPatternPath()
       
   591  */
       
   592 static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
       
   593                                                   const Expression::Ptr &operand2,
       
   594                                                   const QXmlNodeModelIndex::Axis axis,
       
   595                                                   const YYLTYPE &sl,
       
   596                                                   const ParserContext *const parseInfo)
       
   597 {
       
   598     const Expression::Ptr operandR(findAxisStep(operand2));
       
   599     Q_ASSERT(operandR);
       
   600     changeToTopAxis(operandR);
       
   601 
       
   602     const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
       
   603                                             sl,
       
   604                                             parseInfo));
       
   605     const Expression::Ptr isComp(create(new NodeComparison(parentStep,
       
   606                                                            QXmlNodeModelIndex::Is,
       
   607                                                            operand1),
       
   608                                          sl,
       
   609                                          parseInfo));
       
   610 
       
   611     return create(GenericPredicate::create(operandR, isComp,
       
   612                                            parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
       
   613 }
       
   614 
       
   615 /**
       
   616  * @short Centralizes a translation message, for the
       
   617  * purpose of consistency and modularization.
       
   618  */
       
   619 static inline QString prologMessage(const char *const msg)
       
   620 {
       
   621     Q_ASSERT(msg);
       
   622     return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
       
   623 }
       
   624 
       
   625 /**
       
   626  * @short Resolves against the static base URI and checks that @p collation
       
   627  * is a supported Unicode Collation.
       
   628  *
       
   629  * "If a default collation declaration specifies a collation by a
       
   630  *  relative URI, that relative URI is resolved to an absolute
       
   631  *  URI using the base URI in the static context."
       
   632  *
       
   633  * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
       
   634  */
       
   635 template<const ReportContext::ErrorCode errorCode>
       
   636 static QUrl resolveAndCheckCollation(const QString &collation,
       
   637                                      const ParserContext *const parseInfo,
       
   638                                      const YYLTYPE &sl)
       
   639 {
       
   640     Q_ASSERT(parseInfo);
       
   641     const ReflectYYLTYPE ryy(sl, parseInfo);
       
   642 
       
   643     QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
       
   644 
       
   645     if(uri.isRelative())
       
   646         uri = parseInfo->staticContext->baseURI().resolved(uri);
       
   647 
       
   648     XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
       
   649 
       
   650     return uri;
       
   651 }
       
   652 
       
   653 /* The Bison generated parser declares macros that aren't used
       
   654  * so suppress the warnings by fake usage of them.
       
   655  *
       
   656  * We do the same for some more defines in the first action. */
       
   657 #if    defined(YYLSP_NEEDED)    \
       
   658     || defined(YYBISON)         \
       
   659     || defined(YYBISON_VERSION) \
       
   660     || defined(YYPURE)          \
       
   661     || defined(yydebug)         \
       
   662     || defined(YYSKELETON_NAME)
       
   663 #endif
       
   664 
       
   665 /**
       
   666  * Wraps @p operand with a CopyOf in case it makes any difference.
       
   667  *
       
   668  * There is no need to wrap the return value in a call to create(), it's
       
   669  * already done.
       
   670  */
       
   671 static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
       
   672                                     const ParserContext *const parseInfo,
       
   673                                     const YYLTYPE &sl)
       
   674 {
       
   675     return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
       
   676                              parseInfo->preserveNamespacesMode), sl, parseInfo);
       
   677 }
       
   678 
       
   679 static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
       
   680                                          const YYLTYPE &sourceLocator,
       
   681                                          const ParserContext *const parseInfo)
       
   682 {
       
   683     return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
       
   684 }
       
   685 
       
   686 /**
       
   687  * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
       
   688  * <tt>fn:root(self::node()) treat as document-node()</tt>.
       
   689  */
       
   690 static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
       
   691                                             const YYLTYPE &sl)
       
   692 {
       
   693     Q_ASSERT(parseInfo);
       
   694     const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
       
   695 
       
   696     Expression::List args;
       
   697     args.append(create(new ContextItem(), sl, parseInfo));
       
   698 
       
   699     const ReflectYYLTYPE ryy(sl, parseInfo);
       
   700 
       
   701     const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
       
   702                                  ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
       
   703     Q_ASSERT(fnRoot);
       
   704 
       
   705     return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
       
   706 }
       
   707 
       
   708 static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
       
   709 {
       
   710 #ifdef Patternist_DEBUG_PARSER
       
   711     /**
       
   712      * "External integer variable set to zero by default. If yydebug
       
   713      *  is given a nonzero value, the parser will output information on
       
   714      *  input symbols and parser action. See section Debugging Your Parser."
       
   715      */
       
   716 #   define YYDEBUG 1
       
   717 
       
   718     extern int XPathdebug;
       
   719     XPathdebug = 1;
       
   720 #endif
       
   721 
       
   722     Q_ASSERT(parseInfo);
       
   723 
       
   724     const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
       
   725 
       
   726     (*lexVal).sval = tok.value;
       
   727 
       
   728     return static_cast<int>(tok.type);
       
   729 }
       
   730 
       
   731 /**
       
   732  * @short Creates a path expression which contains the step <tt>//</tt> between
       
   733  * @p begin and and @p end.
       
   734  *
       
   735  * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
       
   736  *
       
   737  * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
       
   738  */
       
   739 static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
       
   740                                             const Expression::Ptr &end,
       
   741                                             const YYLTYPE &sourceLocator,
       
   742                                             const ParserContext *const parseInfo)
       
   743 {
       
   744     const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
       
   745     const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));
       
   746 
       
   747     return create(new Path(p1, end), sourceLocator, parseInfo);
       
   748 }
       
   749 
       
   750 /**
       
   751  * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
       
   752  */
       
   753 static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
       
   754                                              const Expression::List &args,
       
   755                                              const YYLTYPE &sourceLocator)
       
   756 {
       
   757     Q_ASSERT(parseInfo);
       
   758     const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
       
   759     const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
       
   760 
       
   761     return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
       
   762                   sourceLocator, parseInfo);
       
   763 }
       
   764 
       
   765 static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
       
   766                                                       const ParserContext *const parseInfo,
       
   767                                                       const YYLTYPE &sourceLocator)
       
   768 {
       
   769     if(content.isEmpty())
       
   770         return create(new EmptySequence(), sourceLocator, parseInfo);
       
   771     else if(content.size() == 1)
       
   772         return content.first();
       
   773     else
       
   774         return createConcatFN(parseInfo, content, sourceLocator);
       
   775 }
       
   776 
       
   777 /**
       
   778  * @short Checks for variable initialization circularity.
       
   779  *
       
   780  * "A recursive function that checks for recursion is full of ironies."
       
   781  *
       
   782  *      -- The Salsa Master
       
   783  *
       
   784  * Issues an error via @p parseInfo's StaticContext if the initialization
       
   785  * expression @p checkee for the global variable @p var, contains a variable
       
   786  * reference to @p var. That is, if there's a circularity.
       
   787  *
       
   788  * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
       
   789  * Query Language, err:XQST0054</a>
       
   790  */
       
   791 static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
       
   792                                      const Expression::Ptr &checkee,
       
   793                                      const VariableDeclaration::Type type,
       
   794                                      FunctionSignature::List &signList,
       
   795                                      const ParserContext *const parseInfo)
       
   796 {
       
   797     Q_ASSERT(var);
       
   798     Q_ASSERT(checkee);
       
   799     Q_ASSERT(parseInfo);
       
   800 
       
   801     const Expression::ID id = checkee->id();
       
   802 
       
   803     if(id == Expression::IDExpressionVariableReference)
       
   804     {
       
   805         const ExpressionVariableReference *const ref =
       
   806                     static_cast<const ExpressionVariableReference *>(checkee.data());
       
   807 
       
   808         if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
       
   809         {
       
   810             parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
       
   811                                                               "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
       
   812                                             parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
       
   813             return;
       
   814         }
       
   815         else
       
   816         {
       
   817             /* If the variable we're checking is below another variable, it can be a recursive
       
   818              * dependency through functions, so we need to check variable references too. */
       
   819             checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
       
   820             return;
       
   821         }
       
   822     }
       
   823     else if(id == Expression::IDUserFunctionCallsite)
       
   824     {
       
   825         const UserFunctionCallsite::Ptr callsite(checkee);
       
   826         const FunctionSignature::Ptr sign(callsite->callTargetDescription());
       
   827         const FunctionSignature::List::const_iterator end(signList.constEnd());
       
   828         FunctionSignature::List::const_iterator it(signList.constBegin());
       
   829         bool noMatch = true;
       
   830 
       
   831         for(; it != end; ++it)
       
   832         {
       
   833             if(*it == sign)
       
   834             {
       
   835                 /* The variable we're checking is depending on a function that's recursive. The
       
   836                  * user has written a weird query, in other words. Since it's the second time
       
   837                  * we've encountered a callsite, we now skip it. */
       
   838                 noMatch = false;
       
   839                 break;
       
   840             }
       
   841         }
       
   842 
       
   843         if(noMatch)
       
   844         {
       
   845             signList.append(sign);
       
   846             /* Check the body of the function being called. */
       
   847             checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
       
   848         }
       
   849         /* Continue with the operands, such that we also check the arguments of the callsite. */
       
   850     }
       
   851     else if(id == Expression::IDUnresolvedVariableReference)
       
   852     {
       
   853         /* We're called before it has rewritten itself. */
       
   854         checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
       
   855     }
       
   856 
       
   857     /* Check the operands. */
       
   858     const Expression::List ops(checkee->operands());
       
   859     if(ops.isEmpty())
       
   860         return;
       
   861 
       
   862     const Expression::List::const_iterator end(ops.constEnd());
       
   863     Expression::List::const_iterator it(ops.constBegin());
       
   864 
       
   865     for(; it != end; ++it)
       
   866         checkVariableCircularity(var, *it, type, signList, parseInfo);
       
   867 }
       
   868 
       
   869 static void variableUnavailable(const QXmlName &variableName,
       
   870                                 const ParserContext *const parseInfo,
       
   871                                 const YYLTYPE &location)
       
   872 {
       
   873     parseInfo->staticContext->error(QtXmlPatterns::tr("No variable by name %1 exists")
       
   874                                        .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
       
   875                                     ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
       
   876 }
       
   877 
       
   878 /**
       
   879  * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
       
   880  * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
       
   881  *
       
   882  * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
       
   883  * Cardinality + on range variables</a>
       
   884  * @see ParserContext::finalizePushedVariable()
       
   885  */
       
   886 static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
       
   887 {
       
   888     Q_ASSERT(type);
       
   889     return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
       
   890 }
       
   891 
       
   892 /**
       
   893  * @p seqType and @p expr may be @c null.
       
   894  */
       
   895 static Expression::Ptr pushVariable(const QXmlName name,
       
   896                                     const SequenceType::Ptr &seqType,
       
   897                                     const Expression::Ptr &expr,
       
   898                                     const VariableDeclaration::Type type,
       
   899                                     const YYLTYPE &sourceLocator,
       
   900                                     ParserContext *const parseInfo,
       
   901                                     const bool checkSource = true)
       
   902 {
       
   903     Q_ASSERT(!name.isNull());
       
   904     Q_ASSERT(parseInfo);
       
   905 
       
   906     /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
       
   907     VariableSlotID slot = -2;
       
   908 
       
   909     switch(type)
       
   910     {
       
   911         case VariableDeclaration::FunctionArgument:
       
   912         /* Fallthrough. */
       
   913         case VariableDeclaration::ExpressionVariable:
       
   914         {
       
   915             slot = parseInfo->allocateExpressionSlot();
       
   916             break;
       
   917         }
       
   918         case VariableDeclaration::GlobalVariable:
       
   919         {
       
   920             slot = parseInfo->allocateGlobalVariableSlot();
       
   921             break;
       
   922         }
       
   923         case VariableDeclaration::RangeVariable:
       
   924         {
       
   925             slot = parseInfo->staticContext->allocateRangeSlot();
       
   926             break;
       
   927         }
       
   928         case VariableDeclaration::PositionalVariable:
       
   929         {
       
   930             slot = parseInfo->allocatePositionalSlot();
       
   931             break;
       
   932         }
       
   933         case VariableDeclaration::TemplateParameter:
       
   934             /* Fallthrough. We do nothing, template parameters
       
   935              * doesn't use context slots at all, they're hashed
       
   936              * on the name. */
       
   937         case VariableDeclaration::ExternalVariable:
       
   938             /* We do nothing, external variables doesn't use
       
   939              *context slots/stack frames at all. */
       
   940             ;
       
   941     }
       
   942 
       
   943     const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
       
   944 
       
   945     Expression::Ptr checked;
       
   946 
       
   947     if(checkSource && seqType)
       
   948     {
       
   949         if(expr)
       
   950         {
       
   951             /* We only want to add conversion for function arguments, and variables
       
   952              * if we're XSL-T.
       
   953              *
       
   954              * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
       
   955              * pass hasn't set up the focus yet, since that's the parent's responsibility. */
       
   956             const TypeChecker::Options options((   type == VariableDeclaration::FunctionArgument
       
   957                                                 || type == VariableDeclaration::TemplateParameter
       
   958                                                 || parseInfo->isXSLT())
       
   959                                                ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());
       
   960 
       
   961             checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
       
   962                                                            parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
       
   963                                                            options);
       
   964         }
       
   965     }
       
   966     else
       
   967         checked = expr;
       
   968 
       
   969     /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
       
   970      * positional variables because in the end they are calls to Iterator::position(). Similarly,
       
   971      * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
       
   972      *
       
   973      * We don't do it for function arguments because the Expression being cached depends -- it depends
       
   974      * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
       
   975      *
       
   976      * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
       
   977      * optimizes itself away. */
       
   978     if(type == VariableDeclaration::ExpressionVariable)
       
   979         checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
       
   980     else if(type == VariableDeclaration::GlobalVariable)
       
   981         checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
       
   982 
       
   983     var->setExpression(checked);
       
   984 
       
   985     parseInfo->variables.push(var);
       
   986     return checked;
       
   987 }
       
   988 
       
   989 static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
       
   990                                                       const ParserContext *const parseInfo)
       
   991 {
       
   992     Q_ASSERT(!name.isNull());
       
   993     Q_ASSERT(parseInfo);
       
   994 
       
   995     /* We walk the list backwards. */
       
   996     const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
       
   997     VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());
       
   998 
       
   999     while(it != start)
       
  1000     {
       
  1001         --it;
       
  1002         Q_ASSERT(*it);
       
  1003         if((*it)->name == name)
       
  1004             return *it;
       
  1005     }
       
  1006 
       
  1007     return VariableDeclaration::Ptr();
       
  1008 }
       
  1009 
       
  1010 static Expression::Ptr resolveVariable(const QXmlName &name,
       
  1011                                        const YYLTYPE &sourceLocator,
       
  1012                                        ParserContext *const parseInfo,
       
  1013                                        const bool raiseErrorOnUnavailability)
       
  1014 {
       
  1015     const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
       
  1016     Expression::Ptr retval;
       
  1017 
       
  1018     if(var && var->type != VariableDeclaration::ExternalVariable)
       
  1019     {
       
  1020         switch(var->type)
       
  1021         {
       
  1022             case VariableDeclaration::RangeVariable:
       
  1023             {
       
  1024                 retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
       
  1025                 break;
       
  1026             }
       
  1027             case VariableDeclaration::GlobalVariable:
       
  1028             /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
       
  1029              * a difference between a global and a local expression variable. However, the cache
       
  1030              * mechanism must. */
       
  1031             case VariableDeclaration::ExpressionVariable:
       
  1032             {
       
  1033                 retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
       
  1034                 break;
       
  1035             }
       
  1036             case VariableDeclaration::FunctionArgument:
       
  1037             {
       
  1038                 retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
       
  1039                 break;
       
  1040             }
       
  1041             case VariableDeclaration::PositionalVariable:
       
  1042             {
       
  1043                 retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
       
  1044                 break;
       
  1045             }
       
  1046             case VariableDeclaration::TemplateParameter:
       
  1047             {
       
  1048                 retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
       
  1049                 break;
       
  1050             }
       
  1051             case VariableDeclaration::ExternalVariable:
       
  1052                 /* This code path will never be hit, but the case
       
  1053                  * label silences a warning. See above. */
       
  1054                 ;
       
  1055         }
       
  1056         Q_ASSERT(retval);
       
  1057         var->references.append(retval);
       
  1058     }
       
  1059     else
       
  1060     {
       
  1061         /* Let's see if your external variable loader can provide us with one. */
       
  1062         const SequenceType::Ptr varType(parseInfo->staticContext->
       
  1063                                         externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));
       
  1064 
       
  1065         if(varType)
       
  1066         {
       
  1067             const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
       
  1068             const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
       
  1069             retval = checked;
       
  1070         }
       
  1071         else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
       
  1072         {
       
  1073             /* In XSL-T, global variables are in scope for the whole
       
  1074              * stylesheet, so we must resolve this first at the end. */
       
  1075             retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
       
  1076             parseInfo->unresolvedVariableReferences.insert(name, retval);
       
  1077         }
       
  1078         else
       
  1079             variableUnavailable(name, parseInfo, sourceLocator);
       
  1080     }
       
  1081 
       
  1082     return retval;
       
  1083 }
       
  1084 
       
  1085 static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
       
  1086                                            const Expression::Ptr &returnExpr,
       
  1087                                            const OrderBy::Stability stability,
       
  1088                                            const YYLTYPE &sourceLocator,
       
  1089                                            const ParserContext *const parseInfo)
       
  1090 {
       
  1091     // TODO do resize(orderSpec.size() + 1)
       
  1092     Expression::List exprs;
       
  1093     OrderBy::OrderSpec::Vector orderSpecs;
       
  1094 
       
  1095     exprs.append(returnExpr);
       
  1096 
       
  1097     const int len = orderSpecTransfer.size();
       
  1098 
       
  1099     for(int i = 0; i < len; ++i)
       
  1100     {
       
  1101         exprs.append(orderSpecTransfer.at(i).expression);
       
  1102         orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
       
  1103     }
       
  1104 
       
  1105     return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
       
  1106 }
       
  1107 
       
  1108 %}
       
  1109 
       
  1110 /* This grammar shouldn't be compiled with anything older than the Bison version
       
  1111  * specified below. This '%require' directive was introduced in Bison 2.2. */
       
  1112 %require "2.3a"
       
  1113 
       
  1114 %name-prefix="XPath"
       
  1115 
       
  1116 /* Specifies the name of the generated parser. */
       
  1117 %output="qquerytransformparser.cpp"
       
  1118 
       
  1119 /* Output the .output file. */
       
  1120 %verbose
       
  1121 
       
  1122 /* Yes, we want descriptive error messages. */
       
  1123 %error-verbose
       
  1124 
       
  1125 /* We'd like to be reentrant/thread-safe */
       
  1126 %pure-parser
       
  1127 
       
  1128 /* We want code for line/columns to be generated. */
       
  1129 %locations
       
  1130 
       
  1131 /* Create a header file and put declarations there. */
       
  1132 %defines
       
  1133 
       
  1134 %parse-param    {ParserContext *const parseInfo}
       
  1135 %lex-param      {ParserContext *const parseInfo}
       
  1136 
       
  1137 %expect 4
       
  1138 /* Silences the following:
       
  1139 
       
  1140 state 327
       
  1141 
       
  1142   293 SequenceType: ItemType . OccurrenceIndicator
       
  1143 
       
  1144     "+"  shift, and go to state 379
       
  1145     "*"  shift, and go to state 380
       
  1146     "?"  shift, and go to state 381
       
  1147 
       
  1148     "+"       [reduce using rule 295 (OccurrenceIndicator)]
       
  1149     "*"       [reduce using rule 295 (OccurrenceIndicator)]
       
  1150     $default  reduce using rule 295 (OccurrenceIndicator)
       
  1151 
       
  1152     OccurrenceIndicator  go to state 382
       
  1153 
       
  1154 state 45
       
  1155 
       
  1156   200 PathExpr: "/" . RelativePathExpr
       
  1157   203         | "/" .
       
  1158 
       
  1159     [...]
       
  1160 
       
  1161     "<"       [reduce using rule 203 (PathExpr)]
       
  1162     "*"       [reduce using rule 203 (PathExpr)]
       
  1163     $default  reduce using rule 203 (PathExpr)
       
  1164 */
       
  1165 
       
  1166 %token <sval> STRING_LITERAL                "<string literal>"
       
  1167 
       
  1168 /**
       
  1169  * This token is only used in element content and signals content that
       
  1170  * is not Boundary whitespace. Nevertheless, the token value can be all whitespace,
       
  1171  * but it was specified using character references or CDATA sections by the user. */
       
  1172 %token <sval> NON_BOUNDARY_WS               "<non-boundary text node>"
       
  1173 
       
  1174 /* XPath 2.0 allows quotes and apostrophes to be escaped with "" and ''; this token is
       
  1175    is used for XPath 2.0 literals such that we can flag syntax errors if running in
       
  1176    1.0 mode. */
       
  1177 %token <sval> XPATH2_STRING_LITERAL         "<string literal(XPath 2.0)>"
       
  1178 %token <sval> QNAME                         "QName"
       
  1179 %token <sval> NCNAME                        "NCName"
       
  1180 
       
  1181 /* A QName as a clark name. See QXmlName::toClarkName(). */
       
  1182 %token <sval> CLARK_NAME                    "ClarkName"
       
  1183 
       
  1184 /**
       
  1185  * Is "ncname:*". The token value does not include the colon and the star.
       
  1186  */
       
  1187 %token <sval> ANY_LOCAL_NAME
       
  1188 
       
  1189 /**
       
  1190  * Is "*:ncname". The token value does not include the colon and the star.
       
  1191  */
       
  1192 %token <sval> ANY_PREFIX
       
  1193 
       
  1194 /**
       
  1195  * An XPath 1.0 number literal. It is a string value because
       
  1196  * Numeric::fromLexical() does the tokenization.
       
  1197  */
       
  1198 %token <sval> NUMBER                        "<number literal>"
       
  1199 
       
  1200 /**
       
  1201  * XPath 2.0 number literal. It includes the use of 'e'/'E'
       
  1202  */
       
  1203 %token <sval> XPATH2_NUMBER                 "<number literal(XPath 2.0)>"
       
  1204 
       
  1205 %token ANCESTOR                             "ancestor"
       
  1206 %token ANCESTOR_OR_SELF                     "ancestor-or-self"
       
  1207 %token AND                                  "and"
       
  1208 %token APOS                                 "'"
       
  1209 %token APPLY_TEMPLATE                       "apply-template"
       
  1210 %token AS                                   "as"
       
  1211 %token ASCENDING                            "ascending"
       
  1212 %token ASSIGN                               ":="
       
  1213 %token AT                                   "at"
       
  1214 %token AT_SIGN                              "@"
       
  1215 %token ATTRIBUTE                            "attribute"
       
  1216 %token AVT                                  /* Synthetic token. Signals an attribute value template. */
       
  1217 %token BAR                                  "|"
       
  1218 %token BASEURI                              "base-uri"
       
  1219 %token BEGIN_END_TAG                        "</"
       
  1220 %token BOUNDARY_SPACE                       "boundary-space"
       
  1221 %token BY                                   "by"
       
  1222 %token CALL_TEMPLATE                        "call-template"
       
  1223 %token CASE                                 "case"
       
  1224 %token CASTABLE                             "castable"
       
  1225 %token CAST                                 "cast"
       
  1226 %token CHILD                                "child"
       
  1227 %token COLLATION                            "collation"
       
  1228 %token COLONCOLON                           "::"
       
  1229 %token COMMA                                ","
       
  1230 %token COMMENT                              "comment"
       
  1231 %token COMMENT_START                        "<!--"
       
  1232 %token CONSTRUCTION                         "construction"
       
  1233 %token COPY_NAMESPACES                      "copy-namespaces"
       
  1234 %token CURLY_LBRACE                         "{"
       
  1235 %token CURLY_RBRACE                         "}"
       
  1236 %token DECLARE                              "declare"
       
  1237 %token DEFAULT                              "default"
       
  1238 %token DESCENDANT                           "descendant"
       
  1239 %token DESCENDANT_OR_SELF                   "descendant-or-self"
       
  1240 %token DESCENDING                           "descending"
       
  1241 %token DIV                                  "div"
       
  1242 %token DOCUMENT                             "document"
       
  1243 %token DOCUMENT_NODE                        "document-node"
       
  1244 %token DOLLAR                               "$"
       
  1245 %token DOT                                  "."
       
  1246 %token DOTDOT                               ".."
       
  1247 %token ELEMENT                              "element"
       
  1248 %token ELSE                                 "else"
       
  1249 %token EMPTY                                "empty"
       
  1250 %token EMPTY_SEQUENCE                       "empty-sequence"
       
  1251 %token ENCODING                             "encoding"
       
  1252 %token END_OF_FILE 0                        "end of file"
       
  1253 %token END_SORT                             "end_sort"
       
  1254 %token EQ                                   "eq"
       
  1255 %token ERROR                                "unknown keyword" /* Used by the Tokenizer. We use the phrase "keyword" instead of "token" to be less pointy.  */
       
  1256 %token EVERY                                "every"
       
  1257 %token EXCEPT                               "except"
       
  1258 %token EXTERNAL                             "external"
       
  1259 %token FOLLOWING                            "following"
       
  1260 %token FOLLOWING_SIBLING                    "following-sibling"
       
  1261 %token FOLLOWS                              ">>"
       
  1262 %token FOR_APPLY_TEMPLATE                   "for-apply-template" /* Synthetic token, used in XSL-T. */
       
  1263 %token FOR                                  "for"
       
  1264 %token FUNCTION                             "function"
       
  1265 %token GE                                   "ge"
       
  1266 %token G_EQ                                 "="
       
  1267 %token G_GE                                 ">="
       
  1268 %token G_GT                                 ">"
       
  1269 %token G_LE                                 "<="
       
  1270 %token G_LT                                 "<"
       
  1271 %token G_NE                                 "!="
       
  1272 %token GREATEST                             "greatest"
       
  1273 %token GT                                   "gt"
       
  1274 %token IDIV                                 "idiv"
       
  1275 %token IF                                   "if"
       
  1276 %token IMPORT                               "import"
       
  1277 %token INHERIT                              "inherit"
       
  1278 %token IN                                   "in"
       
  1279 %token INSTANCE                             "instance"
       
  1280 %token INTERSECT                            "intersect"
       
  1281 %token IS                                   "is"
       
  1282 %token ITEM                                 "item"
       
  1283 %token LAX                                  "lax"
       
  1284 %token LBRACKET                             "["
       
  1285 %token LEAST                                "least"
       
  1286 %token LE                                   "le"
       
  1287 %token LET                                  "let"
       
  1288 %token LPAREN                               "("
       
  1289 %token LT                                   "lt"
       
  1290 %token MAP                                  "map" /* Synthetic token, used in XSL-T. */
       
  1291 %token MATCHES                              "matches"
       
  1292 %token MINUS                                "-"
       
  1293 %token MODE                                 "mode" /* Synthetic token, used in XSL-T. */
       
  1294 %token MOD                                  "mod"
       
  1295 %token MODULE                               "module"
       
  1296 %token NAME                                 "name"
       
  1297 %token NAMESPACE                            "namespace"
       
  1298 %token NE                                   "ne"
       
  1299 %token NODE                                 "node"
       
  1300 %token NO_INHERIT                           "no-inherit"
       
  1301 %token NO_PRESERVE                          "no-preserve"
       
  1302 %token OF                                   "of"
       
  1303 %token OPTION                               "option"
       
  1304 %token ORDERED                              "ordered"
       
  1305 %token ORDERING                             "ordering"
       
  1306 %token ORDER                                "order"
       
  1307 %token OR                                   "or"
       
  1308 %token PARENT                               "parent"
       
  1309 %token PI_START                             "<?"
       
  1310 %token PLUS                                 "+"
       
  1311 %token POSITION_SET                         /* Synthetic token. */
       
  1312 %token PRAGMA_END                           "#)"
       
  1313 %token PRAGMA_START                         "(#"
       
  1314 %token PRECEDES                             "<<"
       
  1315 %token PRECEDING                            "preceding"
       
  1316 %token PRECEDING_SIBLING                    "preceding-sibling"
       
  1317 %token PRESERVE                             "preserve"
       
  1318 %token PRIORITY                             "priority"
       
  1319 %token PROCESSING_INSTRUCTION               "processing-instruction"
       
  1320 %token QUESTION                             "?"
       
  1321 %token QUICK_TAG_END                        "/>"
       
  1322 %token QUOTE                                "\""
       
  1323 %token RBRACKET                             "]"
       
  1324 %token RETURN                               "return"
       
  1325 %token RPAREN                               ")"
       
  1326 %token SATISFIES                            "satisfies"
       
  1327 %token SCHEMA_ATTRIBUTE                     "schema-attribute"
       
  1328 %token SCHEMA_ELEMENT                       "schema-element"
       
  1329 %token SCHEMA                               "schema"
       
  1330 %token SELF                                 "self"
       
  1331 %token SEMI_COLON                           ";"
       
  1332 %token SLASH                                "/"
       
  1333 %token SLASHSLASH                           "//"
       
  1334 %token SOME                                 "some"
       
  1335 %token SORT                                 "sort" /* Synthetic token, used in XSL-T. */
       
  1336 %token STABLE                               "stable"
       
  1337 %token STAR                                 "*"
       
  1338 %token STRICT                               "strict"
       
  1339 %token STRIP                                "strip"
       
  1340 %token SUCCESS                              /* Synthetic token, used by the Tokenizer. */
       
  1341 %token <sval> COMMENT_CONTENT
       
  1342 %token <sval> PI_CONTENT
       
  1343 %token <sval> PI_TARGET
       
  1344 %token <sval> XSLT_VERSION                  /* Synthetic token, used in XSL-T. */
       
  1345 %token TEMPLATE                             "template"
       
  1346 %token TEXT                                 "text"
       
  1347 %token THEN                                 "then"
       
  1348 %token TO                                   "to"
       
  1349 %token TREAT                                "treat"
       
  1350 %token TUNNEL                               "tunnel" /* Synthetic token, used in XSL-T. */
       
  1351 %token TYPESWITCH                           "typeswitch"
       
  1352 %token UNION                                "union"
       
  1353 %token UNORDERED                            "unordered"
       
  1354 %token VALIDATE                             "validate"
       
  1355 %token VARIABLE                             "variable"
       
  1356 %token VERSION                              "version"
       
  1357 %token WHERE                                "where"
       
  1358 %token XQUERY                               "xquery"
       
  1359 %token INTERNAL                             "internal" /* Synthetic token, used in XSL-T. */
       
  1360 %token INTERNAL_NAME                        "internal-name" /* Synthetic token, used in XSL-T. */
       
  1361 %token CURRENT                              "current" /* Synthetic token, used in XSL-T. */
       
  1362 
       
  1363 /* Alphabetically. */
       
  1364 %type <attributeHolder>             Attribute
       
  1365 %type <attributeHolders>            DirAttributeList
       
  1366 %type <cardinality>                 OccurrenceIndicator
       
  1367 %type <enums.axis>                  Axis AxisToken
       
  1368 %type <enums.boundarySpacePolicy>   BoundarySpacePolicy
       
  1369 %type <enums.combinedNodeOp>        IntersectOperator
       
  1370 %type <enums.constructionMode>      ConstructionMode
       
  1371 %type <enums.mathOperator>          MultiplyOperator AdditiveOperator UnaryOperator
       
  1372 %type <enums.nodeOperator>          NodeOperator
       
  1373 %type <enums.orderingEmptySequence> OrderingEmptySequence EmptynessModifier
       
  1374 %type <enums.sortDirection>         DirectionModifier
       
  1375 
       
  1376 %type <enums.orderingMode>          OrderingMode
       
  1377 %type <enums.slot>                  PositionalVar
       
  1378 %type <enums.validationMode>        ValidationMode
       
  1379 %type <enums.valueOperator>         ValueComparisonOperator GeneralComparisonOperator
       
  1380 %type <expr>                        OrExpr AndExpr ComparisonExpr UnionExpr Literal
       
  1381                                     AdditiveExpr MultiplicativeExpr PrimaryExpr FilterExpr
       
  1382                                     StepExpr PathExpr RelativePathExpr Expr ExprSingle
       
  1383                                     VarRef ContextItemExpr IfExpr CastExpr CastableExpr
       
  1384                                     TreatExpr InstanceOfExpr ValueExpr UnaryExpr NodeComp
       
  1385                                     IntersectExceptExpr RangeExpr ParenthesizedExpr
       
  1386                                     ValueComp FunctionCallExpr GeneralComp ForClause
       
  1387                                     WhereClause FLWORExpr ForTail QuantifiedExpr QueryBody
       
  1388                                     SomeQuantificationExpr SomeQuantificationTail
       
  1389                                     EveryQuantificationExpr EveryQuantificationTail
       
  1390                                     ExtensionExpr EnclosedOptionalExpr VariableValue
       
  1391                                     EnclosedExpr FunctionBody ValidateExpr NumericLiteral
       
  1392                                     OrderingExpr TypeswitchExpr LetClause LetTail
       
  1393                                     Constructor DirectConstructor DirElemConstructor
       
  1394                                     ComputedConstructor CompDocConstructor CompElemConstructor
       
  1395                                     CompTextConstructor CompCommentConstructor CompPIConstructor
       
  1396                                     DirPIConstructor CompAttrConstructor DirElemConstructorTail
       
  1397                                     AxisStep ForwardStep ReverseStep AbbrevForwardStep
       
  1398                                     CaseDefault CaseClause CaseTail CompAttributeName
       
  1399                                     FilteredAxisStep DirCommentConstructor CompPIName
       
  1400                                     DirAttributeValue AbbrevReverseStep CompNamespaceConstructor
       
  1401                                     CompElementName CompNameExpr SatisfiesClause Pattern PathPattern
       
  1402                                     PatternStep RelativePathPattern IdKeyPattern OptionalAssign
       
  1403                                     OptionalDefaultValue
       
  1404 
       
  1405 %type <orderSpec>                   OrderSpec
       
  1406 %type <expressionList>              ExpressionSequence FunctionArguments
       
  1407                                     DirElemContent AttrValueContent
       
  1408 %type <orderSpecs>                  OrderSpecList OrderByClause MandatoryOrderByClause
       
  1409 %type <functionArgument>            Param
       
  1410 %type <functionArguments>           ParamList
       
  1411 %type <itemType>                    KindTest ItemType AtomicType NodeTest NameTest WildCard NodeTestInAxisStep
       
  1412                                     ElementTest AttributeTest SchemaElementTest SchemaAttributeTest
       
  1413                                     TextTest CommentTest PITest DocumentTest AnyKindTest AnyAttributeTest
       
  1414 %type <qName>                       ElementName QName VarName FunctionName PragmaName TypeName NCName
       
  1415                                     CaseVariable AttributeName OptionalTemplateName
       
  1416                                     TemplateName Mode OptionalMode
       
  1417 %type <qNameVector>                 Modes OptionalModes
       
  1418 %type <sequenceType>                SequenceType SingleType TypeDeclaration
       
  1419 %type <sval>                        URILiteral StringLiteral LexicalName
       
  1420 %type <enums.Bool>                  IsInternal IsTunnel
       
  1421 %type <enums.Double>                OptionalPriority
       
  1422 %type <enums.pathKind>              MapOrSlash
       
  1423 
       
  1424 /* Operator Precendence
       
  1425  * See: http://www.w3.org/TR/xpath20/#parse-note-occurrence-indicators */
       
  1426 %left STAR DIV
       
  1427 %left PLUS MINUS
       
  1428 
       
  1429 %%
       
  1430 
       
  1431 /* Here, the grammar starts. In the brackets on the right you
       
  1432  * find the number of corresponding EBNF rule in the XQuery 1.0 specification. If it
       
  1433  * contains an X, it means the non-terminal has no counter part in the grammar, but
       
  1434  * exists for implementation purposes. */
       
  1435 Module: VersionDecl LibraryModule                                                   /* [1] */
       
  1436 | VersionDecl MainModule
       
  1437 
       
  1438 VersionDecl: /* empty */                                                            /* [2] */
       
  1439 | XQUERY VERSION StringLiteral Encoding Separator
       
  1440     {
       
  1441 
       
  1442 /* Suppress more compiler warnings about unused defines. */
       
  1443 #if    defined(YYNNTS)              \
       
  1444     || defined(yyerrok)             \
       
  1445     || defined(YYNSTATES)           \
       
  1446     || defined(YYRHSLOC)            \
       
  1447     || defined(YYRECOVERING)        \
       
  1448     || defined(YYFAIL)              \
       
  1449     || defined(YYERROR)             \
       
  1450     || defined(YYNRULES)            \
       
  1451     || defined(YYBACKUP)            \
       
  1452     || defined(YYMAXDEPTH)          \
       
  1453     || defined(yyclearin)           \
       
  1454     || defined(YYERRCODE)           \
       
  1455     || defined(YY_LOCATION_PRINT)   \
       
  1456     || defined(YYLLOC_DEFAULT)
       
  1457 #endif
       
  1458 
       
  1459         if($3 != QLatin1String("1.0"))
       
  1460         {
       
  1461             const ReflectYYLTYPE ryy(@$, parseInfo);
       
  1462 
       
  1463             parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
       
  1464                                                "XQuery version is 1.0.")
       
  1465                                                .arg(formatData($3)),
       
  1466                                             ReportContext::XQST0031, &ryy);
       
  1467         }
       
  1468     }
       
  1469 
       
  1470 Encoding: /* empty */                                                               /* [X] */
       
  1471 | ENCODING StringLiteral
       
  1472     {
       
  1473         const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
       
  1474 
       
  1475         if(!encNameRegExp.exactMatch($2))
       
  1476         {
       
  1477             parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
       
  1478                                                "It must contain Latin characters only, "
       
  1479                                                "must not contain whitespace, and must match "
       
  1480                                                "the regular expression %2.")
       
  1481                                             .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
       
  1482                                                  formatExpression(encNameRegExp.pattern())),
       
  1483                                             ReportContext::XQST0087, fromYYLTYPE(@$, parseInfo));
       
  1484         }
       
  1485     }
       
  1486 
       
  1487 MainModule: Prolog QueryBody                                                        /* [3] */
       
  1488     {
       
  1489         /* In XSL-T, we can have dangling variable references, so resolve them
       
  1490          * before we proceed with other steps, such as checking circularity. */
       
  1491         if(parseInfo->isXSLT())
       
  1492         {
       
  1493             typedef QHash<QXmlName, Expression::Ptr> Hash;
       
  1494             const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
       
  1495 
       
  1496             for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
       
  1497             {
       
  1498                 const Expression::Ptr body(resolveVariable(it.key(), @$, parseInfo, true)); // TODO source locations vaise
       
  1499                 Q_ASSERT(body);
       
  1500                 it.value()->as<UnresolvedVariableReference>()->bindTo(body);
       
  1501             }
       
  1502         }
       
  1503 
       
  1504         /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
       
  1505         {
       
  1506             const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
       
  1507             UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
       
  1508             for(; cit != cend; ++cit) /* For each callsite. */
       
  1509             {
       
  1510                 const UserFunctionCallsite::Ptr callsite(*cit);
       
  1511                 Q_ASSERT(callsite);
       
  1512                 const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
       
  1513                 UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
       
  1514 
       
  1515                 for(; it != end; ++it) /* For each UserFunction. */
       
  1516                 {
       
  1517                     const FunctionSignature::Ptr sign((*it)->signature());
       
  1518                     Q_ASSERT(sign);
       
  1519 
       
  1520                     if(callsite->isSignatureValid(sign))
       
  1521                     {
       
  1522                         callsite->setSource((*it),
       
  1523                                             parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
       
  1524                         break;
       
  1525                     }
       
  1526                 }
       
  1527                 if(it == end)
       
  1528                 {
       
  1529                     parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
       
  1530                                                        .arg(formatFunction(callsite)),
       
  1531                                                     ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
       
  1532                 }
       
  1533             }
       
  1534         }
       
  1535 
       
  1536         /* Mark callsites in UserFunction bodies as recursive, if they are. */
       
  1537         {
       
  1538             const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
       
  1539             UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
       
  1540             for(; fit != fend; ++fit)
       
  1541             {
       
  1542                 CallTargetDescription::List signList;
       
  1543                 signList.append((*fit)->signature());
       
  1544                 CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
       
  1545             }
       
  1546         }
       
  1547 
       
  1548         /* Now, check all global variables for circularity.  This is done
       
  1549          * backwards because global variables are only in scope below them,
       
  1550          * in XQuery. */
       
  1551         {
       
  1552             const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
       
  1553             VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
       
  1554 
       
  1555             while(it != start)
       
  1556             {
       
  1557                 --it;
       
  1558                 if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
       
  1559                     continue; /* We want to ignore 'external' variables. */
       
  1560 
       
  1561                 FunctionSignature::List signList;
       
  1562                 checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
       
  1563                 ExpressionFactory::registerLastPath((*it)->expression());
       
  1564                 parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
       
  1565             }
       
  1566         }
       
  1567 
       
  1568         /* Generate code for doing initial template name calling. One problem
       
  1569          * is that we compilation in the initial template name, since we throw away the
       
  1570          * code if we don't have the requested template. */
       
  1571         if(parseInfo->languageAccent == QXmlQuery::XSLT20
       
  1572            && !parseInfo->initialTemplateName.isNull()
       
  1573            && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
       
  1574         {
       
  1575             parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
       
  1576                                                            WithParam::Hash()),
       
  1577                                           @$, parseInfo);
       
  1578             parseInfo->templateCalls.append(parseInfo->queryBody);
       
  1579             /* We just discard the template body that XSLTTokenizer generated. */
       
  1580         }
       
  1581         else
       
  1582             parseInfo->queryBody = $2;
       
  1583     }
       
  1584 
       
  1585 LibraryModule: ModuleDecl Prolog                                                    /* [4] */
       
  1586 
       
  1587 ModuleDecl: MODULE NAMESPACE NCNAME G_EQ URILiteral Separator                       /* [5] */
       
  1588     {
       
  1589         // TODO add to namespace context
       
  1590         parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace($3);
       
  1591     }
       
  1592 
       
  1593 Prolog: /* Empty. */                                                                /* [6] */
       
  1594 /* First part. */
       
  1595 | Prolog DefaultNamespaceDecl
       
  1596     {
       
  1597         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1598         if(parseInfo->hasSecondPrologPart)
       
  1599             parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
       
  1600                                                "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  1601     }
       
  1602 | Prolog Setter
       
  1603     {
       
  1604         if(parseInfo->hasSecondPrologPart)
       
  1605             parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
       
  1606                                                "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  1607     }
       
  1608 | Prolog NamespaceDecl
       
  1609     {
       
  1610         if(parseInfo->hasSecondPrologPart)
       
  1611             parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
       
  1612                                                "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  1613     }
       
  1614 | Prolog Import
       
  1615     {
       
  1616         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1617         if(parseInfo->hasSecondPrologPart)
       
  1618             parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
       
  1619                                                "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  1620     }
       
  1621 | Prolog TemplateDecl
       
  1622 
       
  1623 /* Second part. */
       
  1624 | Prolog VarDecl
       
  1625     {
       
  1626         parseInfo->hasSecondPrologPart = true;
       
  1627     }
       
  1628 | Prolog FunctionDecl
       
  1629     {
       
  1630         parseInfo->hasSecondPrologPart = true;
       
  1631     }
       
  1632 | Prolog OptionDecl
       
  1633     {
       
  1634         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1635         parseInfo->hasSecondPrologPart = true;
       
  1636     }
       
  1637 
       
  1638 /*
       
  1639  * declare template name theName
       
  1640  * {
       
  1641  *     "expression"
       
  1642  * };
       
  1643  *
       
  1644  * or
       
  1645  *
       
  1646  * declare template name theName matches (pattern) mode modeName priority 123
       
  1647  * {
       
  1648  *     "expression"
       
  1649  * };
       
  1650  *
       
  1651  */
       
  1652 TemplateDecl: DECLARE TEMPLATE TemplateName
       
  1653               OptionalTemplateParameters
       
  1654               TypeDeclaration
       
  1655               EnclosedOptionalExpr Separator                                        /* [X] */
       
  1656     {
       
  1657         Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, $5), @$, parseInfo));
       
  1658 
       
  1659         registerNamedTemplate($3, typeCheckTemplateBody($6, $5, parseInfo),
       
  1660                               parseInfo, @1, temp);
       
  1661         temp->templateParameters = parseInfo->templateParameters;
       
  1662         parseInfo->templateParametersHandled();
       
  1663     }
       
  1664 | DECLARE TEMPLATE OptionalTemplateName
       
  1665   MATCHES LPAREN
       
  1666   {
       
  1667     parseInfo->isParsingPattern = true;
       
  1668   }
       
  1669   Pattern
       
  1670   {
       
  1671     parseInfo->isParsingPattern = false;
       
  1672   }
       
  1673   RPAREN
       
  1674   OptionalModes
       
  1675   OptionalPriority
       
  1676   OptionalTemplateParameters
       
  1677   TypeDeclaration
       
  1678   EnclosedOptionalExpr Separator                                                    /* [X] */
       
  1679     {
       
  1680         /* In this grammar branch, we're guaranteed to be a template rule, but
       
  1681          * may also be a named template. */
       
  1682 
       
  1683         const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
       
  1684         Expression::Ptr pattern($7);
       
  1685         const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
       
  1686 
       
  1687         Template::Ptr templ(create(new Template(ip, $13), @$, parseInfo));
       
  1688         templ->body = typeCheckTemplateBody($14, $13, parseInfo);
       
  1689         templ->templateParameters = parseInfo->templateParameters;
       
  1690         parseInfo->templateParametersHandled();
       
  1691 
       
  1692         TemplatePattern::Vector ourPatterns;
       
  1693         /* We do it as per 6.4 Conflict Resolution for Template Rules:
       
  1694          *
       
  1695          * "If the pattern contains multiple alternatives separated by |, then
       
  1696          * the template rule is treated equivalently to a set of template
       
  1697          * rules, one for each alternative. However, it is not an error if a
       
  1698          * node matches more than one of the alternatives." */
       
  1699         while(pattern->is(Expression::IDCombineNodes))
       
  1700         {
       
  1701             const Expression::List operands(pattern->operands());
       
  1702             pattern = operands.first();
       
  1703 
       
  1704             loadPattern(operands.at(1), ourPatterns, templateID, $11, templ);
       
  1705         }
       
  1706 
       
  1707         loadPattern(pattern, ourPatterns, templateID, $11, templ);
       
  1708 
       
  1709         if(!$3.isNull())
       
  1710             registerNamedTemplate($3, $14, parseInfo, @1, templ);
       
  1711 
       
  1712         /* Now, let's add it to all the relevant templates. */
       
  1713         for(int i = 0; i < $10.count(); ++i) /* For each mode. */
       
  1714         {
       
  1715             const QXmlName &modeName = $10.at(i);
       
  1716 
       
  1717             if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && $10.count() > 1)
       
  1718             {
       
  1719                 parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
       
  1720                                                                  .arg(formatKeyword(QLatin1String("#all"))),
       
  1721                                                 ReportContext::XTSE0530,
       
  1722                                                 fromYYLTYPE(@$, parseInfo));
       
  1723             }
       
  1724 
       
  1725             /* For each pattern the template use. */
       
  1726             const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
       
  1727             for(int t = 0; t < ourPatterns.count(); ++t)
       
  1728                 mode->templatePatterns.append(ourPatterns.at(t));
       
  1729         }
       
  1730     }
       
  1731 
       
  1732 OptionalPriority: /* Empty. */                                                      /* [X] */
       
  1733     {
       
  1734         $$ = std::numeric_limits<xsDouble>::quiet_NaN();
       
  1735     }
       
  1736 
       
  1737 | PRIORITY StringLiteral
       
  1738     {
       
  1739         const AtomicValue::Ptr val(Decimal::fromLexical($2));
       
  1740         if(val->hasError())
       
  1741         {
       
  1742             parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
       
  1743                                                              .arg(formatKeyword(QLatin1String("priority")),
       
  1744                                                                   formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
       
  1745                                                                   formatData($2)),
       
  1746                                             ReportContext::XTSE0530,
       
  1747                                             fromYYLTYPE(@$, parseInfo));
       
  1748         }
       
  1749         else
       
  1750             $$ = val->as<Numeric>()->toDouble();
       
  1751     }
       
  1752 
       
  1753 OptionalTemplateName: /* Empty. */                                                  /* [X] */
       
  1754     {
       
  1755         $$ = QXmlName();
       
  1756     }
       
  1757 | TemplateName
       
  1758 
       
  1759 TemplateName: NAME ElementName
       
  1760     {
       
  1761         $$ = $2;
       
  1762     }
       
  1763 
       
  1764 Setter: BoundarySpaceDecl                                                           /* [7] */
       
  1765 | DefaultCollationDecl
       
  1766     {
       
  1767         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1768     }
       
  1769 | BaseURIDecl
       
  1770 | ConstructionDecl
       
  1771     {
       
  1772         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1773     }
       
  1774 | OrderingModeDecl
       
  1775     {
       
  1776         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1777     }
       
  1778 | EmptyOrderDecl
       
  1779     {
       
  1780         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1781     }
       
  1782 | CopyNamespacesDecl
       
  1783 
       
  1784 Import: SchemaImport                                                                /* [8] */
       
  1785 | ModuleImport
       
  1786 
       
  1787 Separator: SEMI_COLON                                                               /* [9] */
       
  1788 
       
  1789 NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator        /* [10] */
       
  1790     {
       
  1791         if(!$6)
       
  1792             allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1793 
       
  1794         if($3 == QLatin1String("xmlns"))
       
  1795         {
       
  1796             parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
       
  1797                                                .arg(formatKeyword(QLatin1String("xmlns"))),
       
  1798                                             ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
       
  1799         }
       
  1800         else if ($5 == CommonNamespaces::XML || $3 == QLatin1String("xml"))
       
  1801         {
       
  1802              parseInfo->staticContext->error(QtXmlPatterns::tr(
       
  1803                                             "The prefix %1 can not be bound. By default, it is already bound "
       
  1804                                             "to the namespace %2.")
       
  1805                                              .arg(formatKeyword("xml"))
       
  1806                                              .arg(formatURI(CommonNamespaces::XML)),
       
  1807                                              ReportContext::XQST0070,
       
  1808                                              fromYYLTYPE(@$, parseInfo));
       
  1809         }
       
  1810         else if(parseInfo->declaredPrefixes.contains($3))
       
  1811         {
       
  1812             /* This includes the case where the user has bound a default prefix(such
       
  1813              * as 'local') and now tries to do it again. */
       
  1814             parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
       
  1815                                                .arg(formatKeyword($3)),
       
  1816                                             ReportContext::XQST0033, fromYYLTYPE(@$, parseInfo));
       
  1817         }
       
  1818         else
       
  1819         {
       
  1820             parseInfo->declaredPrefixes.append($3);
       
  1821 
       
  1822             if($5.isEmpty())
       
  1823             {
       
  1824                 parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
       
  1825                                                                                    StandardLocalNames::empty,
       
  1826                                                                                    parseInfo->staticContext->namePool()->allocatePrefix($3)));
       
  1827             }
       
  1828             else
       
  1829             {
       
  1830                 parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding($3, $5));
       
  1831             }
       
  1832         }
       
  1833     }
       
  1834 
       
  1835 BoundarySpaceDecl: DECLARE BOUNDARY_SPACE BoundarySpacePolicy Separator             /* [11] */
       
  1836     {
       
  1837         if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
       
  1838         {
       
  1839             parseInfo->staticContext->error(prologMessage("declare boundary-space"),
       
  1840                                             ReportContext::XQST0068, fromYYLTYPE(@$, parseInfo));
       
  1841         }
       
  1842         else
       
  1843         {
       
  1844             parseInfo->staticContext->setBoundarySpacePolicy($3);
       
  1845             parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
       
  1846         }
       
  1847     }
       
  1848 
       
  1849 BoundarySpacePolicy: STRIP                                                          /* [X] */
       
  1850     {
       
  1851         $$ = StaticContext::BSPStrip;
       
  1852     }
       
  1853 
       
  1854 | PRESERVE
       
  1855     {
       
  1856         $$ = StaticContext::BSPPreserve;
       
  1857     }
       
  1858 
       
  1859 DefaultNamespaceDecl: DeclareDefaultElementNamespace                                /* [12] */
       
  1860 | DeclareDefaultFunctionNamespace
       
  1861 
       
  1862 DeclareDefaultElementNamespace: DECLARE DEFAULT ELEMENT NAMESPACE
       
  1863                                 URILiteral Separator                                /* [X] */
       
  1864     {
       
  1865         if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
       
  1866         {
       
  1867             parseInfo->staticContext->error(prologMessage("declare default element namespace"),
       
  1868                                             ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
       
  1869         }
       
  1870         else
       
  1871         {
       
  1872             parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), StandardLocalNames::empty));
       
  1873             parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
       
  1874         }
       
  1875     }
       
  1876 
       
  1877 DeclareDefaultFunctionNamespace: DECLARE DEFAULT FUNCTION NAMESPACE
       
  1878                                  URILiteral Separator                               /* [X] */
       
  1879     {
       
  1880         if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
       
  1881         {
       
  1882             parseInfo->staticContext->error(prologMessage("declare default function namespace"),
       
  1883                                             ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
       
  1884         }
       
  1885         else
       
  1886         {
       
  1887             parseInfo->staticContext->setDefaultFunctionNamespace($5);
       
  1888             parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
       
  1889         }
       
  1890     }
       
  1891 
       
  1892 OptionDecl: DECLARE OPTION ElementName StringLiteral Separator                     /* [13] */
       
  1893     {
       
  1894         if($3.prefix() == StandardPrefixes::empty)
       
  1895         {
       
  1896             parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
       
  1897                                                "There is no default namespace for options."),
       
  1898                                             ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
       
  1899         }
       
  1900     }
       
  1901 
       
  1902 OrderingModeDecl: DECLARE ORDERING OrderingMode Separator                           /* [14] */
       
  1903     {
       
  1904         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  1905         if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
       
  1906         {
       
  1907             parseInfo->staticContext->error(prologMessage("declare ordering"),
       
  1908                                             ReportContext::XQST0065, fromYYLTYPE(@$, parseInfo));
       
  1909         }
       
  1910         else
       
  1911         {
       
  1912             parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
       
  1913             parseInfo->staticContext->setOrderingMode($3);
       
  1914         }
       
  1915     }
       
  1916 
       
  1917 OrderingMode: ORDERED
       
  1918     {
       
  1919         $$ = StaticContext::Ordered;
       
  1920     }
       
  1921 | UNORDERED
       
  1922     {
       
  1923         $$ = StaticContext::Unordered;
       
  1924     }
       
  1925 
       
  1926 EmptyOrderDecl: DECLARE DEFAULT ORDER OrderingEmptySequence Separator               /* [15] */
       
  1927     {
       
  1928         if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
       
  1929         {
       
  1930             parseInfo->staticContext->error(prologMessage("declare default order"),
       
  1931                                             ReportContext::XQST0069, fromYYLTYPE(@$, parseInfo));
       
  1932         }
       
  1933         else
       
  1934         {
       
  1935             parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
       
  1936             parseInfo->staticContext->setOrderingEmptySequence($4);
       
  1937         }
       
  1938     }
       
  1939 
       
  1940 OrderingEmptySequence: EMPTY LEAST                                                  /* [X] */
       
  1941     {
       
  1942         $$ = StaticContext::Least;
       
  1943     }
       
  1944 | EMPTY GREATEST
       
  1945     {
       
  1946         $$ = StaticContext::Greatest;
       
  1947     }
       
  1948 
       
  1949 CopyNamespacesDecl: DECLARE COPY_NAMESPACES PreserveMode COMMA
       
  1950                     InheritMode Separator                                           /* [16] */
       
  1951     {
       
  1952         if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
       
  1953         {
       
  1954             parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
       
  1955                                             ReportContext::XQST0055, fromYYLTYPE(@$, parseInfo));
       
  1956         }
       
  1957         else
       
  1958         {
       
  1959             parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
       
  1960         }
       
  1961     }
       
  1962 
       
  1963 PreserveMode: PRESERVE                                                              /* [17] */
       
  1964     {
       
  1965         parseInfo->preserveNamespacesMode = true;
       
  1966     }
       
  1967 
       
  1968 | NO_PRESERVE
       
  1969     {
       
  1970         parseInfo->preserveNamespacesMode = false;
       
  1971     }
       
  1972 
       
  1973 InheritMode: INHERIT                                                                /* [18] */
       
  1974     {
       
  1975         parseInfo->inheritNamespacesMode = true;
       
  1976     }
       
  1977 
       
  1978 | NO_INHERIT
       
  1979     {
       
  1980         parseInfo->inheritNamespacesMode = false;
       
  1981     }
       
  1982 
       
  1983 DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator             /* [19] */
       
  1984     {
       
  1985         if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
       
  1986         {
       
  1987             parseInfo->staticContext->error(prologMessage("declare default collation"),
       
  1988                                             ReportContext::XQST0038, fromYYLTYPE(@$, parseInfo));
       
  1989         }
       
  1990         else
       
  1991         {
       
  1992             const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>($4, parseInfo, @$));
       
  1993 
       
  1994             parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
       
  1995             parseInfo->staticContext->setDefaultCollation(coll);
       
  1996         }
       
  1997     }
       
  1998 
       
  1999 BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator                        /* [20] */
       
  2000     {
       
  2001         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3);
       
  2002         if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
       
  2003         {
       
  2004             parseInfo->staticContext->error(prologMessage("declare base-uri"),
       
  2005                                             ReportContext::XQST0032, fromYYLTYPE(@$, parseInfo));
       
  2006         }
       
  2007         else
       
  2008         {
       
  2009             parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
       
  2010             const ReflectYYLTYPE ryy(@$, parseInfo);
       
  2011 
       
  2012             QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>($4, parseInfo->staticContext, &ryy));
       
  2013             /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */
       
  2014 
       
  2015             if(toBeBase.isRelative())
       
  2016                 toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
       
  2017 
       
  2018             parseInfo->staticContext->setBaseURI(toBeBase);
       
  2019         }
       
  2020     }
       
  2021 
       
  2022 SchemaImport: IMPORT SCHEMA SchemaPrefix URILiteral FileLocations Separator         /* [21] */
       
  2023     {
       
  2024         parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
       
  2025                                            "and therefore %1 declarations cannot occur.")
       
  2026                                            .arg(formatKeyword("import schema")),
       
  2027                                         ReportContext::XQST0009, fromYYLTYPE(@$, parseInfo));
       
  2028     }
       
  2029 
       
  2030 SchemaPrefix: /* empty */                                                           /* [22] */
       
  2031 | DEFAULT ELEMENT NAMESPACE
       
  2032 | NAMESPACE NCNAME G_EQ
       
  2033 
       
  2034 ModuleImport: IMPORT MODULE ModuleNamespaceDecl URILiteral FileLocations Separator  /* [23] */
       
  2035     {
       
  2036         if($4.isEmpty())
       
  2037         {
       
  2038             parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
       
  2039                                                .arg(formatKeyword("module import")),
       
  2040                                            ReportContext::XQST0088, fromYYLTYPE(@$, parseInfo));
       
  2041 
       
  2042         }
       
  2043         else
       
  2044         {
       
  2045             /* This is temporary until we have implemented it. */
       
  2046             parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
       
  2047                                             ReportContext::XQST0016, fromYYLTYPE(@$, parseInfo));
       
  2048         }
       
  2049     }
       
  2050 
       
  2051 ModuleNamespaceDecl: /* empty */                                                    /* [X] */
       
  2052 | NAMESPACE NCNAME G_EQ
       
  2053 
       
  2054 FileLocations: /* empty */                                                          /* [X] */
       
  2055 | AT FileLocation
       
  2056 
       
  2057 FileLocation: URILiteral                                                            /* [X] */
       
  2058 | FileLocation COMMA URILiteral
       
  2059 
       
  2060 VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration
       
  2061          VariableValue OptionalDefaultValue Separator                               /* [24] */
       
  2062     {
       
  2063         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
       
  2064         if(variableByName($5, parseInfo))
       
  2065         {
       
  2066             parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already "
       
  2067                                                               "been declared.")
       
  2068                                                .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical($5))),
       
  2069                                             parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
       
  2070                                             fromYYLTYPE(@$, parseInfo));
       
  2071         }
       
  2072         else
       
  2073         {
       
  2074             if($7) /* We got a value assigned. */
       
  2075             {
       
  2076                 const Expression::Ptr checked
       
  2077                         (TypeChecker::applyFunctionConversion($7, $6, parseInfo->staticContext,
       
  2078                                                               $3 ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
       
  2079                                                               $3 ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));
       
  2080 
       
  2081                 pushVariable($5, $6, checked, VariableDeclaration::GlobalVariable, @$, parseInfo);
       
  2082                 parseInfo->declaredVariables.append(parseInfo->variables.last());
       
  2083             }
       
  2084             else /* We got an 'external' declaration. */
       
  2085             {
       
  2086                 const SequenceType::Ptr varType(parseInfo->staticContext->
       
  2087                                                 externalVariableLoader()->announceExternalVariable($5, $6));
       
  2088 
       
  2089                 if(varType)
       
  2090                 {
       
  2091                     /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
       
  2092                      * any references to it. */
       
  2093                     pushVariable($5, varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, @$, parseInfo);
       
  2094                 }
       
  2095                 else if($8)
       
  2096                 {
       
  2097                     /* Ok, the xsl:param got a default value, we make it
       
  2098                      * available as a regular variable declaration. */
       
  2099                     // TODO turn into checked
       
  2100                     pushVariable($5, $6, $8, VariableDeclaration::GlobalVariable, @$, parseInfo);
       
  2101                     // TODO ensure that duplicates are trapped.
       
  2102                 }
       
  2103                 else
       
  2104                 {
       
  2105                     parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
       
  2106                                                                       "variable by name %1.")
       
  2107                                                        .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
       
  2108                                                     parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
       
  2109                                                     fromYYLTYPE(@$, parseInfo));
       
  2110                 }
       
  2111             }
       
  2112         }
       
  2113     }
       
  2114 
       
  2115 VariableValue: EXTERNAL                                                             /* [X] */
       
  2116     {
       
  2117         $$.reset();
       
  2118     }
       
  2119 | ASSIGN ExprSingle
       
  2120     {
       
  2121         $$ = $2;
       
  2122     }
       
  2123 
       
  2124 OptionalDefaultValue: /* Empty. */                                                  /* [X] */
       
  2125     {
       
  2126         $$.reset();
       
  2127     }
       
  2128 | ASSIGN ExprSingle
       
  2129     {
       
  2130         $$ = $2;
       
  2131     }
       
  2132 
       
  2133 ConstructionDecl: DECLARE CONSTRUCTION ConstructionMode Separator                   /* [25] */
       
  2134     {
       
  2135         if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
       
  2136         {
       
  2137             parseInfo->staticContext->error(prologMessage("declare ordering"),
       
  2138                                             ReportContext::XQST0067, fromYYLTYPE(@$, parseInfo));
       
  2139         }
       
  2140         else
       
  2141         {
       
  2142             parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
       
  2143             parseInfo->staticContext->setConstructionMode($3);
       
  2144         }
       
  2145     }
       
  2146 
       
  2147 ConstructionMode: STRIP                                                             /* [X] */
       
  2148     {
       
  2149         $$ = StaticContext::CMStrip;
       
  2150     }
       
  2151 | PRESERVE
       
  2152     {
       
  2153         $$ = StaticContext::CMPreserve;
       
  2154     }
       
  2155 
       
  2156 FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN
       
  2157               {
       
  2158                 $<enums.slot>$ = parseInfo->currentExpressionSlot() - $6.count();
       
  2159               }
       
  2160               TypeDeclaration FunctionBody Separator                                /* [26] */
       
  2161     {
       
  2162         if(!$3)
       
  2163             allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
       
  2164 
       
  2165         /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
       
  2166         const QXmlName::NamespaceCode ns($4.namespaceURI());
       
  2167 
       
  2168         if(parseInfo->isXSLT() && !$4.hasPrefix())
       
  2169         {
       
  2170             parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
       
  2171                                             ReportContext::XTSE0740,
       
  2172                                             fromYYLTYPE(@$, parseInfo));
       
  2173         }
       
  2174 
       
  2175         if($10) /* We got a function body. */
       
  2176         {
       
  2177             if(ns == StandardNamespaces::empty)
       
  2178             {
       
  2179                 parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
       
  2180                                                    "cannot be empty (try the predefined "
       
  2181                                                    "prefix %1 which exists for cases "
       
  2182                                                    "like this)")
       
  2183                                                    .arg(formatKeyword("local")),
       
  2184                                                 ReportContext::XQST0060, fromYYLTYPE(@$, parseInfo));
       
  2185             }
       
  2186             else if(XPathHelper::isReservedNamespace(ns))
       
  2187             {
       
  2188                 parseInfo->staticContext->error(QtXmlPatterns::tr(
       
  2189                                                    "The namespace %1 is reserved; therefore "
       
  2190                                                    "user defined functions may not use it. "
       
  2191                                                    "Try the predefined prefix %2, which "
       
  2192                                                    "exists for these cases.")
       
  2193                                                 .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
       
  2194                                                 parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
       
  2195                                                 fromYYLTYPE(@$, parseInfo));
       
  2196             }
       
  2197             else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
       
  2198                     ns != parseInfo->moduleNamespace)
       
  2199             {
       
  2200                 parseInfo->staticContext->error(QtXmlPatterns::tr(
       
  2201                                                    "The namespace of a user defined "
       
  2202                                                    "function in a library module must be "
       
  2203                                                    "equivalent to the module namespace. "
       
  2204                                                    "In other words, it should be %1 instead "
       
  2205                                                    "of %2")
       
  2206                                                 .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
       
  2207                                                      formatURI(parseInfo->staticContext->namePool(), ns)),
       
  2208                                                 ReportContext::XQST0048, fromYYLTYPE(@$, parseInfo));
       
  2209             }
       
  2210             else
       
  2211             {
       
  2212                 /* Apply function conversion such that the body matches the declared
       
  2213                  * return type. */
       
  2214                 const Expression::Ptr checked(TypeChecker::applyFunctionConversion($10, $9,
       
  2215                                                                                    parseInfo->staticContext,
       
  2216                                                                                    ReportContext::XPTY0004,
       
  2217                                                                                    TypeChecker::Options(TypeChecker::AutomaticallyConvert |
       
  2218                                                                                                         TypeChecker::CheckFocus |
       
  2219                                                                                                         TypeChecker::GeneratePromotion)));
       
  2220 
       
  2221                 const int argCount = $6.count();
       
  2222                 const FunctionSignature::Ptr sign(new FunctionSignature($4 /* name */,
       
  2223                                                                         argCount /* minArgs */,
       
  2224                                                                         argCount /* maxArgs */,
       
  2225                                                                         $9 /* returnType */));
       
  2226                 sign->setArguments($6);
       
  2227                 const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
       
  2228                 UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
       
  2229 
       
  2230                 for(; it != end; ++it)
       
  2231                 {
       
  2232                     if(*(*it)->signature() == *sign)
       
  2233                     {
       
  2234                         parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
       
  2235                                                            "the signature %1.")
       
  2236                                                            .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
       
  2237                                                         parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE(@$, parseInfo));
       
  2238                     }
       
  2239                 }
       
  2240 
       
  2241                 VariableDeclaration::List argDecls;
       
  2242 
       
  2243                 for(int i = 0; i < argCount; ++i)
       
  2244                     argDecls.append(parseInfo->variables.at(i));
       
  2245 
       
  2246                 if($<enums.slot>8 > -1)
       
  2247                 {
       
  2248                     /* We have allocated slots, so now push them out of scope. */
       
  2249                     parseInfo->finalizePushedVariable(argCount);
       
  2250                 }
       
  2251 
       
  2252                 parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, $<enums.slot>8, argDecls)));
       
  2253             }
       
  2254         }
       
  2255         else /* We got an 'external' declaration. */
       
  2256         {
       
  2257             parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
       
  2258                                                "All supported functions can be used directly, "
       
  2259                                                "without first declaring them as external"),
       
  2260                                             ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
       
  2261         }
       
  2262     }
       
  2263 
       
  2264 ParamList: /* empty */                                                              /* [27] */
       
  2265     {
       
  2266         $$ = FunctionArgument::List();
       
  2267     }
       
  2268 | Param
       
  2269     {
       
  2270         FunctionArgument::List l;
       
  2271         l.append($1);
       
  2272         $$ = l;
       
  2273     }
       
  2274 | ParamList COMMA Param
       
  2275     {
       
  2276         FunctionArgument::List::const_iterator it($1.constBegin());
       
  2277         const FunctionArgument::List::const_iterator end($1.constEnd());
       
  2278 
       
  2279         for(; it != end; ++it)
       
  2280         {
       
  2281             if((*it)->name() == $3->name())
       
  2282             {
       
  2283                 parseInfo->staticContext->error(QtXmlPatterns::tr("An argument by name %1 has already "
       
  2284                                                    "been declared. Every argument name "
       
  2285                                                    "must be unique.")
       
  2286                                                    .arg(formatKeyword(parseInfo->staticContext->namePool(), $3->name())),
       
  2287                                                 ReportContext::XQST0039, fromYYLTYPE(@$, parseInfo));
       
  2288             }
       
  2289         }
       
  2290 
       
  2291         $1.append($3);
       
  2292         $$ = $1;
       
  2293     }
       
  2294 
       
  2295 Param: DOLLAR VarName TypeDeclaration                                               /* [28] */
       
  2296     {
       
  2297         pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
       
  2298         $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
       
  2299     }
       
  2300 
       
  2301 FunctionBody: EXTERNAL                                                              /* [X] */
       
  2302     {
       
  2303         $$.reset();
       
  2304     }
       
  2305 | EnclosedExpr
       
  2306 
       
  2307 EnclosedExpr: CURLY_LBRACE Expr CURLY_RBRACE                                        /* [29] */
       
  2308     {
       
  2309         $$ = $2;
       
  2310     }
       
  2311 
       
  2312 QueryBody: Expr                                                                     /* [30] */
       
  2313 
       
  2314 /**
       
  2315  * A pattern as found in for instance xsl:template/@match.
       
  2316  *
       
  2317  * @note When using this pattern, remember to set ParserContext::isParsingPattern.
       
  2318  *
       
  2319  * @see <a href="http://www.w3.org/TR/xslt20/#dt-pattern">XSL Transformations
       
  2320  * (XSLT) Version 2.0, 5.5.2 Syntax of Patterns</a>
       
  2321  */
       
  2322 Pattern: PathPattern                                                                /* [XSLT20-1] */
       
  2323 | Pattern BAR PathPattern
       
  2324     {
       
  2325         $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
       
  2326     }
       
  2327 
       
  2328 PathPattern: RelativePathPattern                                                    /* [XSLT20-2] */
       
  2329 | SLASH
       
  2330     {
       
  2331         /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
       
  2332          * "Similarly, / matches a document node, and only a document node,
       
  2333          * because the result of the expression root(.)//(/) returns the root
       
  2334          * node of the tree containing the context node if and only if it is a
       
  2335          * document node." */
       
  2336         $$ = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), @$, parseInfo);
       
  2337     }
       
  2338 | SLASH RelativePathPattern
       
  2339     {
       
  2340         /* /axis::node-test
       
  2341          *       =>
       
  2342          * axis::node-test[parent::document-node()]
       
  2343          *
       
  2344          * In practice it looks like this. $2 is:
       
  2345          *
       
  2346          *     TruthPredicate
       
  2347          *          AxisStep    self::element(c)
       
  2348          *          TruthPredicate
       
  2349          *              AxisStep    parent::element(b)
       
  2350          *              AxisStep    parent::element(a)
       
  2351          *
       
  2352          * and we want this:
       
  2353          *
       
  2354          *      TruthPredicate
       
  2355          *          AxisStep    self::element(c)
       
  2356          *          TruthPredicate
       
  2357          *              AxisStep    self::element(b)
       
  2358          *              TruthPredicate
       
  2359          *                  AxisStep    parent::element(a)
       
  2360          *                  AxisStep    parent::document()
       
  2361          *
       
  2362          * So we want to rewrite the predicate deepest down into a
       
  2363          * another TruthPredicate containing the AxisStep.
       
  2364          *
       
  2365          * The simplest case where $2 is only an axis step is special. When $2 is:
       
  2366          *
       
  2367          *  AxisStep self::element(a)
       
  2368          *
       
  2369          * we want:
       
  2370          *
       
  2371          *  TruthPredicate
       
  2372          *      AxisStep self::element(a)
       
  2373          *      AxisStep parent::document()
       
  2374          */
       
  2375 
       
  2376         /* First, find the target. */
       
  2377         Expression::Ptr target($2);
       
  2378 
       
  2379         while(isPredicate(target->id()))
       
  2380         {
       
  2381             const Expression::Ptr candidate(target->operands().at(1));
       
  2382 
       
  2383             if(isPredicate(candidate->id()))
       
  2384                 target = candidate;
       
  2385             else
       
  2386                 break; /* target is now the last predicate. */
       
  2387         }
       
  2388 
       
  2389         if(target->is(Expression::IDAxisStep))
       
  2390         {
       
  2391             $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
       
  2392                                                  parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
       
  2393         }
       
  2394         else
       
  2395         {
       
  2396             const Expression::List targetOperands(target->operands());
       
  2397             Expression::List newOps;
       
  2398             newOps.append(targetOperands.at(0));
       
  2399 
       
  2400             newOps.append(create(GenericPredicate::create(targetOperands.at(1),
       
  2401                                                           create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
       
  2402                                                           parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo));
       
  2403 
       
  2404             target->setOperands(newOps);
       
  2405             $$ = $2;
       
  2406         }
       
  2407     }
       
  2408 | SLASHSLASH RelativePathPattern
       
  2409     {
       
  2410         /* //axis::node-test
       
  2411          *        =>
       
  2412          * axis::node-test[parent::node()]
       
  2413          *
       
  2414          * Spec says: "//para matches any para element that has a parent node."
       
  2415          */
       
  2416         $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo),
       
  2417                                              parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
       
  2418     }
       
  2419 | IdKeyPattern
       
  2420 | IdKeyPattern SLASH RelativePathPattern
       
  2421     {
       
  2422         createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
       
  2423     }
       
  2424 | IdKeyPattern SLASHSLASH RelativePathPattern
       
  2425     {
       
  2426         createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
       
  2427     }
       
  2428 
       
  2429 IdKeyPattern: FunctionCallExpr
       
  2430     {
       
  2431         const Expression::List ands($1->operands());
       
  2432         const FunctionSignature::Ptr signature($1->as<FunctionCall>()->signature());
       
  2433         const QXmlName name(signature->name());
       
  2434         const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
       
  2435         const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);
       
  2436 
       
  2437         if(name == id)
       
  2438         {
       
  2439             const Expression::ID id = ands.first()->id();
       
  2440             if(!isVariableReference(id) && id != Expression::IDStringValue)
       
  2441             {
       
  2442                 parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
       
  2443                                                                   "the argument must be a variable reference or a string literal.")
       
  2444                                                                   .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
       
  2445                                                 ReportContext::XPST0003,
       
  2446                                                 fromYYLTYPE(@$, parseInfo));
       
  2447             }
       
  2448         }
       
  2449         else if(name == key)
       
  2450         {
       
  2451             if(ands.first()->id() != Expression::IDStringValue)
       
  2452             {
       
  2453                 parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
       
  2454                                                                   "must be a string literal, when used for matching.")
       
  2455                                                                   .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
       
  2456                                                 ReportContext::XPST0003,
       
  2457                                                 fromYYLTYPE(@$, parseInfo));
       
  2458             }
       
  2459 
       
  2460             const Expression::ID id2 = ands.at(1)->id();
       
  2461             if(!isVariableReference(id2) &&
       
  2462                id2 != Expression::IDStringValue &&
       
  2463                id2 != Expression::IDIntegerValue &&
       
  2464                id2 != Expression::IDBooleanValue &&
       
  2465                id2 != Expression::IDFloat)
       
  2466             {
       
  2467                 parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
       
  2468                                                                   "must be a literal or a variable reference, when used for matching.")
       
  2469                                                                   .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
       
  2470                                                 ReportContext::XPST0003,
       
  2471                                                 fromYYLTYPE(@$, parseInfo));
       
  2472             }
       
  2473 
       
  2474             if(ands.count() == 3)
       
  2475             {
       
  2476                 parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
       
  2477                                                                   .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
       
  2478                                                 ReportContext::XPST0003,
       
  2479                                                 fromYYLTYPE(@$, parseInfo));
       
  2480             }
       
  2481 
       
  2482         }
       
  2483         else
       
  2484         {
       
  2485             const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
       
  2486             parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
       
  2487                                                               "and %2, not %3, can be used for matching.")
       
  2488                                                               .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
       
  2489                                                                    formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
       
  2490                                                                    formatFunction(parseInfo->staticContext->namePool(), signature)),
       
  2491                                             ReportContext::XPST0003,
       
  2492                                             fromYYLTYPE(@$, parseInfo));
       
  2493         }
       
  2494 
       
  2495         $$ = $1;
       
  2496     }
       
  2497 
       
  2498 RelativePathPattern: PatternStep                                                    /* [XSLT20-3] */
       
  2499 | RelativePathPattern SLASH PatternStep
       
  2500     {
       
  2501         $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
       
  2502     }
       
  2503 | RelativePathPattern SLASHSLASH PatternStep
       
  2504     {
       
  2505         $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
       
  2506     }
       
  2507 
       
  2508 PatternStep: FilteredAxisStep
       
  2509     {
       
  2510         const Expression::Ptr expr(findAxisStep($1));
       
  2511 
       
  2512         const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
       
  2513         AxisStep *const axisStep = expr->as<AxisStep>();
       
  2514 
       
  2515         /* Here we constrain the possible axes, and we rewrite the axes as according
       
  2516          * to 5.5.3 The Meaning of a Pattern.
       
  2517          *
       
  2518          * However, we also rewrite axis child and attribute to axis self. The
       
  2519          * reason for this is that if we don't, we will match the children of
       
  2520          * the context node, instead of the context node itself. The formal
       
  2521          * definition of a pattern, root(.)//EE is insensitive to context,
       
  2522          * while the way we implement pattern, "the other way of seeing it",
       
  2523          * e.g from right to left, are very much. */
       
  2524 
       
  2525         if(axisStep->nodeTest() == BuiltinTypes::document
       
  2526            || axis == QXmlNodeModelIndex::AxisChild)
       
  2527             axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
       
  2528         else if(axis == QXmlNodeModelIndex::AxisAttribute)
       
  2529         {
       
  2530             axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
       
  2531             /* Consider that the user write attribute::node().  This is
       
  2532              * semantically equivalent to attribute::attribute(), but since we have changed
       
  2533              * the axis to axis self, we also need to change the node test, such that we
       
  2534              * have self::attribute(). */
       
  2535             if(*axisStep->nodeTest() == *BuiltinTypes::node)
       
  2536                 axisStep->setNodeTest(BuiltinTypes::attribute);
       
  2537         }
       
  2538         else
       
  2539         {
       
  2540             parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
       
  2541                                                               "only axis %2 or %3 can.")
       
  2542                                             .arg(formatKeyword(AxisStep::axisName(axis)),
       
  2543                                                  formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
       
  2544                                                  formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
       
  2545                                             ReportContext::XPST0003,
       
  2546                                             fromYYLTYPE(@$, parseInfo));
       
  2547         }
       
  2548 
       
  2549         $$ = $1;
       
  2550     }
       
  2551 
       
  2552 Expr: ExprSingle                                                                    /* [31] */
       
  2553 | ExpressionSequence
       
  2554     {
       
  2555         $$ = create(new ExpressionSequence($1), @$, parseInfo);
       
  2556     }
       
  2557 
       
  2558 ExpressionSequence: ExprSingle COMMA ExprSingle                                     /* [X] */
       
  2559     {
       
  2560         Expression::List l;
       
  2561         l.append($1);
       
  2562         l.append($3);
       
  2563         $$ = l;
       
  2564     }
       
  2565 | ExpressionSequence COMMA ExprSingle
       
  2566     {
       
  2567         $1.append($3);
       
  2568         $$ = $1;
       
  2569     }
       
  2570 
       
  2571 ExprSingle: OrExpr                                                                  /* [32] */
       
  2572 | FLWORExpr
       
  2573 | QuantifiedExpr
       
  2574 | TypeswitchExpr
       
  2575 | IfExpr
       
  2576 | AVT LPAREN AttrValueContent RPAREN
       
  2577     {
       
  2578         $$ = createDirAttributeValue($3, parseInfo, @$);
       
  2579     }
       
  2580 
       
  2581 OptionalModes: /* Empty. */                                                         /* [X] */
       
  2582     {
       
  2583         QVector<QXmlName> result;
       
  2584         result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
       
  2585         $$ = result;
       
  2586     }
       
  2587 | MODE Modes
       
  2588     {
       
  2589         $$ = $2;
       
  2590     }
       
  2591 
       
  2592 OptionalMode: /* Empty. */                                                          /* [X] */
       
  2593     {
       
  2594             $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
       
  2595     }
       
  2596 | MODE Mode
       
  2597     {
       
  2598         $$ = $2;
       
  2599     }
       
  2600 
       
  2601 Modes: Mode
       
  2602     {
       
  2603         QVector<QXmlName> result;
       
  2604         result.append($1);
       
  2605         $$ = result;
       
  2606     }
       
  2607 | Modes COMMA Mode
       
  2608     {
       
  2609         $1.append($3);
       
  2610         $$ = $1;
       
  2611     }
       
  2612 
       
  2613 Mode: QName                                                                         /* [X] */
       
  2614     {
       
  2615         $$ = $1;
       
  2616     }
       
  2617 | NCNAME
       
  2618     {
       
  2619         if($1 == QLatin1String("#current"))
       
  2620             $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
       
  2621         else if($1 == QLatin1String("#default"))
       
  2622             $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
       
  2623         else if($1 == QLatin1String("#all"))
       
  2624             $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
       
  2625         else
       
  2626         {
       
  2627             const ReflectYYLTYPE ryy(@$, parseInfo);
       
  2628 
       
  2629             if(!QXmlUtils::isNCName($1))
       
  2630             {
       
  2631                 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
       
  2632                                                                   .arg(formatKeyword($1)),
       
  2633                                                 ReportContext::XTSE0550,
       
  2634                                                 fromYYLTYPE(@$, parseInfo));
       
  2635             }
       
  2636 
       
  2637             $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
       
  2638         }
       
  2639     }
       
  2640 
       
  2641 
       
  2642 FLWORExpr: ForClause                                                                /* [33] */
       
  2643 | LetClause
       
  2644 
       
  2645 ForClause: FOR DOLLAR VarName TypeDeclaration
       
  2646            PositionalVar IN ExprSingle
       
  2647            {
       
  2648                /* We're pushing the range variable here, not the positional. */
       
  2649                $<expr>$ = pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2650            }
       
  2651            {
       
  2652                /* It is ok this appears after PositionalVar, because currentRangeSlot()
       
  2653                 * uses a different "channel" than currentPositionSlot(), so they can't trash
       
  2654                 * each other. */
       
  2655                $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
       
  2656            }
       
  2657            ForTail                                                                  /* [34] */
       
  2658     {
       
  2659         Q_ASSERT($7);
       
  2660         Q_ASSERT($10);
       
  2661 
       
  2662         /* We want the next last pushed variable, since we push the range variable after the
       
  2663          * positional variable. */
       
  2664         if($5 != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == $3)
       
  2665         {
       
  2666             /* Ok, a positional variable is used since its slot is not -1, and its name is equal
       
  2667              * to our range variable. This is an error. */
       
  2668             parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
       
  2669                                                "from the positional variable. Hence, the two variables named %1 collide.")
       
  2670                                                .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
       
  2671                                             ReportContext::XQST0089,
       
  2672                                             fromYYLTYPE(@$, parseInfo));
       
  2673 
       
  2674         }
       
  2675 
       
  2676         const Expression::Ptr retBody(create(new ForClause($<enums.slot>9, $<expr>8, $10, $5), @$, parseInfo));
       
  2677         ReturnOrderBy *const rob = locateReturnClause($10);
       
  2678 
       
  2679         if(rob)
       
  2680             $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), @$, parseInfo);
       
  2681         else
       
  2682             $$ = retBody;
       
  2683 
       
  2684         parseInfo->finalizePushedVariable();
       
  2685 
       
  2686         if($5 != -1) /* We also have a positional variable to remove from the scope. */
       
  2687             parseInfo->finalizePushedVariable();
       
  2688     }
       
  2689 
       
  2690 ForTail: COMMA DOLLAR VarName TypeDeclaration
       
  2691          PositionalVar IN ExprSingle
       
  2692          {
       
  2693              pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2694          }
       
  2695          {
       
  2696              /* It is ok this appears after PositionalVar, because currentRangeSlot()
       
  2697               * uses a different "channel" than currentPositionSlot(), so they can't trash
       
  2698               * each other. */
       
  2699              $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
       
  2700          }
       
  2701          ForTail                                                                    /* [X] */
       
  2702     {
       
  2703         $$ = create(new ForClause($<enums.slot>9, $<expr>7, $10, $5), @$, parseInfo);
       
  2704 
       
  2705         parseInfo->finalizePushedVariable();
       
  2706 
       
  2707         if($5 != -1) /* We also have a positional variable to remove from the scope. */
       
  2708             parseInfo->finalizePushedVariable();
       
  2709     }
       
  2710 
       
  2711 | WhereClause
       
  2712 | ForClause
       
  2713 | LetClause
       
  2714 
       
  2715 PositionalVar: /* empty */                                                          /* [35] */
       
  2716     {
       
  2717         $$ = -1;
       
  2718     }
       
  2719 
       
  2720 | AT DOLLAR VarName
       
  2721     {
       
  2722         pushVariable($3, CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
       
  2723                      VariableDeclaration::PositionalVariable, @$, parseInfo);
       
  2724         $$ = parseInfo->currentPositionSlot();
       
  2725     }
       
  2726 
       
  2727 LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
       
  2728            {
       
  2729                 $<expr>$ = pushVariable($4, quantificationType($5), $7, VariableDeclaration::ExpressionVariable, @$, parseInfo);
       
  2730            }
       
  2731            LetTail                                                                  /* [36] */
       
  2732     {
       
  2733         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  2734 
       
  2735         Q_ASSERT(parseInfo->variables.top()->name == $4);
       
  2736         $$ = create(new LetClause($<expr>8, $9, parseInfo->variables.top()), @$, parseInfo);
       
  2737         parseInfo->finalizePushedVariable();
       
  2738     }
       
  2739 
       
  2740 LetTail: COMMA DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
       
  2741          { $<expr>$ = pushVariable($3, quantificationType($4), $6, VariableDeclaration::ExpressionVariable, @$, parseInfo);}
       
  2742          LetTail                                                                    /* [X] */
       
  2743     {
       
  2744         Q_ASSERT(parseInfo->variables.top()->name == $3);
       
  2745         $$ = create(new LetClause($<expr>7, $8, parseInfo->variables.top()), @$, parseInfo);
       
  2746         parseInfo->finalizePushedVariable();
       
  2747     }
       
  2748 
       
  2749 | WhereClause
       
  2750 | ForClause
       
  2751 | LetClause
       
  2752 
       
  2753 WhereClause: OrderByClause RETURN ExprSingle                                        /* [37] */
       
  2754     {
       
  2755         if($1.isEmpty())
       
  2756             $$ = $3;
       
  2757         else
       
  2758             $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
       
  2759     }
       
  2760 
       
  2761 | WHERE ExprSingle OrderByClause RETURN ExprSingle
       
  2762     {
       
  2763         if($3.isEmpty())
       
  2764             $$ = create(new IfThenClause($2, $5, create(new EmptySequence, @$, parseInfo)), @$, parseInfo);
       
  2765         else
       
  2766             $$ = create(new IfThenClause($2, createReturnOrderBy($3, $5, parseInfo->orderStability.pop(), @$, parseInfo),
       
  2767                                          create(new EmptySequence, @$, parseInfo)),
       
  2768                         @$, parseInfo);
       
  2769     }
       
  2770 
       
  2771 OrderByClause: /* Empty. */                                                         /* [38] */
       
  2772     {
       
  2773         $$ = OrderSpecTransfer::List();
       
  2774     }
       
  2775 | MandatoryOrderByClause
       
  2776 
       
  2777 MandatoryOrderByClause: OrderByInputOrder OrderSpecList
       
  2778     {
       
  2779         $$ = $2;
       
  2780     }
       
  2781 
       
  2782 OrderSpecList: OrderSpecList COMMA OrderSpec                                        /* [39] */
       
  2783     {
       
  2784         OrderSpecTransfer::List list;
       
  2785         list += $1;
       
  2786         list.append($3);
       
  2787         $$ = list;
       
  2788     }
       
  2789 | OrderSpec
       
  2790     {
       
  2791         OrderSpecTransfer::List list;
       
  2792         list.append($1);
       
  2793         $$ = list;
       
  2794     }
       
  2795 
       
  2796 OrderSpec: ExprSingle DirectionModifier EmptynessModifier CollationModifier         /* [40] */
       
  2797     {
       
  2798         $$ = OrderSpecTransfer($1, OrderBy::OrderSpec($2, $3));
       
  2799     }
       
  2800 
       
  2801 DirectionModifier: /* Empty. */                                                     /* [X] */
       
  2802     {
       
  2803         /* Where does the specification state the default value is ascending?
       
  2804          *
       
  2805          * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
       
  2806          *
       
  2807          * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
       
  2808          *  of values encountered when evaluating their orderspecs from left to right for
       
  2809          *  which one value is greater-than the other (as defined above), then:
       
  2810          *
       
  2811          *      1. If V1 is greater-than V2: If the orderspec specifies descending,
       
  2812          *         then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
       
  2813          *      2. If V2 is greater-than V1: If the orderspec specifies descending,
       
  2814          *         then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
       
  2815          *
       
  2816          * which means that if you don't specify anything, or you
       
  2817          * specify ascending, you get the same result.
       
  2818          */
       
  2819         $$ = OrderBy::OrderSpec::Ascending;
       
  2820     }
       
  2821 
       
  2822 | ASCENDING
       
  2823     {
       
  2824         $$ = OrderBy::OrderSpec::Ascending;
       
  2825     }
       
  2826 
       
  2827 | DESCENDING
       
  2828     {
       
  2829         $$ = OrderBy::OrderSpec::Descending;
       
  2830     }
       
  2831 
       
  2832 EmptynessModifier: /* Empty. */                                                     /* [X] */
       
  2833     {
       
  2834         $$ = parseInfo->staticContext->orderingEmptySequence();
       
  2835     }
       
  2836 | OrderingEmptySequence
       
  2837 
       
  2838 CollationModifier: /* Empty. */                                                     /* [X] */
       
  2839 | COLLATION URILiteral
       
  2840     {
       
  2841         if(parseInfo->isXSLT())
       
  2842             resolveAndCheckCollation<ReportContext::XTDE1035>($2, parseInfo, @$);
       
  2843         else
       
  2844             resolveAndCheckCollation<ReportContext::XQST0076>($2, parseInfo, @$);
       
  2845     }
       
  2846 | INTERNAL COLLATION ExprSingle
       
  2847     {
       
  2848         /* We do nothing. We don't use collations, and we have this non-terminal
       
  2849          * in order to accept expressions. */
       
  2850     }
       
  2851 
       
  2852 OrderByInputOrder: STABLE ORDER BY                                                  /* [X] */
       
  2853     {
       
  2854         parseInfo->orderStability.push(OrderBy::StableOrder);
       
  2855     }
       
  2856 | ORDER BY
       
  2857     {
       
  2858         parseInfo->orderStability.push(OrderBy::UnstableOrder);
       
  2859     }
       
  2860 
       
  2861 QuantifiedExpr: SomeQuantificationExpr                                              /* [42] */
       
  2862 | EveryQuantificationExpr
       
  2863 
       
  2864 SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle
       
  2865                         {
       
  2866                             pushVariable($3, quantificationType($4), $6,
       
  2867                                          VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2868                         }
       
  2869                         {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
       
  2870                         SomeQuantificationTail                                      /* [X] */
       
  2871     {
       
  2872         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  2873         $$ = create(new QuantifiedExpression($<enums.slot>8,
       
  2874                                              QuantifiedExpression::Some, $<expr>6, $9), @$, parseInfo);
       
  2875         parseInfo->finalizePushedVariable();
       
  2876     }
       
  2877 
       
  2878 SomeQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
       
  2879                         {
       
  2880                             $<expr>$ = pushVariable($3, quantificationType($4), $6,
       
  2881                                                     VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2882                         }
       
  2883                         {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
       
  2884                         SomeQuantificationTail                                      /* [X] */
       
  2885     {
       
  2886         $$ = create(new QuantifiedExpression($<enums.slot>8,
       
  2887                                              QuantifiedExpression::Some, $<expr>7, $9), @$, parseInfo);
       
  2888         parseInfo->finalizePushedVariable();
       
  2889     }
       
  2890 
       
  2891 | SatisfiesClause
       
  2892 
       
  2893 EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle
       
  2894                          {
       
  2895                             pushVariable($3, quantificationType($4), $6,
       
  2896                                          VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2897                          }
       
  2898                          {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
       
  2899                          EveryQuantificationTail                                    /* [X] */
       
  2900     {
       
  2901         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  2902         $$ = create(new QuantifiedExpression($<enums.slot>8,
       
  2903                                              QuantifiedExpression::Every, $<expr>6, $9), @$, parseInfo);
       
  2904         parseInfo->finalizePushedVariable();
       
  2905     }
       
  2906 
       
  2907 EveryQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
       
  2908                          {
       
  2909                             $<expr>$ = pushVariable($3, quantificationType($4), $6,
       
  2910                                                     VariableDeclaration::RangeVariable, @$, parseInfo);
       
  2911                          }
       
  2912                          {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
       
  2913                          EveryQuantificationTail                                    /* [X] */
       
  2914     {
       
  2915         $$ = create(new QuantifiedExpression($<enums.slot>8,
       
  2916                                              QuantifiedExpression::Every, $<expr>7, $9), @$, parseInfo);
       
  2917         parseInfo->finalizePushedVariable();
       
  2918     }
       
  2919 
       
  2920 | SatisfiesClause
       
  2921 
       
  2922 SatisfiesClause: SATISFIES ExprSingle                                               /* [X] */
       
  2923     {
       
  2924         $$ = $2;
       
  2925     }
       
  2926 
       
  2927 /*
       
  2928  * Typeswitches are re-written to a combination between @c if clauses, <tt>instance of</tt>, and
       
  2929  * @c let bindings. For example, the query:
       
  2930  *
       
  2931  * @code
       
  2932  * typeswitch(input)
       
  2933  * case element()             return <!-- a comment -->
       
  2934  * case $i as attribute(name) return name($i)
       
  2935  * default                    return "Didn't match"
       
  2936  * @endcode
       
  2937  *
       
  2938  * becomes:
       
  2939  *
       
  2940  * @code
       
  2941  * if(input instance of element())
       
  2942  * then <!-- a comment -->
       
  2943  * else if(input instance of attribute(name))
       
  2944  *      then let $i as attribute(name) := input return name($i)
       
  2945  *      else "Didn't match"
       
  2946  * @endcode
       
  2947  */
       
  2948 
       
  2949 TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN
       
  2950                 {
       
  2951                     parseInfo->typeswitchSource.push($3);
       
  2952                 }
       
  2953                 CaseClause                                                          /* [43] */
       
  2954     {
       
  2955         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  2956         parseInfo->typeswitchSource.pop();
       
  2957         $$ = $6;
       
  2958     }
       
  2959 
       
  2960 CaseClause: CASE CaseVariable SequenceType                                          /* [44] */
       
  2961     {
       
  2962         if(!$2.isNull())
       
  2963         {
       
  2964             pushVariable($2, $3, parseInfo->typeswitchSource.top(),
       
  2965                          VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
       
  2966         }
       
  2967     }
       
  2968     RETURN ExprSingle
       
  2969     {
       
  2970         /* The variable shouldn't be in-scope for other case branches. */
       
  2971         if(!$2.isNull())
       
  2972             parseInfo->finalizePushedVariable();
       
  2973     }
       
  2974     CaseTail
       
  2975     {
       
  2976         const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), $3), @$, parseInfo));
       
  2977         $$ = create(new IfThenClause(instanceOf, $6, $8), @$, parseInfo);
       
  2978     }
       
  2979 
       
  2980 CaseTail: CaseClause                                                                /* [X] */
       
  2981 | CaseDefault
       
  2982 
       
  2983 CaseVariable: /* Empty. */                                                          /* [X] */
       
  2984     {
       
  2985         $$ = QXmlName();
       
  2986     }
       
  2987 
       
  2988 | DOLLAR ElementName AS
       
  2989     {
       
  2990         $$ = $2;
       
  2991     }
       
  2992 
       
  2993 CaseDefault: DEFAULT RETURN ExprSingle                                              /* [X] */
       
  2994     {
       
  2995         $$ = $3;
       
  2996     }
       
  2997 | DEFAULT DOLLAR ElementName
       
  2998     {
       
  2999         if(!$3.isNull())
       
  3000         {
       
  3001             pushVariable($3, parseInfo->typeswitchSource.top()->staticType(),
       
  3002                          parseInfo->typeswitchSource.top(),
       
  3003                          VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
       
  3004         }
       
  3005     }
       
  3006   RETURN ExprSingle
       
  3007     {
       
  3008         if(!$3.isNull())
       
  3009             parseInfo->finalizePushedVariable();
       
  3010         $$ = $6;
       
  3011     }
       
  3012 
       
  3013 IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle                       /* [45] */
       
  3014     {
       
  3015         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3016         $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
       
  3017     }
       
  3018 
       
  3019 OrExpr: AndExpr                                                                     /* [46] */
       
  3020 | OrExpr OR AndExpr
       
  3021     {
       
  3022         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3023         $$ = create(new OrExpression($1, $3), @$, parseInfo);
       
  3024     }
       
  3025 
       
  3026 AndExpr: ComparisonExpr                                                             /* [47] */
       
  3027 | AndExpr AND ComparisonExpr
       
  3028     {
       
  3029         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3030         $$ = create(new AndExpression($1, $3), @$, parseInfo);
       
  3031     }
       
  3032 
       
  3033 ComparisonExpr: RangeExpr                                                           /* [48] */
       
  3034 | ValueComp
       
  3035 | GeneralComp
       
  3036 | NodeComp
       
  3037 
       
  3038 RangeExpr: AdditiveExpr                                                             /* [49] */
       
  3039 | AdditiveExpr TO AdditiveExpr
       
  3040     {
       
  3041         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3042         $$ = create(new RangeExpression($1, $3), @$, parseInfo);
       
  3043     }
       
  3044 
       
  3045 AdditiveExpr: MultiplicativeExpr                                                    /* [50] */
       
  3046 | AdditiveExpr AdditiveOperator MultiplicativeExpr
       
  3047     {
       
  3048         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3049         $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
       
  3050     }
       
  3051 
       
  3052 AdditiveOperator: PLUS  {$$ = AtomicMathematician::Add;}                            /* [X] */
       
  3053 | MINUS                 {$$ = AtomicMathematician::Substract;}
       
  3054 
       
  3055 MultiplicativeExpr: UnionExpr                                                       /* [51] */
       
  3056 | MultiplicativeExpr MultiplyOperator UnionExpr
       
  3057     {
       
  3058         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3059         $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
       
  3060     }
       
  3061 
       
  3062 MultiplyOperator: STAR  {$$ = AtomicMathematician::Multiply;}                       /* [X] */
       
  3063 | DIV                   {$$ = AtomicMathematician::Div;}
       
  3064 | IDIV                  {$$ = AtomicMathematician::IDiv;}
       
  3065 | MOD                   {$$ = AtomicMathematician::Mod;}
       
  3066 
       
  3067 UnionExpr: IntersectExceptExpr                                                      /* [52] */
       
  3068 | UnionExpr UnionOperator IntersectExceptExpr
       
  3069     {
       
  3070         allowedIn(QueryLanguages(QXmlQuery::XQuery10
       
  3071                                  | QXmlQuery::XPath20
       
  3072                                  | QXmlQuery::XmlSchema11IdentityConstraintField
       
  3073                                  | QXmlQuery::XmlSchema11IdentityConstraintSelector),
       
  3074                   parseInfo, @$);
       
  3075         $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
       
  3076     }
       
  3077 
       
  3078 IntersectExceptExpr: InstanceOfExpr                                                 /* [53] */
       
  3079 | IntersectExceptExpr IntersectOperator InstanceOfExpr
       
  3080     {
       
  3081         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3082         $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo);
       
  3083     }
       
  3084 
       
  3085 UnionOperator: UNION                                                                /* [X] */
       
  3086 | BAR
       
  3087 
       
  3088 IntersectOperator: INTERSECT                                                        /* [X] */
       
  3089     {
       
  3090         $$ = CombineNodes::Intersect;
       
  3091     }
       
  3092 | EXCEPT
       
  3093     {
       
  3094         $$ = CombineNodes::Except;
       
  3095     }
       
  3096 
       
  3097 InstanceOfExpr: TreatExpr                                                           /* [54] */
       
  3098 | TreatExpr INSTANCE OF SequenceType
       
  3099     {
       
  3100         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3101         $$ = create(new InstanceOf($1,
       
  3102                     SequenceType::Ptr($4)), @$, parseInfo);
       
  3103     }
       
  3104 
       
  3105 TreatExpr: CastableExpr                                                             /* [55] */
       
  3106 | CastableExpr TREAT AS SequenceType
       
  3107     {
       
  3108         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3109         $$ = create(new TreatAs($1, $4), @$, parseInfo);
       
  3110     }
       
  3111 
       
  3112 CastableExpr: CastExpr                                                              /* [56] */
       
  3113 | CastExpr CASTABLE AS SingleType
       
  3114     {
       
  3115         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3116         $$ = create(new CastableAs($1, $4), @$, parseInfo);
       
  3117     }
       
  3118 
       
  3119 CastExpr: UnaryExpr                                                                 /* [57] */
       
  3120 | UnaryExpr CAST AS SingleType
       
  3121     {
       
  3122         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3123         $$ = create(new CastAs($1, $4), @$, parseInfo);
       
  3124     }
       
  3125 
       
  3126 UnaryExpr: ValueExpr                                                                /* [58] */
       
  3127 | UnaryOperator UnaryExpr
       
  3128     {
       
  3129         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3130         $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo);
       
  3131     }
       
  3132 
       
  3133 UnaryOperator: PLUS                                                                 /* [X] */
       
  3134     {
       
  3135         $$ = AtomicMathematician::Add;
       
  3136     }
       
  3137 | MINUS
       
  3138     {
       
  3139         $$ = AtomicMathematician::Substract;
       
  3140     }
       
  3141 
       
  3142 ValueExpr: ValidateExpr                                                             /* [59] */
       
  3143 | PathExpr
       
  3144 | ExtensionExpr
       
  3145 
       
  3146 GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr                          /* [60] */
       
  3147     {
       
  3148         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3149         $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo);
       
  3150     }
       
  3151 
       
  3152 GeneralComparisonOperator: G_EQ {$$ = AtomicComparator::OperatorEqual;}             /* [X] */
       
  3153 | G_NE                          {$$ = AtomicComparator::OperatorNotEqual;}
       
  3154 | G_GE                          {$$ = AtomicComparator::OperatorGreaterOrEqual;}
       
  3155 | G_GT                          {$$ = AtomicComparator::OperatorGreaterThan;}
       
  3156 | G_LE                          {$$ = AtomicComparator::OperatorLessOrEqual;}
       
  3157 | G_LT                          {$$ = AtomicComparator::OperatorLessThan;}
       
  3158 
       
  3159 ValueComp: RangeExpr ValueComparisonOperator RangeExpr                              /* [61] */
       
  3160     {
       
  3161         $$ = create(new ValueComparison($1, $2, $3), @$, parseInfo);
       
  3162     }
       
  3163 
       
  3164 ValueComparisonOperator: EQ {$$ = AtomicComparator::OperatorEqual;}
       
  3165 | NE                        {$$ = AtomicComparator::OperatorNotEqual;}
       
  3166 | GE                        {$$ = AtomicComparator::OperatorGreaterOrEqual;}
       
  3167 | GT                        {$$ = AtomicComparator::OperatorGreaterThan;}
       
  3168 | LE                        {$$ = AtomicComparator::OperatorLessOrEqual;}
       
  3169 | LT                        {$$ = AtomicComparator::OperatorLessThan;}
       
  3170 
       
  3171 NodeComp: RangeExpr NodeOperator RangeExpr                                          /* [62] */
       
  3172     {
       
  3173         $$ = create(new NodeComparison($1, $2, $3), @$, parseInfo);
       
  3174     }
       
  3175 
       
  3176 NodeOperator: IS    {$$ = QXmlNodeModelIndex::Is;}                                  /* [X] */
       
  3177 | PRECEDES          {$$ = QXmlNodeModelIndex::Precedes;}
       
  3178 | FOLLOWS           {$$ = QXmlNodeModelIndex::Follows;}
       
  3179 
       
  3180 ValidateExpr: ValidationMode EnclosedExpr                                           /* [63] */
       
  3181     {
       
  3182         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  3183         parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
       
  3184                                                           "Hence, %1-expressions may not be used.")
       
  3185                                            .arg(formatKeyword("validate")),
       
  3186                                         ReportContext::XQST0075, fromYYLTYPE(@$, parseInfo));
       
  3187         /*
       
  3188         $$ = Validate::create($2, $1, parseInfo->staticContext);
       
  3189         */
       
  3190     }
       
  3191 
       
  3192 /* "A validate expression may optionally specify a validation mode. The
       
  3193     default validation mode is strict." */
       
  3194 ValidationMode: VALIDATE    {$$ = Validate::Strict;}                                /* [64] */
       
  3195 | VALIDATE STRICT           {$$ = Validate::Strict;}
       
  3196 | VALIDATE LAX              {$$ = Validate::Lax;}
       
  3197 
       
  3198 ExtensionExpr: Pragmas EnclosedOptionalExpr                                         /* [65] */
       
  3199     {
       
  3200         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  3201         /* We don't support any pragmas, so we only do the
       
  3202          * necessary validation and use the fallback expression. */
       
  3203 
       
  3204         if($2)
       
  3205             $$ = $2;
       
  3206         else
       
  3207         {
       
  3208             parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
       
  3209                                                "Therefore, a fallback expression "
       
  3210                                                "must be present"),
       
  3211                                             ReportContext::XQST0079, fromYYLTYPE(@$, parseInfo));
       
  3212         }
       
  3213     }
       
  3214 
       
  3215 EnclosedOptionalExpr: CURLY_LBRACE /* empty */ CURLY_RBRACE                         /* [X] */
       
  3216     {
       
  3217         $$.reset();
       
  3218     }
       
  3219 | CURLY_LBRACE Expr CURLY_RBRACE
       
  3220     {
       
  3221         $$ = $2;
       
  3222     }
       
  3223 
       
  3224 Pragmas: Pragmas Pragma                                                             /* [X] */
       
  3225 | Pragma
       
  3226 
       
  3227 Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END                           /* [66] */
       
  3228     {
       
  3229         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  3230     }
       
  3231 
       
  3232 PragmaContents: /* empty */                                                         /* [67] */
       
  3233 | StringLiteral
       
  3234 
       
  3235 PathExpr: SLASH RelativePathExpr                                                    /* [68] */
       
  3236     {
       
  3237         /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
       
  3238         $$ = create(new Path(createRootExpression(parseInfo, @$), $2), @$, parseInfo);
       
  3239     }
       
  3240 
       
  3241 | SLASHSLASH RelativePathExpr
       
  3242     {
       
  3243         $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
       
  3244     }
       
  3245 | SLASH
       
  3246     {
       
  3247         /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
       
  3248         $$ = createRootExpression(parseInfo, @$);
       
  3249     }
       
  3250 
       
  3251 | RelativePathExpr
       
  3252     /* This is "step", simply. We let bison generate "$$ = $1". */
       
  3253 
       
  3254 RelativePathExpr: StepExpr                                                          /* [69] */
       
  3255 | RelativePathExpr MapOrSlash StepExpr
       
  3256     {
       
  3257         $$ = create(new Path($1, $3, $2), @$, parseInfo);
       
  3258     }
       
  3259 | RelativePathExpr MapOrSlash SORT MandatoryOrderByClause RETURN StepExpr END_SORT
       
  3260     {
       
  3261         const Expression::Ptr orderBy(createReturnOrderBy($4, $6, parseInfo->orderStability.pop(), @$, parseInfo));
       
  3262 
       
  3263         ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
       
  3264         const Expression::Ptr path(create(new Path($1, orderBy, $2), @$, parseInfo));
       
  3265 
       
  3266         $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), @$, parseInfo);
       
  3267     }
       
  3268 | RelativePathExpr SLASHSLASH StepExpr
       
  3269     {
       
  3270         $$ = createSlashSlashPath($1, $3, @$, parseInfo);
       
  3271     }
       
  3272 
       
  3273 StepExpr: FilteredAxisStep                                                          /* [70] */
       
  3274     {
       
  3275         $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
       
  3276     }
       
  3277 | FilterExpr
       
  3278 | CURRENT EnclosedExpr
       
  3279     {
       
  3280         $$ = create(new CurrentItemStore($2), @$, parseInfo);
       
  3281     }
       
  3282 | XSLT_VERSION
       
  3283     {
       
  3284         const xsDouble version = $1.toDouble();
       
  3285 
       
  3286         parseInfo->isBackwardsCompat.push(version != 2);
       
  3287 
       
  3288         $<enums.Double>$ = version;
       
  3289     }
       
  3290     EnclosedExpr
       
  3291     {
       
  3292         if($<enums.Double>2 < 2)
       
  3293             $$ = createCompatStore($3, @$, parseInfo);
       
  3294         else
       
  3295             $$ = $3;
       
  3296     }
       
  3297 | BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE                              /* [X] */
       
  3298 {
       
  3299     allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
       
  3300     Q_ASSERT(!$2.isEmpty());
       
  3301     $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
       
  3302 }
       
  3303 
       
  3304 | DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE                         /* [X] */
       
  3305     {
       
  3306         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$);
       
  3307         parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
       
  3308         const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
       
  3309         resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5),
       
  3310                                       StandardLocalNames::empty,
       
  3311                                       parseInfo->staticContext->namePool()->allocatePrefix($3)));
       
  3312         parseInfo->staticContext->setNamespaceBindings(resolver);
       
  3313     }
       
  3314     Expr
       
  3315     CURLY_RBRACE
       
  3316     {
       
  3317         parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
       
  3318         $$ = $8;
       
  3319     }
       
  3320 | CALL_TEMPLATE ElementName LPAREN TemplateWithParameters RPAREN
       
  3321     {
       
  3322         $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
       
  3323         parseInfo->templateWithParametersHandled();
       
  3324         parseInfo->templateCalls.append($$);
       
  3325     }
       
  3326 
       
  3327 TemplateWithParameters:
       
  3328     {
       
  3329         parseInfo->startParsingWithParam();
       
  3330     }
       
  3331     TemplateParameters
       
  3332     {
       
  3333         parseInfo->endParsingWithParam();
       
  3334     }
       
  3335 
       
  3336 TemplateParameters: /* Empty. */                                                    /* [X] */
       
  3337     {
       
  3338     }
       
  3339 | TemplateParameter
       
  3340     {
       
  3341     }
       
  3342 | TemplateParameters COMMA TemplateParameter
       
  3343     {
       
  3344     }
       
  3345 
       
  3346 OptionalTemplateParameters: /* Empty. */                                            /* [X] */
       
  3347     {
       
  3348     }
       
  3349 | LPAREN TemplateParameters RPAREN
       
  3350     {
       
  3351     }
       
  3352 
       
  3353 TemplateParameter: IsTunnel DOLLAR VarName TypeDeclaration OptionalAssign
       
  3354     {
       
  3355         /* Note, this grammar rule is invoked for @c xsl:param @em and @c
       
  3356          * xsl:with-param. */
       
  3357         const bool isParsingWithParam = parseInfo->isParsingWithParam();
       
  3358 
       
  3359         /**
       
  3360          * @c xsl:param doesn't make life easy:
       
  3361          *
       
  3362          * If it only has @c name, it's default value is an empty
       
  3363          * string(hence has type @c xs:string), but the value that
       
  3364          * (maybe) is supplied can be anything, typically a node.
       
  3365          *
       
  3366          * Therefore, for that very common case we can't rely on
       
  3367          * the Expression's type, but have to force it to item()*.
       
  3368          *
       
  3369          * So if we're supplied the type item()*, we pass a null
       
  3370          * SequenceType. TemplateParameterReference recognizes this
       
  3371          * and has item()* as its static type, regardless of if the
       
  3372          * expression has a more specific type.
       
  3373          */
       
  3374         SequenceType::Ptr type;
       
  3375 
       
  3376         if(!$4->is(CommonSequenceTypes::ZeroOrMoreItems))
       
  3377             type = $4;
       
  3378 
       
  3379         Expression::Ptr expr;
       
  3380 
       
  3381         /* The default value is an empty sequence. */
       
  3382         if(!$5 && ((type && $4->cardinality().allowsEmpty())
       
  3383                    || isParsingWithParam))
       
  3384             expr = create(new EmptySequence, @$, parseInfo);
       
  3385         else
       
  3386             expr = $5;
       
  3387 
       
  3388         /* We ensure we have some type, so CallTemplate, Template and friends
       
  3389          * are happy. */
       
  3390         if(!isParsingWithParam && !type)
       
  3391             type = CommonSequenceTypes::ZeroOrMoreItems;
       
  3392 
       
  3393         if($1)
       
  3394             /* TODO, handle tunnel parameters. */;
       
  3395         else
       
  3396         {
       
  3397             if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, $3)) ||
       
  3398                (isParsingWithParam && parseInfo->templateWithParams.contains($3)))
       
  3399             {
       
  3400                 parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
       
  3401                                                                  .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
       
  3402                                                 isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE(@$, parseInfo));
       
  3403             }
       
  3404             else
       
  3405             {
       
  3406                 if(isParsingWithParam)
       
  3407                     parseInfo->templateWithParams[$3] = WithParam::Ptr(new WithParam($3, $4, expr));
       
  3408                 else
       
  3409                 {
       
  3410                     Q_ASSERT(type);
       
  3411                     pushVariable($3, type, expr, VariableDeclaration::TemplateParameter, @$, parseInfo);
       
  3412                     parseInfo->templateParameters.append(parseInfo->variables.top());
       
  3413                 }
       
  3414             }
       
  3415         }
       
  3416     }
       
  3417 
       
  3418 IsTunnel: /* Empty. */
       
  3419     {
       
  3420         $$ = false;
       
  3421     }
       
  3422 | TUNNEL
       
  3423     {
       
  3424         $$ = true;
       
  3425     }
       
  3426 
       
  3427 OptionalAssign: /* Empty. */                                                        /* [X] */
       
  3428     {
       
  3429         $$ = Expression::Ptr();
       
  3430     }
       
  3431 | ASSIGN ExprSingle
       
  3432     {
       
  3433         $$ = $2;
       
  3434     }
       
  3435 
       
  3436 /**
       
  3437  * Controls whethers a path expression should sort its result. Used for
       
  3438  * implementing XSL-T's for-each.
       
  3439  */
       
  3440 MapOrSlash: SLASH                                                                   /* [X] */
       
  3441     {
       
  3442         $$ = Path::RegularPath;
       
  3443     }
       
  3444 | MAP
       
  3445     {
       
  3446         $$ = Path::XSLTForEach;
       
  3447     }
       
  3448 | FOR_APPLY_TEMPLATE
       
  3449     {
       
  3450         $$ = Path::ForApplyTemplate;
       
  3451     }
       
  3452 
       
  3453 FilteredAxisStep: AxisStep                                                          /* [X] */
       
  3454 | FilteredAxisStep LBRACKET Expr RBRACKET
       
  3455     {
       
  3456         $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@$, parseInfo)), @$, parseInfo);
       
  3457     }
       
  3458 
       
  3459 AxisStep: ForwardStep                                                               /* [71] */
       
  3460 | ReverseStep
       
  3461 
       
  3462 ForwardStep: Axis
       
  3463              {
       
  3464                 if($1 == QXmlNodeModelIndex::AxisAttribute)
       
  3465                     parseInfo->nodeTestSource = BuiltinTypes::attribute;
       
  3466              }
       
  3467              NodeTestInAxisStep                                                     /* [72] */
       
  3468     {
       
  3469         if($3)
       
  3470         {
       
  3471             /* A node test was explicitly specified. The un-abbreviated syntax was used. */
       
  3472             $$ = create(new AxisStep($1, $3), @$, parseInfo);
       
  3473         }
       
  3474         else
       
  3475         {
       
  3476             /* Quote from 3.2.1.1 Axes
       
  3477              *
       
  3478              * [Definition: Every axis has a principal node kind. If an axis
       
  3479              *  can contain elements, then the principal node kind is element;
       
  3480              *  otherwise, it is the kind of nodes that the axis can contain.] Thus:
       
  3481              * - For the attribute axis, the principal node kind is attribute.
       
  3482              * - For all other axes, the principal node kind is element. */
       
  3483 
       
  3484             if($1 == QXmlNodeModelIndex::AxisAttribute)
       
  3485                 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), @$, parseInfo);
       
  3486             else
       
  3487                 $$ = create(new AxisStep($1, BuiltinTypes::element), @$, parseInfo);
       
  3488         }
       
  3489 
       
  3490         parseInfo->restoreNodeTestSource();
       
  3491     }
       
  3492 | AbbrevForwardStep
       
  3493 
       
  3494 NodeTestInAxisStep: NodeTest
       
  3495 | AnyAttributeTest
       
  3496 
       
  3497 Axis: AxisToken COLONCOLON                                                          /* [73] */
       
  3498     {
       
  3499         if($1 == QXmlNodeModelIndex::AxisNamespace)
       
  3500         {
       
  3501             /* We don't raise XPST0010 here because the namespace axis isn't an optional
       
  3502              * axis. It simply is not part of the XQuery grammar. */
       
  3503             parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
       
  3504                                                .arg(formatKeyword("namespace")),
       
  3505                                             ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  3506         }
       
  3507         else
       
  3508             $$ = $1;
       
  3509 
       
  3510         switch($1)
       
  3511         {
       
  3512             case QXmlNodeModelIndex::AxisAttribute:
       
  3513             {
       
  3514                 allowedIn(QueryLanguages(  QXmlQuery::XPath20
       
  3515                                          | QXmlQuery::XQuery10
       
  3516                                          | QXmlQuery::XmlSchema11IdentityConstraintField
       
  3517                                          | QXmlQuery::XSLT20),
       
  3518                           parseInfo, @$);
       
  3519                 break;
       
  3520             }
       
  3521             case QXmlNodeModelIndex::AxisChild:
       
  3522             {
       
  3523                 allowedIn(QueryLanguages(  QXmlQuery::XPath20
       
  3524                                          | QXmlQuery::XQuery10
       
  3525                                          | QXmlQuery::XmlSchema11IdentityConstraintField
       
  3526                                          | QXmlQuery::XmlSchema11IdentityConstraintSelector
       
  3527                                          | QXmlQuery::XSLT20),
       
  3528                           parseInfo, @$);
       
  3529                 break;
       
  3530             }
       
  3531             default:
       
  3532             {
       
  3533                 allowedIn(QueryLanguages(  QXmlQuery::XPath20
       
  3534                                          | QXmlQuery::XQuery10
       
  3535                                          | QXmlQuery::XSLT20),
       
  3536                           parseInfo, @$);
       
  3537             }
       
  3538         }
       
  3539     }
       
  3540 
       
  3541 AxisToken: ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf  ;}
       
  3542 | ANCESTOR                  {$$ = QXmlNodeModelIndex::AxisAncestor        ;}
       
  3543 | ATTRIBUTE                 {$$ = QXmlNodeModelIndex::AxisAttribute       ;}
       
  3544 | CHILD                     {$$ = QXmlNodeModelIndex::AxisChild           ;}
       
  3545 | DESCENDANT_OR_SELF        {$$ = QXmlNodeModelIndex::AxisDescendantOrSelf;}
       
  3546 | DESCENDANT                {$$ = QXmlNodeModelIndex::AxisDescendant      ;}
       
  3547 | FOLLOWING                 {$$ = QXmlNodeModelIndex::AxisFollowing       ;}
       
  3548 | PRECEDING                 {$$ = QXmlNodeModelIndex::AxisPreceding       ;}
       
  3549 | FOLLOWING_SIBLING         {$$ = QXmlNodeModelIndex::AxisFollowingSibling;}
       
  3550 | PRECEDING_SIBLING         {$$ = QXmlNodeModelIndex::AxisPrecedingSibling;}
       
  3551 | PARENT                    {$$ = QXmlNodeModelIndex::AxisParent          ;}
       
  3552 | SELF                      {$$ = QXmlNodeModelIndex::AxisSelf            ;}
       
  3553 
       
  3554 AbbrevForwardStep: AT_SIGN
       
  3555                    {
       
  3556                         parseInfo->nodeTestSource = BuiltinTypes::attribute;
       
  3557                    }
       
  3558                    NodeTest                                                         /* [72] */
       
  3559     {
       
  3560         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$);
       
  3561         $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo);
       
  3562 
       
  3563         parseInfo->restoreNodeTestSource();
       
  3564     }
       
  3565 | NodeTest
       
  3566     {
       
  3567         ItemType::Ptr nodeTest;
       
  3568 
       
  3569         if(parseInfo->isParsingPattern && *$1 == *BuiltinTypes::node)
       
  3570             nodeTest = BuiltinTypes::xsltNodeTest;
       
  3571         else
       
  3572             nodeTest = $1;
       
  3573 
       
  3574         $$ = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), @$, parseInfo);
       
  3575     }
       
  3576 | AnyAttributeTest
       
  3577     {
       
  3578         $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $1), @$, parseInfo);
       
  3579     }
       
  3580 
       
  3581 ReverseStep: AbbrevReverseStep                                                      /* [75] */
       
  3582 
       
  3583 AbbrevReverseStep: DOTDOT                                                           /* [77] */
       
  3584     {
       
  3585         $$ = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo);
       
  3586     }
       
  3587 
       
  3588 NodeTest: NameTest                                                                  /* [78] */
       
  3589 | KindTest
       
  3590     {
       
  3591         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3592     }
       
  3593 
       
  3594 NameTest: ElementName                                                               /* [79] */
       
  3595     {
       
  3596         $$ = QNameTest::create(parseInfo->nodeTestSource, $1);
       
  3597     }
       
  3598 | WildCard
       
  3599 
       
  3600 WildCard: STAR                                                                      /* [80] */
       
  3601     {
       
  3602         $$ = parseInfo->nodeTestSource;
       
  3603     }
       
  3604 | ANY_LOCAL_NAME
       
  3605     {
       
  3606         const NamePool::Ptr np(parseInfo->staticContext->namePool());
       
  3607         const ReflectYYLTYPE ryy(@$, parseInfo);
       
  3608 
       
  3609         const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix($1), parseInfo->staticContext, &ryy));
       
  3610 
       
  3611         $$ = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
       
  3612     }
       
  3613 | ANY_PREFIX
       
  3614     {
       
  3615         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3616         const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
       
  3617         $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
       
  3618     }
       
  3619 
       
  3620 FilterExpr: PrimaryExpr                                                             /* [81] */
       
  3621 | FilterExpr LBRACKET Expr RBRACKET
       
  3622     {
       
  3623         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3624         $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo);
       
  3625     }
       
  3626 
       
  3627 PrimaryExpr: Literal                                                                /* [84] */
       
  3628 | VarRef
       
  3629 | ParenthesizedExpr
       
  3630 | ContextItemExpr
       
  3631 | FunctionCallExpr
       
  3632 | OrderingExpr
       
  3633 | Constructor
       
  3634 | APPLY_TEMPLATE OptionalMode LPAREN TemplateWithParameters RPAREN
       
  3635     {
       
  3636         $$ = create(new ApplyTemplate(parseInfo->modeFor($2),
       
  3637                                       parseInfo->templateWithParams,
       
  3638                                       parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
       
  3639                                                                   StandardLocalNames::Default))),
       
  3640                     @1, parseInfo);
       
  3641         parseInfo->templateWithParametersHandled();
       
  3642     }
       
  3643 
       
  3644 Literal: NumericLiteral                                                             /* [85] */
       
  3645 | StringLiteral
       
  3646     {
       
  3647         $$ = create(new Literal(AtomicString::fromValue($1)), @$, parseInfo);
       
  3648     }
       
  3649 
       
  3650 NumericLiteral: XPATH2_NUMBER                                                       /* [86] */
       
  3651     {
       
  3652         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3653         $$ = createNumericLiteral<Double>($1, @$, parseInfo);
       
  3654     }
       
  3655 | NUMBER
       
  3656     {
       
  3657         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3658         $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
       
  3659     }
       
  3660 
       
  3661 VarRef: DOLLAR VarName                                                              /* [87] */
       
  3662     {
       
  3663         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3664         $$ = resolveVariable($2, @$, parseInfo, false);
       
  3665     }
       
  3666 
       
  3667 VarName: NCNAME                                                                     /* [88] */
       
  3668     {
       
  3669         /* See: http://www.w3.org/TR/xpath20/#id-variables */
       
  3670         $$ = parseInfo->staticContext->namePool()->allocateQName(QString(), $1);
       
  3671     }
       
  3672 | QName
       
  3673     {
       
  3674         $$ = $1;
       
  3675     }
       
  3676 
       
  3677 ParenthesizedExpr: LPAREN Expr RPAREN                                               /* [89] */
       
  3678     {
       
  3679         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3680         $$ = $2;
       
  3681     }
       
  3682 | LPAREN RPAREN
       
  3683     {
       
  3684         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3685         $$ = create(new EmptySequence, @$, parseInfo);
       
  3686     }
       
  3687 
       
  3688 ContextItemExpr: DOT                                                                /* [90] */
       
  3689     {
       
  3690         $$ = create(new ContextItem(), @$, parseInfo);
       
  3691     }
       
  3692 
       
  3693 OrderingExpr: OrderingMode EnclosedExpr                                             /* [X] */
       
  3694     {
       
  3695         $$ = $2;
       
  3696     }
       
  3697 
       
  3698 FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN                      /* [93] */
       
  3699     {
       
  3700         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  3701         if(XPathHelper::isReservedNamespace($1.namespaceURI()) || $1.namespaceURI() == StandardNamespaces::InternalXSLT)
       
  3702         { /* We got a call to a builtin function. */
       
  3703             const ReflectYYLTYPE ryy(@$, parseInfo);
       
  3704 
       
  3705             const Expression::Ptr
       
  3706                 func(parseInfo->staticContext->
       
  3707                 functionSignatures()->createFunctionCall($1, $3, parseInfo->staticContext, &ryy));
       
  3708 
       
  3709             if(func)
       
  3710                 $$ = create(func, @$, parseInfo);
       
  3711             else
       
  3712             {
       
  3713                 parseInfo->staticContext->error(QtXmlPatterns::tr("No function by name %1 is available.")
       
  3714                                                    .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)),
       
  3715                                                 ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
       
  3716             }
       
  3717         }
       
  3718         else /* It's a call to a function created with 'declare function'.*/
       
  3719         {
       
  3720             $$ = create(new UserFunctionCallsite($1, $3.count()), @$, parseInfo);
       
  3721 
       
  3722             $$->setOperands($3);
       
  3723             parseInfo->userFunctionCallsites.append($$);
       
  3724         }
       
  3725     }
       
  3726 
       
  3727 FunctionArguments: /* empty */                                                      /* [X] */
       
  3728     {
       
  3729         $$ = Expression::List();
       
  3730     }
       
  3731 
       
  3732 | ExprSingle
       
  3733     {
       
  3734         Expression::List list;
       
  3735         list.append($1);
       
  3736         $$ = list;
       
  3737     }
       
  3738 
       
  3739 | ExpressionSequence
       
  3740 
       
  3741 Constructor: DirectConstructor                                                      /* [94] */
       
  3742     {
       
  3743         allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
       
  3744     }
       
  3745 | ComputedConstructor
       
  3746 /* The reason we cannot call alloweIn() as the action for ComputedConstructor,
       
  3747  * is that we use the computed constructors for XSL-T, and therefore generate
       
  3748  * INTERNAL tokens. */
       
  3749 
       
  3750 DirectConstructor: DirElemConstructor                                               /* [95] */
       
  3751 | DirCommentConstructor
       
  3752 | DirPIConstructor
       
  3753 
       
  3754 /*
       
  3755  * Direct attribute constructors can contain embedded expressions, and for those namespace bindings
       
  3756  * on the same element needs to be in scope. For example:
       
  3757  *
       
  3758  * @code
       
  3759  * <element attribute="{prefix:nameTest}" xmlns:prefix="http://example.com/"/>
       
  3760  * @endcode
       
  3761  *
       
  3762  * Patternist is designed to do all name resolution at parse time so the subsequent code only has to
       
  3763  * deal with expanded QNames(which the QName class represents), and this presents a problem since
       
  3764  * the parser haven't even encountered the @c xmlns:prefix when resolving @c prefix in the name test.
       
  3765  *
       
  3766  * This is solved as follows:
       
  3767  *
       
  3768  * <ol>
       
  3769  *  <li>Just before starting parsing the attributes, we call Tokenizer::commenceScanOnly().
       
  3770  *      This switches the tokenizer to not tokenize embedded expressions in attributes,
       
  3771  *      but to return them as strings, token type STRING_LITERAL.</li>
       
  3772  *  <li>We parse all the attributes, and iterates over them, only caring about
       
  3773  *      namespace bindings, and validates and adds them to the context.</li>
       
  3774  *  <li>We call Tokenizer::resumeTokenizationFrom() from the previous position
       
  3775  *      returned from Tokenizer::commenceScanOnly() and parses the attributes once more,
       
  3776  *      but this time with tokenization of embedded expressions. Since we this time
       
  3777  *      have the namespace bindings in place, everything resolves.</li>
       
  3778  * </ol>
       
  3779  *
       
  3780  * Saxon does this in a similar way. Study net.sf.saxon.expr.QueryParser::parseDirectElementConstructor().
       
  3781  *
       
  3782  * @see XQueryTokenizer::attributeAsRaw()
       
  3783  */
       
  3784 DirElemConstructor: G_LT
       
  3785                     LexicalName
       
  3786                     {
       
  3787                         $<enums.tokenizerPosition>$ = parseInfo->tokenizer->commenceScanOnly();
       
  3788                         parseInfo->scanOnlyStack.push(true);
       
  3789                     }
       
  3790 
       
  3791                     /* This list contains name/string pairs. No embedded
       
  3792                      * expressions has been parsed. */
       
  3793                     DirAttributeList
       
  3794 
       
  3795                     {
       
  3796                         ++parseInfo->elementConstructorDepth;
       
  3797                         Expression::List constructors;
       
  3798 
       
  3799                         parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
       
  3800 
       
  3801                         /* Fix up attributes and namespace declarations. */
       
  3802                         const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
       
  3803                         const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
       
  3804                         const int len = $4.size();
       
  3805                         QSet<QXmlName::PrefixCode> usedDeclarations;
       
  3806 
       
  3807                         /* Whether xmlns="" has been encountered. */
       
  3808                         bool hasDefaultDeclaration = false;
       
  3809 
       
  3810                         /* For each attribute & namespace declaration, do: */
       
  3811                         for(int i = 0; i < len; ++i)
       
  3812                         {
       
  3813                             QString strLocalName;
       
  3814                             QString strPrefix;
       
  3815 
       
  3816                             XPathHelper::splitQName($4.at(i).first, strPrefix, strLocalName);
       
  3817                             const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
       
  3818 
       
  3819                             /* This can seem a bit weird. However, this name is ending up in a QXmlName
       
  3820                              * which consider its prefix a... prefix. So, a namespace binding name can in some cases
       
  3821                              * be a local name, but that's just as the initial syntactical construct. */
       
  3822                             const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);
       
  3823 
       
  3824                             /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
       
  3825 
       
  3826                             if(prefix == StandardPrefixes::xmlns ||
       
  3827                                (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
       
  3828                             {
       
  3829                                 if(localName == StandardPrefixes::xmlns)
       
  3830                                     hasDefaultDeclaration = true;
       
  3831 
       
  3832                                 /* We have a namespace declaration. */
       
  3833 
       
  3834                                 const Expression::Ptr nsExpr($4.at(i).second);
       
  3835 
       
  3836                                 const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
       
  3837 
       
  3838                                 const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
       
  3839 
       
  3840                                 if(ns == StandardNamespaces::empty)
       
  3841                                 {
       
  3842                                     if(localName != StandardPrefixes::xmlns)
       
  3843                                     {
       
  3844                                         parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
       
  3845                                                                            .arg(formatURI(strPrefix)),
       
  3846                                                                         ReportContext::XQST0085, fromYYLTYPE(@$, parseInfo));
       
  3847                                     }
       
  3848                                 }
       
  3849                                 else if(!AnyURI::isValid(strNamespace))
       
  3850                                 {
       
  3851                                     parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
       
  3852                                                                     ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
       
  3853                                 }
       
  3854 
       
  3855                                 if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
       
  3856                                 {
       
  3857                                     parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
       
  3858                                                                        .arg(formatKeyword("xmlns")),
       
  3859                                                                     ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
       
  3860                                 }
       
  3861 
       
  3862                                 if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
       
  3863                                 {
       
  3864                                     parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
       
  3865                                                                        .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
       
  3866                                                                        .arg(formatKeyword("xml")),
       
  3867                                                                     ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
       
  3868                                 }
       
  3869 
       
  3870                                 if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
       
  3871                                 {
       
  3872                                     parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
       
  3873                                                                        .arg(formatKeyword("xml"))
       
  3874                                                                        .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
       
  3875                                                                     ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
       
  3876                                 }
       
  3877 
       
  3878                                 QXmlName nb;
       
  3879 
       
  3880                                 if(localName == StandardPrefixes::xmlns)
       
  3881                                     nb = QXmlName(ns, StandardLocalNames::empty);
       
  3882                                 else
       
  3883                                     nb = QXmlName(ns, StandardLocalNames::empty, localName);
       
  3884 
       
  3885                                 if(usedDeclarations.contains(nb.prefix()))
       
  3886                                 {
       
  3887                                     parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
       
  3888                                                                        .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
       
  3889                                                                     ReportContext::XQST0071, fromYYLTYPE(@$, parseInfo));
       
  3890 
       
  3891                                 }
       
  3892                                 else
       
  3893                                     usedDeclarations.insert(nb.prefix());
       
  3894 
       
  3895                                 /* If the user has bound the XML namespace correctly, we in either
       
  3896                                  * case don't want to output it.
       
  3897                                  *
       
  3898                                  * We only have to check the namespace parts since the above checks has ensured
       
  3899                                  * consistency in the prefix parts. */
       
  3900                                 if(ns != StandardNamespaces::xml)
       
  3901                                 {
       
  3902                                     /* We don't want default namespace declarations when the
       
  3903                                      * default namespace already is empty. */
       
  3904                                     if(!(ns == StandardNamespaces::empty          &&
       
  3905                                          localName == StandardNamespaces::xmlns   &&
       
  3906                                          resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
       
  3907                                     {
       
  3908                                         constructors.append(create(new NamespaceConstructor(nb), @$, parseInfo));
       
  3909                                         resolver->addBinding(nb);
       
  3910                                     }
       
  3911                                 }
       
  3912                             }
       
  3913                         }
       
  3914 
       
  3915                         if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
       
  3916                         {
       
  3917                             /* TODO But mostly this isn't needed, since the default element
       
  3918                              * namespace is empty? How does this at all work? */
       
  3919                             const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
       
  3920                             constructors.append(create(new NamespaceConstructor(def), @$, parseInfo));
       
  3921                         }
       
  3922 
       
  3923                         parseInfo->staticContext->setNamespaceBindings(resolver);
       
  3924                         $<expressionList>$ = constructors;
       
  3925 
       
  3926                         /* Resolve the name of the element, now that the namespace attributes are read. */
       
  3927                         {
       
  3928                             const ReflectYYLTYPE ryy(@$, parseInfo);
       
  3929 
       
  3930                             const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
       
  3931                                                                                ReportContext::XPST0081,
       
  3932                                                                                ReportContext::XPST0081>($2, parseInfo->staticContext, resolver, &ryy);
       
  3933                             parseInfo->tagStack.push(ele);
       
  3934                         }
       
  3935 
       
  3936                         parseInfo->tokenizer->resumeTokenizationFrom($<enums.tokenizerPosition>3);
       
  3937                     }
       
  3938                     POSITION_SET
       
  3939                     DirAttributeList
       
  3940                     DirElemConstructorTail                         /* [96] */
       
  3941     {
       
  3942         /* We add the content constructor after the attribute constructors. This might result
       
  3943          * in nested ExpressionSequences, but it will be optimized away later on. */
       
  3944 
       
  3945         Expression::List attributes($<expressionList>5);
       
  3946         const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
       
  3947         const int len = $7.size();
       
  3948         QSet<QXmlName> declaredAttributes;
       
  3949         declaredAttributes.reserve(len);
       
  3950 
       
  3951         /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
       
  3952          * turn it into an attribute constructor. */
       
  3953         for(int i = 0; i < len; ++i)
       
  3954         {
       
  3955             QString strLocalName;
       
  3956             QString strPrefix;
       
  3957 
       
  3958             XPathHelper::splitQName($7.at(i).first, strPrefix, strLocalName);
       
  3959             const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
       
  3960             const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);
       
  3961 
       
  3962             if(prefix == StandardPrefixes::xmlns ||
       
  3963                (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
       
  3964             {
       
  3965                 const Expression::ID id = $7.at(i).second->id();
       
  3966 
       
  3967                 if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
       
  3968                 {
       
  3969                     /* It's a namespace declaration, and we've already handled those above. */
       
  3970                     continue;
       
  3971                 }
       
  3972                 else
       
  3973                 {
       
  3974                     parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
       
  3975                                                        "use enclosed expressions."),
       
  3976                                                     ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
       
  3977                 }
       
  3978 
       
  3979             }
       
  3980             else
       
  3981             {
       
  3982                 const ReflectYYLTYPE ryy(@$, parseInfo);
       
  3983                 const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
       
  3984                                                                    ReportContext::XPST0081,
       
  3985                                                                    ReportContext::XPST0081>($7.at(i).first, parseInfo->staticContext,
       
  3986                                                                                             parseInfo->staticContext->namespaceBindings(),
       
  3987                                                                                             &ryy, true);
       
  3988                 if(declaredAttributes.contains(att))
       
  3989                 {
       
  3990                     parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute by name %1 has already appeared on this element.")
       
  3991                                                       .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
       
  3992                                             ReportContext::XQST0040, fromYYLTYPE(@$, parseInfo));
       
  3993 
       
  3994                 }
       
  3995                 else
       
  3996                     declaredAttributes.insert(att);
       
  3997 
       
  3998                 /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
       
  3999                  * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
       
  4000                  * it twice.
       
  4001                  *
       
  4002                  * The AttributeConstructor's arguments are just dummies. */
       
  4003                 const Expression::Ptr ctor(create(new AttributeConstructor($7.at(i).second, $7.at(i).second), @$, parseInfo));
       
  4004 
       
  4005                 Expression::List ops;
       
  4006                 ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
       
  4007                 ops.append($7.at(i).second);
       
  4008                 ctor->setOperands(ops);
       
  4009 
       
  4010                 attributes.append(ctor);
       
  4011             }
       
  4012         }
       
  4013 
       
  4014         Expression::Ptr contentOp;
       
  4015 
       
  4016         if(attributes.isEmpty())
       
  4017             contentOp = $8;
       
  4018         else
       
  4019         {
       
  4020             attributes.append($8);
       
  4021             contentOp = create(new ExpressionSequence(attributes), @$, parseInfo);
       
  4022         }
       
  4023 
       
  4024         const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), @$, parseInfo));
       
  4025         $$ = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), @$, parseInfo);
       
  4026 
       
  4027         /* Restore the old context. We don't want the namespaces
       
  4028          * to be in-scope for expressions appearing after the
       
  4029          * element they appeared on. */
       
  4030         parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
       
  4031         parseInfo->tagStack.pop();
       
  4032 
       
  4033         --parseInfo->elementConstructorDepth;
       
  4034     }
       
  4035 
       
  4036 DirElemConstructorTail: QUICK_TAG_END
       
  4037     {
       
  4038         $$ = create(new EmptySequence(), @$, parseInfo);
       
  4039     }
       
  4040 | G_GT DirElemContent BEGIN_END_TAG ElementName G_GT
       
  4041     {
       
  4042         if(!$4.isLexicallyEqual(parseInfo->tagStack.top()))
       
  4043         {
       
  4044             parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
       
  4045                                                "well-formed. %1 is ended with %2.")
       
  4046                                                .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
       
  4047                                                     formatKeyword(parseInfo->staticContext->namePool()->toLexical($4))),
       
  4048                                             ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
       
  4049         }
       
  4050 
       
  4051         if($2.isEmpty())
       
  4052             $$ = create(new EmptySequence(), @$, parseInfo);
       
  4053         else if($2.size() == 1)
       
  4054             $$ = $2.first();
       
  4055         else
       
  4056             $$ = create(new ExpressionSequence($2), @$, parseInfo);
       
  4057     }
       
  4058 
       
  4059 DirAttributeList: /* empty */                                                       /* [97] */
       
  4060     {
       
  4061         $$ = AttributeHolderVector();
       
  4062     }
       
  4063 | DirAttributeList Attribute
       
  4064     {
       
  4065         $1.append($2);
       
  4066         $$ = $1;
       
  4067     }
       
  4068 
       
  4069 Attribute: LexicalName G_EQ DirAttributeValue                                       /* [X] */
       
  4070     {
       
  4071         $$ = qMakePair($1, $3);
       
  4072     }
       
  4073 
       
  4074 DirAttributeValue: QUOTE AttrValueContent QUOTE                                     /* [98] */
       
  4075     {
       
  4076         $$ = createDirAttributeValue($2, parseInfo, @$);
       
  4077     }
       
  4078 
       
  4079 | APOS AttrValueContent APOS
       
  4080     {
       
  4081         $$ = createDirAttributeValue($2, parseInfo, @$);
       
  4082     }
       
  4083 
       
  4084 AttrValueContent: /* Empty. */                                                      /* [X] */
       
  4085     {
       
  4086         $$ = Expression::List();
       
  4087     }
       
  4088 | EnclosedExpr AttrValueContent
       
  4089     {
       
  4090         Expression::Ptr content($1);
       
  4091 
       
  4092         if(parseInfo->isBackwardsCompat.top())
       
  4093             content = create(GenericPredicate::createFirstItem(content), @$, parseInfo);
       
  4094 
       
  4095         $2.prepend(createSimpleContent(content, @$, parseInfo));
       
  4096         $$ = $2;
       
  4097     }
       
  4098 | StringLiteral AttrValueContent
       
  4099     {
       
  4100         $2.prepend(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo));
       
  4101         $$ = $2;
       
  4102     }
       
  4103 
       
  4104 DirElemContent: /* empty */                                                         /* [101] */
       
  4105     {
       
  4106         $$ = Expression::List();
       
  4107         parseInfo->isPreviousEnclosedExpr = false;
       
  4108     }
       
  4109 | DirElemContent DirectConstructor
       
  4110     {
       
  4111         $1.append($2);
       
  4112         $$ = $1;
       
  4113         parseInfo->isPreviousEnclosedExpr = false;
       
  4114     }
       
  4115 | DirElemContent StringLiteral
       
  4116     {
       
  4117         if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
       
  4118            XPathHelper::isWhitespaceOnly($2))
       
  4119         {
       
  4120             $$ = $1;
       
  4121         }
       
  4122         else
       
  4123         {
       
  4124             $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
       
  4125             $$ = $1;
       
  4126             parseInfo->isPreviousEnclosedExpr = false;
       
  4127         }
       
  4128     }
       
  4129 | DirElemContent NON_BOUNDARY_WS
       
  4130     {
       
  4131         $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
       
  4132         $$ = $1;
       
  4133         parseInfo->isPreviousEnclosedExpr = false;
       
  4134     }
       
  4135 | DirElemContent EnclosedExpr
       
  4136     {
       
  4137         /* We insert a text node constructor that send an empty text node between
       
  4138          * the two enclosed expressions, in order to ensure that no space is inserted.
       
  4139          *
       
  4140          * However, we only do it when we have no node constructors. */
       
  4141         if(parseInfo->isPreviousEnclosedExpr &&
       
  4142            BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($2->staticType()->itemType()) &&
       
  4143            BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($1.last()->staticType()->itemType()))
       
  4144             $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), @$, parseInfo)), @$, parseInfo));
       
  4145         else
       
  4146             parseInfo->isPreviousEnclosedExpr = true;
       
  4147 
       
  4148         $1.append(createCopyOf($2, parseInfo, @$));
       
  4149         $$ = $1;
       
  4150     }
       
  4151 
       
  4152 DirCommentConstructor: COMMENT_START COMMENT_CONTENT                                /* [103] */
       
  4153     {
       
  4154         $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
       
  4155     }
       
  4156 
       
  4157 DirPIConstructor: PI_START PI_TARGET PI_CONTENT                                     /* [105] */
       
  4158     {
       
  4159         const ReflectYYLTYPE ryy(@$, parseInfo);
       
  4160         NCNameConstructor::validateTargetName<StaticContext::Ptr,
       
  4161                                               ReportContext::XPST0003,
       
  4162                                               ReportContext::XPST0003>($2,
       
  4163                                                                        parseInfo->staticContext, &ryy);
       
  4164 
       
  4165         $$ = create(new ProcessingInstructionConstructor(
       
  4166                              create(new Literal(AtomicString::fromValue($2)), @$, parseInfo),
       
  4167                              create(new Literal(AtomicString::fromValue($3)), @$, parseInfo)), @$, parseInfo);
       
  4168     }
       
  4169 
       
  4170 ComputedConstructor: CompDocConstructor                                             /* [109] */
       
  4171 | CompElemConstructor
       
  4172 | CompAttrConstructor
       
  4173 | CompTextConstructor
       
  4174 | CompCommentConstructor
       
  4175 | CompPIConstructor
       
  4176 | CompNamespaceConstructor
       
  4177 
       
  4178 CompDocConstructor: DOCUMENT IsInternal EnclosedExpr                                /* [110] */
       
  4179     {
       
  4180         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  4181 
       
  4182         $$ = create(new DocumentConstructor($3), @$, parseInfo);
       
  4183     }
       
  4184 
       
  4185 CompElemConstructor: ELEMENT IsInternal CompElementName
       
  4186                      {
       
  4187                         /* This value is incremented before the action below is executed. */
       
  4188                         ++parseInfo->elementConstructorDepth;
       
  4189                      }
       
  4190                      EnclosedOptionalExpr                                           /* [111] */
       
  4191     {
       
  4192         Q_ASSERT(5);
       
  4193         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  4194 
       
  4195         Expression::Ptr effExpr;
       
  4196 
       
  4197         if($5)
       
  4198             effExpr = createCopyOf($5, parseInfo, @$);
       
  4199         else
       
  4200             effExpr = create(new EmptySequence(), @$, parseInfo);
       
  4201 
       
  4202         const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
       
  4203 
       
  4204         /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
       
  4205          * a child of another constructor, it has already been done. */
       
  4206         if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
       
  4207         {
       
  4208             Expression::List exprList;
       
  4209 
       
  4210             /* We append the namespace constructor before the body, in order to
       
  4211              * comply with QAbstractXmlPushHandler's contract. */
       
  4212             const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
       
  4213             exprList.append(create(new NamespaceConstructor(def), @$, parseInfo));
       
  4214 
       
  4215             exprList.append(effExpr);
       
  4216 
       
  4217             effExpr = create(new ExpressionSequence(exprList), @$, parseInfo);
       
  4218         }
       
  4219 
       
  4220         --parseInfo->elementConstructorDepth;
       
  4221         $$ = create(new ElementConstructor($3, effExpr, parseInfo->isXSLT()), @$, parseInfo);
       
  4222     }
       
  4223 
       
  4224 IsInternal: /* Empty. */                                                          /* [X] */
       
  4225     {
       
  4226         $$ = false;
       
  4227     }
       
  4228 | INTERNAL
       
  4229     {
       
  4230         $$ = true;
       
  4231     }
       
  4232 
       
  4233 CompAttrConstructor: ATTRIBUTE
       
  4234                      IsInternal
       
  4235                      CompAttributeName
       
  4236                      EnclosedOptionalExpr                                           /* [113] */
       
  4237     {
       
  4238         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  4239 
       
  4240         const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo));
       
  4241 
       
  4242         if($4)
       
  4243             $$ = create(new AttributeConstructor(name, createSimpleContent($4, @$, parseInfo)), @$, parseInfo);
       
  4244         else
       
  4245             $$ = create(new AttributeConstructor(name, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
       
  4246     }
       
  4247 
       
  4248 CompTextConstructor: TEXT IsInternal EnclosedExpr                                 /* [114] */
       
  4249     {
       
  4250         $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
       
  4251     }
       
  4252 
       
  4253 CompCommentConstructor: COMMENT IsInternal EnclosedExpr                           /* [115] */
       
  4254     {
       
  4255         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  4256 
       
  4257         $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
       
  4258     }
       
  4259 
       
  4260 CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr           /* [116] */
       
  4261     {
       
  4262         allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
       
  4263 
       
  4264         if($3)
       
  4265         {
       
  4266             $$ = create(new ProcessingInstructionConstructor($2, createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
       
  4267         }
       
  4268         else
       
  4269             $$ = create(new ProcessingInstructionConstructor($2, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
       
  4270     }
       
  4271 
       
  4272 CompAttributeName: {
       
  4273                         parseInfo->nodeTestSource = BuiltinTypes::attribute;
       
  4274                    }
       
  4275                    ElementName
       
  4276                    {
       
  4277                         parseInfo->restoreNodeTestSource();
       
  4278                    }                                                                /* [X] */
       
  4279     {
       
  4280         $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $2))), @$, parseInfo);
       
  4281     }
       
  4282 | CompNameExpr
       
  4283 
       
  4284 CompElementName: ElementName                                                        /* [X] */
       
  4285     {
       
  4286         $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $1))), @$, parseInfo);
       
  4287     }
       
  4288 | CompNameExpr
       
  4289 
       
  4290 CompNameExpr: EnclosedExpr
       
  4291     {
       
  4292         if(BuiltinTypes::xsQName->xdtTypeMatches($1->staticType()->itemType()))
       
  4293             $$ = $1;
       
  4294         else
       
  4295         {
       
  4296             $$ = create(new QNameConstructor($1,
       
  4297                                              parseInfo->staticContext->namespaceBindings()),
       
  4298                         @$, parseInfo);
       
  4299         }
       
  4300     }
       
  4301 
       
  4302 /*
       
  4303  * We always create an NCNameConstructor here. If will be rewritten away if not needed.
       
  4304  */
       
  4305 CompPIName: NCNAME
       
  4306     {
       
  4307         $$ = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo)), @$, parseInfo);
       
  4308     }
       
  4309 | EnclosedExpr
       
  4310     {
       
  4311         $$ = create(new NCNameConstructor($1), @$, parseInfo);
       
  4312     }
       
  4313 
       
  4314 /*
       
  4315  * This expression is used for implementing XSL-T 2.0's xsl:namespace
       
  4316  * instruction.
       
  4317  */
       
  4318 CompNamespaceConstructor: NAMESPACE EnclosedExpr EnclosedExpr                       /* [X] */
       
  4319 {
       
  4320     $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
       
  4321 }
       
  4322 
       
  4323 SingleType: AtomicType                                                              /* [117] */
       
  4324     {
       
  4325         $$ = makeGenericSequenceType($1, Cardinality::exactlyOne());
       
  4326     }
       
  4327 | AtomicType QUESTION
       
  4328     {
       
  4329         $$ = makeGenericSequenceType($1, Cardinality::zeroOrOne());
       
  4330     }
       
  4331 
       
  4332 TypeDeclaration: /* empty */                                                        /* [118] */
       
  4333     {
       
  4334         $$ = CommonSequenceTypes::ZeroOrMoreItems;
       
  4335     }
       
  4336 | AS SequenceType
       
  4337     {
       
  4338         $$ = $2;
       
  4339     }
       
  4340 
       
  4341 SequenceType: ItemType OccurrenceIndicator                                          /* [119] */
       
  4342     {
       
  4343         $$ = makeGenericSequenceType($1, $2);
       
  4344     }
       
  4345 
       
  4346 | EMPTY_SEQUENCE EmptyParanteses
       
  4347     {
       
  4348         $$ = CommonSequenceTypes::Empty;
       
  4349     }
       
  4350 
       
  4351 OccurrenceIndicator: /* empty */    {$$ = Cardinality::exactlyOne();}               /* [120] */
       
  4352 | PLUS                              {$$ = Cardinality::oneOrMore();}
       
  4353 | STAR                              {$$ = Cardinality::zeroOrMore();}
       
  4354 | QUESTION                          {$$ = Cardinality::zeroOrOne();}
       
  4355 
       
  4356 ItemType: AtomicType                                                                /* [121] */
       
  4357 | KindTest
       
  4358 | AnyAttributeTest
       
  4359 | ITEM EmptyParanteses
       
  4360     {
       
  4361         $$ = BuiltinTypes::item;
       
  4362     }
       
  4363 
       
  4364 AtomicType: ElementName                                                             /* [122] */
       
  4365     {
       
  4366         const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($1));
       
  4367 
       
  4368         if(!t)
       
  4369         {
       
  4370             parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
       
  4371                                                .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)), ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
       
  4372         }
       
  4373         else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
       
  4374             $$ = AtomicType::Ptr(t);
       
  4375         else
       
  4376         {
       
  4377             /* Try to give an intelligent message. */
       
  4378             if(t->isComplexType())
       
  4379             {
       
  4380                 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
       
  4381                                                    "types is not possible. However, casting "
       
  4382                                                    "to atomic types such as %2 works.")
       
  4383                                                    .arg(formatType(parseInfo->staticContext->namePool(), t))
       
  4384                                                    .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
       
  4385                                                 ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
       
  4386             }
       
  4387             else
       
  4388             {
       
  4389                 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
       
  4390                                                    "is only possible to atomic types.")
       
  4391                                                    .arg(formatType(parseInfo->staticContext->namePool(), t)),
       
  4392                                                 ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
       
  4393             }
       
  4394         }
       
  4395     }
       
  4396 
       
  4397 /* This non-terminal does not contain SchemaAttributeTest and AttributeTest.
       
  4398    Those are in the AnyAttributeTest non-terminal. This is in order to get the axis
       
  4399    right for attribute tests in the abbreviated syntax. */
       
  4400 KindTest: DocumentTest                                                          /* [123] */
       
  4401 | ElementTest
       
  4402 | SchemaElementTest
       
  4403 | PITest
       
  4404 | CommentTest
       
  4405 | TextTest
       
  4406 | AnyKindTest
       
  4407 
       
  4408 AnyKindTest: NODE EmptyParanteses                                               /* [124] */
       
  4409     {
       
  4410         $$ = BuiltinTypes::node;
       
  4411     }
       
  4412 
       
  4413 DocumentTest: DOCUMENT_NODE EmptyParanteses                                     /* [125] */
       
  4414     {
       
  4415         $$ = BuiltinTypes::document;
       
  4416     }
       
  4417 
       
  4418 | DOCUMENT_NODE LPAREN AnyElementTest RPAREN
       
  4419     {
       
  4420         // TODO support for document element testing
       
  4421         $$ = BuiltinTypes::document;
       
  4422     }
       
  4423 
       
  4424 AnyElementTest: ElementTest                                                     /* [X] */
       
  4425 | SchemaElementTest
       
  4426 
       
  4427 TextTest: TEXT EmptyParanteses                                                  /* [126] */
       
  4428     {
       
  4429         $$ = BuiltinTypes::text;
       
  4430     }
       
  4431 
       
  4432 CommentTest: COMMENT EmptyParanteses                                            /* [127] */
       
  4433     {
       
  4434         $$ = BuiltinTypes::comment;
       
  4435     }
       
  4436 
       
  4437 PITest: PROCESSING_INSTRUCTION EmptyParanteses                                  /* [128] */
       
  4438     {
       
  4439         $$ = BuiltinTypes::pi;
       
  4440     }
       
  4441 
       
  4442 | PROCESSING_INSTRUCTION LPAREN NCNAME RPAREN
       
  4443     {
       
  4444         $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
       
  4445     }
       
  4446 
       
  4447 | PROCESSING_INSTRUCTION LPAREN StringLiteral RPAREN
       
  4448     {
       
  4449         if(QXmlUtils::isNCName($3))
       
  4450         {
       
  4451             $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
       
  4452         }
       
  4453         else
       
  4454         {
       
  4455             parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
       
  4456                                                               "processing-instruction.")
       
  4457                                                  .arg(formatKeyword($3)),
       
  4458                                             ReportContext::XPTY0004,
       
  4459                                             fromYYLTYPE(@$, parseInfo));
       
  4460         }
       
  4461     }
       
  4462 
       
  4463 AnyAttributeTest: AttributeTest
       
  4464 | SchemaAttributeTest
       
  4465 
       
  4466 AttributeTest: ATTRIBUTE EmptyParanteses                                            /* [129] */
       
  4467     {
       
  4468         $$ = BuiltinTypes::attribute;
       
  4469     }
       
  4470 
       
  4471 | ATTRIBUTE LPAREN STAR RPAREN
       
  4472     {
       
  4473         $$ = BuiltinTypes::attribute;
       
  4474     }
       
  4475 
       
  4476 | ATTRIBUTE LPAREN AttributeName RPAREN
       
  4477     {
       
  4478         $$ = QNameTest::create(BuiltinTypes::attribute, $3);
       
  4479     }
       
  4480 | ATTRIBUTE LPAREN AttributeName COMMA TypeName RPAREN
       
  4481     {
       
  4482         const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
       
  4483 
       
  4484         if(t)
       
  4485             $$ = BuiltinTypes::attribute;
       
  4486         else
       
  4487         {
       
  4488             parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
       
  4489                                             ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4490         }
       
  4491     }
       
  4492 | ATTRIBUTE LPAREN STAR COMMA TypeName RPAREN
       
  4493     {
       
  4494         const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
       
  4495 
       
  4496         if(t)
       
  4497             $$ = BuiltinTypes::attribute;
       
  4498         else
       
  4499         {
       
  4500             parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
       
  4501                                             ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4502         }
       
  4503     }
       
  4504 
       
  4505 SchemaAttributeTest: SCHEMA_ATTRIBUTE LPAREN ElementName RPAREN                     /* [131] */
       
  4506     {
       
  4507         parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
       
  4508                                            "declarations. Note that the schema import "
       
  4509                                            "feature is not supported.")
       
  4510                                            .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
       
  4511                                         ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4512         $$.reset();
       
  4513     }
       
  4514 
       
  4515 ElementTest: ELEMENT EmptyParanteses                                                /* [133] */
       
  4516     {
       
  4517         $$ = BuiltinTypes::element;
       
  4518     }
       
  4519 
       
  4520 | ELEMENT LPAREN STAR RPAREN
       
  4521     {
       
  4522         $$ = BuiltinTypes::element;
       
  4523     }
       
  4524 
       
  4525 | ELEMENT LPAREN ElementName RPAREN
       
  4526     {
       
  4527         $$ = QNameTest::create(BuiltinTypes::element, $3);
       
  4528     }
       
  4529 
       
  4530 | ELEMENT LPAREN ElementName COMMA TypeName OptionalQuestionMark RPAREN
       
  4531     {
       
  4532         const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
       
  4533 
       
  4534         if(t)
       
  4535             $$ = BuiltinTypes::element;
       
  4536         else
       
  4537         {
       
  4538             parseInfo->staticContext->error(unknownType()
       
  4539                                                .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
       
  4540                                             ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4541         }
       
  4542     }
       
  4543 
       
  4544 | ELEMENT LPAREN STAR COMMA TypeName OptionalQuestionMark RPAREN
       
  4545     {
       
  4546         const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
       
  4547 
       
  4548         if(t)
       
  4549             $$ = BuiltinTypes::element;
       
  4550         else
       
  4551         {
       
  4552             parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
       
  4553                                                .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
       
  4554                                             ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4555         }
       
  4556     }
       
  4557 
       
  4558 OptionalQuestionMark: /* Empty. */
       
  4559 | QUESTION
       
  4560 
       
  4561 SchemaElementTest: SCHEMA_ELEMENT LPAREN ElementName RPAREN                         /* [135] */
       
  4562     {
       
  4563         parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
       
  4564                                            "declarations. Note that the schema import "
       
  4565                                            "feature is not supported.")
       
  4566                                            .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
       
  4567                                         ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
       
  4568         $$.reset();
       
  4569     }
       
  4570 
       
  4571 EmptyParanteses: LPAREN RPAREN                                                      /* [X] */
       
  4572 
       
  4573 AttributeName: NCNAME                                                               /* [137] */
       
  4574     {
       
  4575         $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
       
  4576     }
       
  4577 
       
  4578 | QName
       
  4579 
       
  4580 /*
       
  4581  * When a QName appear with no prefix, it uses a certain default namespace
       
  4582  * depending on where the QName occurs. These two rules, invoked in the appropriate
       
  4583  * contexts, performs this distinction.
       
  4584  */
       
  4585 ElementName: NCNAME                                                                 /* [138] */
       
  4586     {
       
  4587         if(parseInfo->nodeTestSource == BuiltinTypes::element)
       
  4588             $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), $1);
       
  4589         else
       
  4590             $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
       
  4591     }
       
  4592 | QName
       
  4593 
       
  4594 TypeName: ElementName                                                               /* [139] */
       
  4595 
       
  4596 FunctionName: NCName                                                                /* [X] */
       
  4597 | QName
       
  4598 
       
  4599 NCName: NCNAME
       
  4600     {
       
  4601         $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
       
  4602     }
       
  4603 | INTERNAL_NAME NCNAME
       
  4604     {
       
  4605         $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
       
  4606     }
       
  4607 
       
  4608 LexicalName: NCNAME
       
  4609 | QNAME
       
  4610 
       
  4611 PragmaName: NCNAME                                                                  /* [X] */
       
  4612     {
       
  4613         parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
       
  4614                                                           "a namespace."),
       
  4615                                         ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
       
  4616     }
       
  4617 | QName
       
  4618 
       
  4619 URILiteral: StringLiteral                                                           /* [140] */
       
  4620 
       
  4621 StringLiteral: STRING_LITERAL                                                       /* [144] */
       
  4622     {
       
  4623         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  4624     }
       
  4625 | XPATH2_STRING_LITERAL
       
  4626     {
       
  4627         allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
       
  4628     }
       
  4629 
       
  4630 QName: QNAME                                                      /* [154] */
       
  4631     {
       
  4632 
       
  4633         const ReflectYYLTYPE ryy(@$, parseInfo);
       
  4634 
       
  4635         $$ = QNameConstructor::
       
  4636              expandQName<StaticContext::Ptr,
       
  4637                          ReportContext::XPST0081,
       
  4638                          ReportContext::XPST0081>($1, parseInfo->staticContext,
       
  4639                                                   parseInfo->staticContext->namespaceBindings(), &ryy);
       
  4640 
       
  4641     }
       
  4642 | CLARK_NAME
       
  4643     {
       
  4644         $$ = parseInfo->staticContext->namePool()->fromClarkName($1);
       
  4645     }
       
  4646 
       
  4647 %%
       
  4648 
       
  4649 QString Tokenizer::tokenToString(const Token &token)
       
  4650 {
       
  4651     switch(token.type)
       
  4652     {
       
  4653         case NCNAME:
       
  4654         /* Fallthrough. */
       
  4655         case QNAME:
       
  4656         /* Fallthrough. */
       
  4657         case NUMBER:
       
  4658         /* Fallthrough. */
       
  4659         case XPATH2_NUMBER:
       
  4660             return token.value;
       
  4661         case STRING_LITERAL:
       
  4662             return QLatin1Char('"') + token.value + QLatin1Char('"');
       
  4663         default:
       
  4664         {
       
  4665             const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
       
  4666 
       
  4667             /* Remove the quotes. */
       
  4668             if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
       
  4669                 return raw.mid(1, raw.length() - 2);
       
  4670             else
       
  4671                 return raw;
       
  4672         }
       
  4673     }
       
  4674 }
       
  4675 
       
  4676 } /* namespace Patternist */
       
  4677 
       
  4678 QT_END_NAMESPACE
       
  4679 
       
  4680 // vim: et:ts=4:sw=4:sts=4:syntax=yacc