d69868ea14666e5e8b1bccf78d03c6a33c328cac
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / parser / querytransformparser.ypp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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) 2012 Nokia Corporation and/or its subsidiary(-ies).
56 ** Contact: http://www.qt-project.org/
57 **
58 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
59 **
60 ** $QT_BEGIN_LICENSE:LGPL$
61 ** GNU Lesser General Public License Usage
62 ** This file may be used under the terms of the GNU Lesser General Public
63 ** License version 2.1 as published by the Free Software Foundation and
64 ** appearing in the file LICENSE.LGPL included in the packaging of this
65 ** file. Please review the following information to ensure the GNU Lesser
66 ** General Public License version 2.1 requirements will be met:
67 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
68 **
69 ** In addition, as a special exception, Nokia gives you certain additional
70 ** rights. These rights are described in the Nokia Qt LGPL Exception
71 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
72 **
73 ** GNU General Public License Usage
74 ** Alternatively, this file may be used under the terms of the GNU General
75 ** Public License version 3.0 as published by the Free Software Foundation
76 ** and appearing in the file LICENSE.GPL included in the packaging of this
77 ** file. Please review the following information to ensure the GNU General
78 ** Public License version 3.0 requirements will be met:
79 ** http://www.gnu.org/copyleft/gpl.html.
80 **
81 ** Other Usage
82 ** Alternatively, this file may be used in accordance with the terms and
83 ** conditions contained in a signed written agreement between you and Nokia.
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 <private/qabstractfloat_p.h>
109 #include <private/qandexpression_p.h>
110 #include <private/qanyuri_p.h>
111 #include <private/qapplytemplate_p.h>
112 #include <private/qargumentreference_p.h>
113 #include <private/qarithmeticexpression_p.h>
114 #include <private/qatomicstring_p.h>
115 #include <private/qattributeconstructor_p.h>
116 #include <private/qattributenamevalidator_p.h>
117 #include <private/qaxisstep_p.h>
118 #include <private/qbuiltintypes_p.h>
119 #include <private/qcalltemplate_p.h>
120 #include <private/qcastableas_p.h>
121 #include <private/qcastas_p.h>
122 #include <private/qcombinenodes_p.h>
123 #include <private/qcommentconstructor_p.h>
124 #include <private/qcommonnamespaces_p.h>
125 #include <private/qcommonsequencetypes_p.h>
126 #include <private/qcommonvalues_p.h>
127 #include <private/qcomputednamespaceconstructor_p.h>
128 #include <private/qcontextitem_p.h>
129 #include <private/qcopyof_p.h>
130 #include <private/qcurrentitemstore_p.h>
131 #include <private/qdebug_p.h>
132 #include <private/qdelegatingnamespaceresolver_p.h>
133 #include <private/qdocumentconstructor_p.h>
134 #include <private/qelementconstructor_p.h>
135 #include <private/qemptysequence_p.h>
136 #include <private/qemptysequencetype_p.h>
137 #include <private/qevaluationcache_p.h>
138 #include <private/qexpressionfactory_p.h>
139 #include <private/qexpressionsequence_p.h>
140 #include <private/qexpressionvariablereference_p.h>
141 #include <private/qexternalvariablereference_p.h>
142 #include <private/qforclause_p.h>
143 #include <private/qfunctioncall_p.h>
144 #include <private/qfunctionfactory_p.h>
145 #include <private/qfunctionsignature_p.h>
146 #include <private/qgeneralcomparison_p.h>
147 #include <private/qgenericpredicate_p.h>
148 #include <private/qgenericsequencetype_p.h>
149 #include <private/qifthenclause_p.h>
150 #include <private/qinstanceof_p.h>
151 #include <private/qletclause_p.h>
152 #include <private/qliteral_p.h>
153 #include <private/qlocalnametest_p.h>
154 #include <private/qnamespaceconstructor_p.h>
155 #include <private/qnamespacenametest_p.h>
156 #include <private/qncnameconstructor_p.h>
157 #include <private/qnodecomparison_p.h>
158 #include <private/qnodesort_p.h>
159 #include <private/qorderby_p.h>
160 #include <private/qorexpression_p.h>
161 #include <private/qparsercontext_p.h>
162 #include <private/qpath_p.h>
163 #include <private/qpatternistlocale_p.h>
164 #include <private/qpositionalvariablereference_p.h>
165 #include <private/qprocessinginstructionconstructor_p.h>
166 #include <private/qqnameconstructor_p.h>
167 #include <private/qqnametest_p.h>
168 #include <private/qqnamevalue_p.h>
169 #include <private/qquantifiedexpression_p.h>
170 #include <private/qrangeexpression_p.h>
171 #include <private/qrangevariablereference_p.h>
172 #include <private/qreturnorderby_p.h>
173 #include <private/qschemanumeric_p.h>
174 #include <private/qschematypefactory_p.h>
175 #include <private/qsimplecontentconstructor_p.h>
176 #include <private/qstaticbaseuristore_p.h>
177 #include <private/qstaticcompatibilitystore_p.h>
178 #include <private/qtemplateparameterreference_p.h>
179 #include <private/qtemplate_p.h>
180 #include <private/qtextnodeconstructor_p.h>
181 #include <private/qtokenizer_p.h>
182 #include <private/qtreatas_p.h>
183 #include <private/qtypechecker_p.h>
184 #include <private/qunaryexpression_p.h>
185 #include <private/qunresolvedvariablereference_p.h>
186 #include <private/quserfunctioncallsite_p.h>
187 #include <private/qvaluecomparison_p.h>
188 #include <private/qxpathhelper_p.h>
189 #include <private/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 with 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         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