1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
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.
53 /****************************************************************************
55 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
56 ** All rights reserved.
57 ** Contact: http://www.qt-project.org/
59 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
61 ** $QT_BEGIN_LICENSE:LGPL$
62 ** GNU Lesser General Public License Usage
63 ** This file may be used under the terms of the GNU Lesser General Public
64 ** License version 2.1 as published by the Free Software Foundation and
65 ** appearing in the file LICENSE.LGPL included in the packaging of this
66 ** file. Please review the following information to ensure the GNU Lesser
67 ** General Public License version 2.1 requirements will be met:
68 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
70 ** In addition, as a special exception, Nokia gives you certain additional
71 ** rights. These rights are described in the Nokia Qt LGPL Exception
72 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
74 ** GNU General Public License Usage
75 ** Alternatively, this file may be used under the terms of the GNU General
76 ** Public License version 3.0 as published by the Free Software Foundation
77 ** and appearing in the file LICENSE.GPL included in the packaging of this
78 ** file. Please review the following information to ensure the GNU General
79 ** Public License version 3.0 requirements will be met:
80 ** http://www.gnu.org/copyleft/gpl.html.
83 ** Alternatively, this file may be used in accordance with the terms and
84 ** conditions contained in a signed written agreement between you and Nokia.
92 ****************************************************************************/
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.
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>
192 * The cpp generated with bison 2.1 wants to
193 * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
195 #define YYMALLOC malloc
200 /* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
201 * undocumented reason. */
202 namespace QPatternist
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."
210 #define YYERROR_VERBOSE 1
212 #undef YYLTYPE_IS_TRIVIAL
213 #define YYLTYPE_IS_TRIVIAL 0
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.
219 #define YYENABLE_NLS 0
221 static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
222 const ParserContext *const parseInfo)
224 return QSourceLocation(parseInfo->tokenizer->queryURI(),
225 sourceLocator.first_line,
226 sourceLocator.first_column);
233 typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
236 * @short Flags invalid expressions and declarations in the currently
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.
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.
252 * Hence, this function is called from each expression and declaration with @p
253 * allowedLanguages stating what languages it is allowed in.
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.
258 static void allowedIn(const QueryLanguages allowedLanguages,
259 const ParserContext *const parseInfo,
260 const YYLTYPE &sourceLocator,
261 const bool isInternal = false)
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. */
266 (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
271 switch(parseInfo->languageAccent)
273 case QXmlQuery::XPath20:
274 langName = QLatin1String("XPath 2.0");
276 case QXmlQuery::XSLT20:
277 langName = QLatin1String("XSL-T 2.0");
279 case QXmlQuery::XQuery10:
280 langName = QLatin1String("XQuery 1.0");
282 case QXmlQuery::XmlSchema11IdentityConstraintSelector:
283 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
285 case QXmlQuery::XmlSchema11IdentityConstraintField:
286 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
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));
298 static inline bool isVariableReference(const Expression::ID id)
300 return id == Expression::IDExpressionVariableReference
301 || id == Expression::IDRangeVariableReference
302 || id == Expression::IDArgumentReference;
305 class ReflectYYLTYPE : public SourceLocationReflection
308 inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
309 const ParserContext *const pi) : m_sl(sourceLocator)
314 virtual const SourceLocationReflection *actualReflection() const
319 virtual QSourceLocation sourceLocation() const
321 return fromYYLTYPE(m_sl, m_parseInfo);
324 virtual QString description() const
332 const ParserContext *const m_parseInfo;
336 * @short Centralizes a translation string for the purpose of increasing consistency.
338 static inline QString unknownType()
340 return QtXmlPatterns::tr("%1 is an unknown schema type.");
343 static inline Expression::Ptr create(Expression *const expr,
344 const YYLTYPE &sourceLocator,
345 const ParserContext *const parseInfo)
347 parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
348 return Expression::Ptr(expr);
351 static inline Template::Ptr create(Template *const expr,
352 const YYLTYPE &sourceLocator,
353 const ParserContext *const parseInfo)
355 parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
356 return Template::Ptr(expr);
359 static inline Expression::Ptr create(const Expression::Ptr &expr,
360 const YYLTYPE &sourceLocator,
361 const ParserContext *const parseInfo)
363 parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
367 static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
368 const YYLTYPE &sourceLocator,
369 const ParserContext *const parseInfo)
371 return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
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)
384 const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
386 ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
389 static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
390 const SequenceType::Ptr &reqType,
391 const ParserContext *const parseInfo)
393 return TypeChecker::applyFunctionConversion(body, reqType,
394 parseInfo->staticContext,
395 ReportContext::XTTE0505,
396 TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
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)
405 Template::Ptr &e = parseInfo->namedTemplates[name];
409 parseInfo->staticContext->error(QtXmlPatterns::tr("A template by name %1 "
410 "has already been declared.")
411 .arg(formatKeyword(parseInfo->staticContext->namePool(),
413 ReportContext::XTSE0660,
414 fromYYLTYPE(sourceLocator, parseInfo));
424 * @short Centralizes code for creating numeric literals.
426 template<typename TNumberClass>
427 Expression::Ptr createNumericLiteral(const QString &in,
429 const ParserContext *const parseInfo)
431 const Item num(TNumberClass::fromLexical(in));
433 if(num.template as<AtomicValue>()->hasError())
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. */
441 return create(new Literal(num), sl, parseInfo);
445 * @short The generated Bison parser calls this function when there is a parse error.
447 * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
448 * ReportContext::error() is called.
450 static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
452 Q_UNUSED(sourceLocator);
455 parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
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.
463 static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
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>();
476 static inline bool isPredicate(const Expression::ID id)
478 return id == Expression::IDGenericPredicate ||
479 id == Expression::IDFirstItemPredicate;
483 * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
484 * through the predicates and returns the AxisStep.
486 static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
487 const bool throughStructures = true)
491 if(!throughStructures)
494 Expression *candidate = expr.data();
495 Expression::ID id = candidate->id();
497 while(isPredicate(id) || id == Expression::IDPath)
499 const Expression::List &children = candidate->operands();
500 if(children.isEmpty())
501 return Expression::Ptr();
504 candidate = children.first().data();
505 id = candidate->id();
509 if(id == Expression::IDEmptySequence)
510 return Expression::Ptr();
513 Q_ASSERT(candidate->is(Expression::IDAxisStep));
514 return Expression::Ptr(candidate);
518 static void changeToTopAxis(const Expression::Ptr &op)
520 /* This axis must have been written away by now. */
521 Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
523 if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
524 op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
528 * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
529 * into an equivalent XPath expression.
531 * Essentially, the following rewrite is done:
534 * axis1::test1(a)/axis2::test2(b)
536 * child-or-top::test2(b)[parent::test1(a)]
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.
543 * Keep in mind the rewrites that non-terminal PatternStep do.
545 * @see createIdPatternPath()
547 static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
548 const Expression::Ptr &operand2,
549 const QXmlNodeModelIndex::Axis axis,
551 const ParserContext *const parseInfo)
553 const Expression::Ptr operandL(findAxisStep(operand1, false));
555 if(operandL->is(Expression::IDAxisStep))
556 operandL->as<AxisStep>()->setAxis(axis);
558 findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
560 return create(GenericPredicate::create(operand2, operandL,
561 parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
565 * @short Performs the same role as createPatternPath(), but is tailored
566 * for @c fn:key() and @c fn:id().
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:
576 * child-or-top::abc[parent::id-or-key]
579 * Our approach is to rewrite like this:
584 * child-or-top::abc[parent::node is id-or-key]
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.
590 * @see createPatternPath()
592 static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
593 const Expression::Ptr &operand2,
594 const QXmlNodeModelIndex::Axis axis,
596 const ParserContext *const parseInfo)
598 const Expression::Ptr operandR(findAxisStep(operand2));
600 changeToTopAxis(operandR);
602 const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
605 const Expression::Ptr isComp(create(new NodeComparison(parentStep,
606 QXmlNodeModelIndex::Is,
611 return create(GenericPredicate::create(operandR, isComp,
612 parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
616 * @short Centralizes a translation message, for the
617 * purpose of consistency and modularization.
619 static inline QString prologMessage(const char *const msg)
622 return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
626 * @short Resolves against the static base URI and checks that @p collation
627 * is a supported Unicode Collation.
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."
633 * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
635 template<const ReportContext::ErrorCode errorCode>
636 static QUrl resolveAndCheckCollation(const QString &collation,
637 const ParserContext *const parseInfo,
641 const ReflectYYLTYPE ryy(sl, parseInfo);
643 QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
646 uri = parseInfo->staticContext->baseURI().resolved(uri);
648 XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
653 /* The Bison generated parser declares macros that aren't used
654 * so suppress the warnings by fake usage of them.
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) \
661 || defined(yydebug) \
662 || defined(YYSKELETON_NAME)
666 * Wraps @p operand with a CopyOf in case it makes any difference.
668 * There is no need to wrap the return value in a call to create(), it's
671 static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
672 const ParserContext *const parseInfo,
675 return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
676 parseInfo->preserveNamespacesMode), sl, parseInfo);
679 static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
680 const YYLTYPE &sourceLocator,
681 const ParserContext *const parseInfo)
683 return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
687 * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
688 * <tt>fn:root(self::node()) treat as document-node()</tt>.
690 static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
694 const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
696 Expression::List args;
697 args.append(create(new ContextItem(), sl, parseInfo));
699 const ReflectYYLTYPE ryy(sl, parseInfo);
701 const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
702 ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
705 return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
708 static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
710 #ifdef Patternist_DEBUG_PARSER
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."
718 extern int XPathdebug;
724 const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
726 (*lexVal).sval = tok.value;
728 return static_cast<int>(tok.type);
732 * @short Creates a path expression which contains the step <tt>//</tt> between
733 * @p begin and and @p end.
735 * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
737 * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
739 static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
740 const Expression::Ptr &end,
741 const YYLTYPE &sourceLocator,
742 const ParserContext *const parseInfo)
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));
747 return create(new Path(p1, end), sourceLocator, parseInfo);
751 * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
753 static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
754 const Expression::List &args,
755 const YYLTYPE &sourceLocator)
758 const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
759 const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
761 return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
762 sourceLocator, parseInfo);
765 static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
766 const ParserContext *const parseInfo,
767 const YYLTYPE &sourceLocator)
769 if(content.isEmpty())
770 return create(new EmptySequence(), sourceLocator, parseInfo);
771 else if(content.size() == 1)
772 return content.first();
774 return createConcatFN(parseInfo, content, sourceLocator);
778 * @short Checks for variable initialization circularity.
780 * "A recursive function that checks for recursion is full of ironies."
782 * -- The Salsa Master
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.
788 * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
789 * Query Language, err:XQST0054</a>
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)
801 const Expression::ID id = checkee->id();
803 if(id == Expression::IDExpressionVariableReference)
805 const ExpressionVariableReference *const ref =
806 static_cast<const ExpressionVariableReference *>(checkee.data());
808 if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
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);
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);
823 else if(id == Expression::IDUserFunctionCallsite)
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());
831 for(; it != end; ++it)
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. */
845 signList.append(sign);
846 /* Check the body of the function being called. */
847 checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
849 /* Continue with the operands, such that we also check the arguments of the callsite. */
851 else if(id == Expression::IDUnresolvedVariableReference)
853 /* We're called before it has rewritten itself. */
854 checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
857 /* Check the operands. */
858 const Expression::List ops(checkee->operands());
862 const Expression::List::const_iterator end(ops.constEnd());
863 Expression::List::const_iterator it(ops.constBegin());
865 for(; it != end; ++it)
866 checkVariableCircularity(var, *it, type, signList, parseInfo);
869 static void variableUnavailable(const QXmlName &variableName,
870 const ParserContext *const parseInfo,
871 const YYLTYPE &location)
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));
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().
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()
886 static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
889 return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
893 * @p seqType and @p expr may be @c null.
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)
903 Q_ASSERT(!name.isNull());
906 /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
907 VariableSlotID slot = -2;
911 case VariableDeclaration::FunctionArgument:
913 case VariableDeclaration::ExpressionVariable:
915 slot = parseInfo->allocateExpressionSlot();
918 case VariableDeclaration::GlobalVariable:
920 slot = parseInfo->allocateGlobalVariableSlot();
923 case VariableDeclaration::RangeVariable:
925 slot = parseInfo->staticContext->allocateRangeSlot();
928 case VariableDeclaration::PositionalVariable:
930 slot = parseInfo->allocatePositionalSlot();
933 case VariableDeclaration::TemplateParameter:
934 /* Fallthrough. We do nothing, template parameters
935 * doesn't use context slots at all, they're hashed
937 case VariableDeclaration::ExternalVariable:
938 /* We do nothing, external variables doesn't use
939 *context slots/stack frames at all. */
943 const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
945 Expression::Ptr checked;
947 if(checkSource && seqType)
951 /* We only want to add conversion for function arguments, and variables
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());
961 checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
962 parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
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().
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.
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);
983 var->setExpression(checked);
985 parseInfo->variables.push(var);
989 static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
990 const ParserContext *const parseInfo)
992 Q_ASSERT(!name.isNull());
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());
1003 if((*it)->name == name)
1007 return VariableDeclaration::Ptr();
1010 static Expression::Ptr resolveVariable(const QXmlName &name,
1011 const YYLTYPE &sourceLocator,
1012 ParserContext *const parseInfo,
1013 const bool raiseErrorOnUnavailability)
1015 const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
1016 Expression::Ptr retval;
1018 if(var && var->type != VariableDeclaration::ExternalVariable)
1022 case VariableDeclaration::RangeVariable:
1024 retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
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:
1033 retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
1036 case VariableDeclaration::FunctionArgument:
1038 retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
1041 case VariableDeclaration::PositionalVariable:
1043 retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
1046 case VariableDeclaration::TemplateParameter:
1048 retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
1051 case VariableDeclaration::ExternalVariable:
1052 /* This code path will never be hit, but the case
1053 * label silences a warning. See above. */
1057 var->references.append(retval);
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));
1067 const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
1068 const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
1071 else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
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);
1079 variableUnavailable(name, parseInfo, sourceLocator);
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)
1091 // TODO do resize(orderSpec.size() + 1)
1092 Expression::List exprs;
1093 OrderBy::OrderSpec::Vector orderSpecs;
1095 exprs.append(returnExpr);
1097 const int len = orderSpecTransfer.size();
1099 for(int i = 0; i < len; ++i)
1101 exprs.append(orderSpecTransfer.at(i).expression);
1102 orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
1105 return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
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. */
1114 %name-prefix="XPath"
1116 /* Specifies the name of the generated parser. */
1117 %output="qquerytransformparser.cpp"
1119 /* Output the .output file. */
1122 /* Yes, we want descriptive error messages. */
1125 /* We'd like to be reentrant/thread-safe */
1128 /* We want code for line/columns to be generated. */
1131 /* Create a header file and put declarations there. */
1134 %parse-param {ParserContext *const parseInfo}
1135 %lex-param {ParserContext *const parseInfo}
1138 /* Silences the following:
1142 293 SequenceType: ItemType . OccurrenceIndicator
1144 "+" shift, and go to state 379
1145 "*" shift, and go to state 380
1146 "?" shift, and go to state 381
1148 "+" [reduce using rule 295 (OccurrenceIndicator)]
1149 "*" [reduce using rule 295 (OccurrenceIndicator)]
1150 $default reduce using rule 295 (OccurrenceIndicator)
1152 OccurrenceIndicator go to state 382
1156 200 PathExpr: "/" . RelativePathExpr
1161 "<" [reduce using rule 203 (PathExpr)]
1162 "*" [reduce using rule 203 (PathExpr)]
1163 $default reduce using rule 203 (PathExpr)
1166 %token <sval> STRING_LITERAL "<string literal>"
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>"
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
1177 %token <sval> XPATH2_STRING_LITERAL "<string literal(XPath 2.0)>"
1178 %token <sval> QNAME "QName"
1179 %token <sval> NCNAME "NCName"
1181 /* A QName as a clark name. See QXmlName::toClarkName(). */
1182 %token <sval> CLARK_NAME "ClarkName"
1185 * Is "ncname:*". The token value does not include the colon and the star.
1187 %token <sval> ANY_LOCAL_NAME
1190 * Is "*:ncname". The token value does not include the colon and the star.
1192 %token <sval> ANY_PREFIX
1195 * An XPath 1.0 number literal. It is a string value because
1196 * Numeric::fromLexical() does the tokenization.
1198 %token <sval> NUMBER "<number literal>"
1201 * XPath 2.0 number literal. It includes the use of 'e'/'E'
1203 %token <sval> XPATH2_NUMBER "<number literal(XPath 2.0)>"
1205 %token ANCESTOR "ancestor"
1206 %token ANCESTOR_OR_SELF "ancestor-or-self"
1209 %token APPLY_TEMPLATE "apply-template"
1211 %token ASCENDING "ascending"
1215 %token ATTRIBUTE "attribute"
1216 %token AVT /* Synthetic token. Signals an attribute value template. */
1218 %token BASEURI "base-uri"
1219 %token BEGIN_END_TAG "</"
1220 %token BOUNDARY_SPACE "boundary-space"
1222 %token CALL_TEMPLATE "call-template"
1224 %token CASTABLE "castable"
1226 %token CHILD "child"
1227 %token COLLATION "collation"
1228 %token COLONCOLON "::"
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"
1242 %token DOCUMENT "document"
1243 %token DOCUMENT_NODE "document-node"
1247 %token ELEMENT "element"
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"
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"
1262 %token FOR_APPLY_TEMPLATE "for-apply-template" /* Synthetic token, used in XSL-T. */
1264 %token FUNCTION "function"
1272 %token GREATEST "greatest"
1276 %token IMPORT "import"
1277 %token INHERIT "inherit"
1279 %token INSTANCE "instance"
1280 %token INTERSECT "intersect"
1285 %token LEAST "least"
1290 %token MAP "map" /* Synthetic token, used in XSL-T. */
1291 %token MATCHES "matches"
1293 %token MODE "mode" /* Synthetic token, used in XSL-T. */
1295 %token MODULE "module"
1297 %token NAMESPACE "namespace"
1300 %token NO_INHERIT "no-inherit"
1301 %token NO_PRESERVE "no-preserve"
1303 %token OPTION "option"
1304 %token ORDERED "ordered"
1305 %token ORDERING "ordering"
1306 %token ORDER "order"
1308 %token PARENT "parent"
1309 %token PI_START "<?"
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"
1321 %token QUICK_TAG_END "/>"
1324 %token RETURN "return"
1326 %token SATISFIES "satisfies"
1327 %token SCHEMA_ATTRIBUTE "schema-attribute"
1328 %token SCHEMA_ELEMENT "schema-element"
1329 %token SCHEMA "schema"
1331 %token SEMI_COLON ";"
1333 %token SLASHSLASH "//"
1335 %token SORT "sort" /* Synthetic token, used in XSL-T. */
1336 %token STABLE "stable"
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"
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. */
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
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
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
1424 /* Operator Precendence
1425 * See: http://www.w3.org/TR/xpath20/#parse-note-occurrence-indicators */
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
1438 VersionDecl: /* empty */ /* [2] */
1439 | XQUERY VERSION StringLiteral Encoding Separator
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)
1459 if($3 != QLatin1String("1.0"))
1461 const ReflectYYLTYPE ryy(@$, parseInfo);
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);
1470 Encoding: /* empty */ /* [X] */
1471 | ENCODING StringLiteral
1473 const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
1475 if(!encNameRegExp.exactMatch($2))
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));
1487 MainModule: Prolog QueryBody /* [3] */
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())
1493 typedef QHash<QXmlName, Expression::Ptr> Hash;
1494 const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
1496 for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
1498 const Expression::Ptr body(resolveVariable(it.key(), @$, parseInfo, true)); // TODO source locations vaise
1500 it.value()->as<UnresolvedVariableReference>()->bindTo(body);
1504 /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
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. */
1510 const UserFunctionCallsite::Ptr callsite(*cit);
1512 const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
1513 UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
1515 for(; it != end; ++it) /* For each UserFunction. */
1517 const FunctionSignature::Ptr sign((*it)->signature());
1520 if(callsite->isSignatureValid(sign))
1522 callsite->setSource((*it),
1523 parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
1529 parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
1530 .arg(formatFunction(callsite)),
1531 ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
1536 /* Mark callsites in UserFunction bodies as recursive, if they are. */
1538 const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
1539 UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
1540 for(; fit != fend; ++fit)
1542 CallTargetDescription::List signList;
1543 signList.append((*fit)->signature());
1544 CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
1548 /* Now, check all global variables for circularity. This is done
1549 * backwards because global variables are only in scope below them,
1552 const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
1553 VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
1558 if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
1559 continue; /* We want to ignore 'external' variables. */
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. */
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))
1575 parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
1578 parseInfo->templateCalls.append(parseInfo->queryBody);
1579 /* We just discard the template body that XSLTTokenizer generated. */
1582 parseInfo->queryBody = $2;
1585 LibraryModule: ModuleDecl Prolog /* [4] */
1587 ModuleDecl: MODULE NAMESPACE NCNAME G_EQ URILiteral Separator /* [5] */
1589 // TODO add to namespace context
1590 parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace($3);
1593 Prolog: /* Empty. */ /* [6] */
1595 | Prolog DefaultNamespaceDecl
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));
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));
1608 | Prolog NamespaceDecl
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));
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));
1621 | Prolog TemplateDecl
1626 parseInfo->hasSecondPrologPart = true;
1628 | Prolog FunctionDecl
1630 parseInfo->hasSecondPrologPart = true;
1634 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1635 parseInfo->hasSecondPrologPart = true;
1639 * declare template name theName
1646 * declare template name theName matches (pattern) mode modeName priority 123
1652 TemplateDecl: DECLARE TEMPLATE TemplateName
1653 OptionalTemplateParameters
1655 EnclosedOptionalExpr Separator /* [X] */
1657 Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, $5), @$, parseInfo));
1659 registerNamedTemplate($3, typeCheckTemplateBody($6, $5, parseInfo),
1660 parseInfo, @1, temp);
1661 temp->templateParameters = parseInfo->templateParameters;
1662 parseInfo->templateParametersHandled();
1664 | DECLARE TEMPLATE OptionalTemplateName
1667 parseInfo->isParsingPattern = true;
1671 parseInfo->isParsingPattern = false;
1676 OptionalTemplateParameters
1678 EnclosedOptionalExpr Separator /* [X] */
1680 /* In this grammar branch, we're guaranteed to be a template rule, but
1681 * may also be a named template. */
1683 const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
1684 Expression::Ptr pattern($7);
1685 const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
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();
1692 TemplatePattern::Vector ourPatterns;
1693 /* We do it as per 6.4 Conflict Resolution for Template Rules:
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))
1701 const Expression::List operands(pattern->operands());
1702 pattern = operands.first();
1704 loadPattern(operands.at(1), ourPatterns, templateID, $11, templ);
1707 loadPattern(pattern, ourPatterns, templateID, $11, templ);
1710 registerNamedTemplate($3, $14, parseInfo, @1, templ);
1712 /* Now, let's add it to all the relevant templates. */
1713 for(int i = 0; i < $10.count(); ++i) /* For each mode. */
1715 const QXmlName &modeName = $10.at(i);
1717 if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && $10.count() > 1)
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));
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));
1732 OptionalPriority: /* Empty. */ /* [X] */
1734 $$ = std::numeric_limits<xsDouble>::quiet_NaN();
1737 | PRIORITY StringLiteral
1739 const AtomicValue::Ptr val(Decimal::fromLexical($2));
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),
1746 ReportContext::XTSE0530,
1747 fromYYLTYPE(@$, parseInfo));
1750 $$ = val->as<Numeric>()->toDouble();
1753 OptionalTemplateName: /* Empty. */ /* [X] */
1759 TemplateName: NAME ElementName
1764 Setter: BoundarySpaceDecl /* [7] */
1765 | DefaultCollationDecl
1767 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1772 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1776 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1780 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1782 | CopyNamespacesDecl
1784 Import: SchemaImport /* [8] */
1787 Separator: SEMI_COLON /* [9] */
1789 NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator /* [10] */
1792 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1794 if($3 == QLatin1String("xmlns"))
1796 parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
1797 .arg(formatKeyword(QLatin1String("xmlns"))),
1798 ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
1800 else if ($5 == CommonNamespaces::XML || $3 == QLatin1String("xml"))
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));
1810 else if(parseInfo->declaredPrefixes.contains($3))
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));
1820 parseInfo->declaredPrefixes.append($3);
1824 parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
1825 StandardLocalNames::empty,
1826 parseInfo->staticContext->namePool()->allocatePrefix($3)));
1830 parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding($3, $5));
1835 BoundarySpaceDecl: DECLARE BOUNDARY_SPACE BoundarySpacePolicy Separator /* [11] */
1837 if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
1839 parseInfo->staticContext->error(prologMessage("declare boundary-space"),
1840 ReportContext::XQST0068, fromYYLTYPE(@$, parseInfo));
1844 parseInfo->staticContext->setBoundarySpacePolicy($3);
1845 parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
1849 BoundarySpacePolicy: STRIP /* [X] */
1851 $$ = StaticContext::BSPStrip;
1856 $$ = StaticContext::BSPPreserve;
1859 DefaultNamespaceDecl: DeclareDefaultElementNamespace /* [12] */
1860 | DeclareDefaultFunctionNamespace
1862 DeclareDefaultElementNamespace: DECLARE DEFAULT ELEMENT NAMESPACE
1863 URILiteral Separator /* [X] */
1865 if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
1867 parseInfo->staticContext->error(prologMessage("declare default element namespace"),
1868 ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
1872 parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), StandardLocalNames::empty));
1873 parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
1877 DeclareDefaultFunctionNamespace: DECLARE DEFAULT FUNCTION NAMESPACE
1878 URILiteral Separator /* [X] */
1880 if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
1882 parseInfo->staticContext->error(prologMessage("declare default function namespace"),
1883 ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
1887 parseInfo->staticContext->setDefaultFunctionNamespace($5);
1888 parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
1892 OptionDecl: DECLARE OPTION ElementName StringLiteral Separator /* [13] */
1894 if($3.prefix() == StandardPrefixes::empty)
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));
1902 OrderingModeDecl: DECLARE ORDERING OrderingMode Separator /* [14] */
1904 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
1905 if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
1907 parseInfo->staticContext->error(prologMessage("declare ordering"),
1908 ReportContext::XQST0065, fromYYLTYPE(@$, parseInfo));
1912 parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
1913 parseInfo->staticContext->setOrderingMode($3);
1917 OrderingMode: ORDERED
1919 $$ = StaticContext::Ordered;
1923 $$ = StaticContext::Unordered;
1926 EmptyOrderDecl: DECLARE DEFAULT ORDER OrderingEmptySequence Separator /* [15] */
1928 if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
1930 parseInfo->staticContext->error(prologMessage("declare default order"),
1931 ReportContext::XQST0069, fromYYLTYPE(@$, parseInfo));
1935 parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
1936 parseInfo->staticContext->setOrderingEmptySequence($4);
1940 OrderingEmptySequence: EMPTY LEAST /* [X] */
1942 $$ = StaticContext::Least;
1946 $$ = StaticContext::Greatest;
1949 CopyNamespacesDecl: DECLARE COPY_NAMESPACES PreserveMode COMMA
1950 InheritMode Separator /* [16] */
1952 if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
1954 parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
1955 ReportContext::XQST0055, fromYYLTYPE(@$, parseInfo));
1959 parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
1963 PreserveMode: PRESERVE /* [17] */
1965 parseInfo->preserveNamespacesMode = true;
1970 parseInfo->preserveNamespacesMode = false;
1973 InheritMode: INHERIT /* [18] */
1975 parseInfo->inheritNamespacesMode = true;
1980 parseInfo->inheritNamespacesMode = false;
1983 DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator /* [19] */
1985 if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
1987 parseInfo->staticContext->error(prologMessage("declare default collation"),
1988 ReportContext::XQST0038, fromYYLTYPE(@$, parseInfo));
1992 const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>($4, parseInfo, @$));
1994 parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
1995 parseInfo->staticContext->setDefaultCollation(coll);
1999 BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator /* [20] */
2001 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3);
2002 if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
2004 parseInfo->staticContext->error(prologMessage("declare base-uri"),
2005 ReportContext::XQST0032, fromYYLTYPE(@$, parseInfo));
2009 parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
2010 const ReflectYYLTYPE ryy(@$, parseInfo);
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. */
2015 if(toBeBase.isRelative())
2016 toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
2018 parseInfo->staticContext->setBaseURI(toBeBase);
2022 SchemaImport: IMPORT SCHEMA SchemaPrefix URILiteral FileLocations Separator /* [21] */
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));
2030 SchemaPrefix: /* empty */ /* [22] */
2031 | DEFAULT ELEMENT NAMESPACE
2032 | NAMESPACE NCNAME G_EQ
2034 ModuleImport: IMPORT MODULE ModuleNamespaceDecl URILiteral FileLocations Separator /* [23] */
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));
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));
2051 ModuleNamespaceDecl: /* empty */ /* [X] */
2052 | NAMESPACE NCNAME G_EQ
2054 FileLocations: /* empty */ /* [X] */
2057 FileLocation: URILiteral /* [X] */
2058 | FileLocation COMMA URILiteral
2060 VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration
2061 VariableValue OptionalDefaultValue Separator /* [24] */
2063 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
2064 if(variableByName($5, parseInfo))
2066 parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already "
2068 .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical($5))),
2069 parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
2070 fromYYLTYPE(@$, parseInfo));
2074 if($7) /* We got a value assigned. */
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));
2081 pushVariable($5, $6, checked, VariableDeclaration::GlobalVariable, @$, parseInfo);
2082 parseInfo->declaredVariables.append(parseInfo->variables.last());
2084 else /* We got an 'external' declaration. */
2086 const SequenceType::Ptr varType(parseInfo->staticContext->
2087 externalVariableLoader()->announceExternalVariable($5, $6));
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);
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.
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));
2115 VariableValue: EXTERNAL /* [X] */
2124 OptionalDefaultValue: /* Empty. */ /* [X] */
2133 ConstructionDecl: DECLARE CONSTRUCTION ConstructionMode Separator /* [25] */
2135 if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
2137 parseInfo->staticContext->error(prologMessage("declare ordering"),
2138 ReportContext::XQST0067, fromYYLTYPE(@$, parseInfo));
2142 parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
2143 parseInfo->staticContext->setConstructionMode($3);
2147 ConstructionMode: STRIP /* [X] */
2149 $$ = StaticContext::CMStrip;
2153 $$ = StaticContext::CMPreserve;
2156 FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN
2158 $<enums.slot>$ = parseInfo->currentExpressionSlot() - $6.count();
2160 TypeDeclaration FunctionBody Separator /* [26] */
2163 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
2165 /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
2166 const QXmlName::NamespaceCode ns($4.namespaceURI());
2168 if(parseInfo->isXSLT() && !$4.hasPrefix())
2170 parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
2171 ReportContext::XTSE0740,
2172 fromYYLTYPE(@$, parseInfo));
2175 if($10) /* We got a function body. */
2177 if(ns == StandardNamespaces::empty)
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 "
2183 .arg(formatKeyword("local")),
2184 ReportContext::XQST0060, fromYYLTYPE(@$, parseInfo));
2186 else if(XPathHelper::isReservedNamespace(ns))
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));
2197 else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
2198 ns != parseInfo->moduleNamespace)
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 "
2206 .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
2207 formatURI(parseInfo->staticContext->namePool(), ns)),
2208 ReportContext::XQST0048, fromYYLTYPE(@$, parseInfo));
2212 /* Apply function conversion such that the body matches the declared
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)));
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());
2230 for(; it != end; ++it)
2232 if(*(*it)->signature() == *sign)
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));
2241 VariableDeclaration::List argDecls;
2243 for(int i = 0; i < argCount; ++i)
2244 argDecls.append(parseInfo->variables.at(i));
2246 if($<enums.slot>8 > -1)
2248 /* We have allocated slots, so now push them out of scope. */
2249 parseInfo->finalizePushedVariable(argCount);
2252 parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, $<enums.slot>8, argDecls)));
2255 else /* We got an 'external' declaration. */
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));
2264 ParamList: /* empty */ /* [27] */
2266 $$ = FunctionArgument::List();
2270 FunctionArgument::List l;
2274 | ParamList COMMA Param
2276 FunctionArgument::List::const_iterator it($1.constBegin());
2277 const FunctionArgument::List::const_iterator end($1.constEnd());
2279 for(; it != end; ++it)
2281 if((*it)->name() == $3->name())
2283 parseInfo->staticContext->error(QtXmlPatterns::tr("An argument by name %1 has already "
2284 "been declared. Every argument name "
2286 .arg(formatKeyword(parseInfo->staticContext->namePool(), $3->name())),
2287 ReportContext::XQST0039, fromYYLTYPE(@$, parseInfo));
2295 Param: DOLLAR VarName TypeDeclaration /* [28] */
2297 pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
2298 $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
2301 FunctionBody: EXTERNAL /* [X] */
2307 EnclosedExpr: CURLY_LBRACE Expr CURLY_RBRACE /* [29] */
2312 QueryBody: Expr /* [30] */
2315 * A pattern as found in for instance xsl:template/@match.
2317 * @note When using this pattern, remember to set ParserContext::isParsingPattern.
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>
2322 Pattern: PathPattern /* [XSLT20-1] */
2323 | Pattern BAR PathPattern
2325 $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
2328 PathPattern: RelativePathPattern /* [XSLT20-2] */
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);
2338 | SLASH RelativePathPattern
2342 * axis::node-test[parent::document-node()]
2344 * In practice it looks like this. $2 is:
2347 * AxisStep self::element(c)
2349 * AxisStep parent::element(b)
2350 * AxisStep parent::element(a)
2355 * AxisStep self::element(c)
2357 * AxisStep self::element(b)
2359 * AxisStep parent::element(a)
2360 * AxisStep parent::document()
2362 * So we want to rewrite the predicate deepest down into a
2363 * another TruthPredicate containing the AxisStep.
2365 * The simplest case where $2 is only an axis step is special. When $2 is:
2367 * AxisStep self::element(a)
2372 * AxisStep self::element(a)
2373 * AxisStep parent::document()
2376 /* First, find the target. */
2377 Expression::Ptr target($2);
2379 while(isPredicate(target->id()))
2381 const Expression::Ptr candidate(target->operands().at(1));
2383 if(isPredicate(candidate->id()))
2386 break; /* target is now the last predicate. */
2389 if(target->is(Expression::IDAxisStep))
2391 $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
2392 parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
2396 const Expression::List targetOperands(target->operands());
2397 Expression::List newOps;
2398 newOps.append(targetOperands.at(0));
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));
2404 target->setOperands(newOps);
2408 | SLASHSLASH RelativePathPattern
2410 /* //axis::node-test
2412 * axis::node-test[parent::node()]
2414 * Spec says: "//para matches any para element that has a parent node."
2416 $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo),
2417 parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
2420 | IdKeyPattern SLASH RelativePathPattern
2422 createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
2424 | IdKeyPattern SLASHSLASH RelativePathPattern
2426 createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
2429 IdKeyPattern: FunctionCallExpr
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);
2439 const Expression::ID id = ands.first()->id();
2440 if(!isVariableReference(id) && id != Expression::IDStringValue)
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));
2449 else if(name == key)
2451 if(ands.first()->id() != Expression::IDStringValue)
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));
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)
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));
2474 if(ands.count() == 3)
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));
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));
2498 RelativePathPattern: PatternStep /* [XSLT20-3] */
2499 | RelativePathPattern SLASH PatternStep
2501 $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
2503 | RelativePathPattern SLASHSLASH PatternStep
2505 $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
2508 PatternStep: FilteredAxisStep
2510 const Expression::Ptr expr(findAxisStep($1));
2512 const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
2513 AxisStep *const axisStep = expr->as<AxisStep>();
2515 /* Here we constrain the possible axes, and we rewrite the axes as according
2516 * to 5.5.3 The Meaning of a Pattern.
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. */
2525 if(axisStep->nodeTest() == BuiltinTypes::document
2526 || axis == QXmlNodeModelIndex::AxisChild)
2527 axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
2528 else if(axis == QXmlNodeModelIndex::AxisAttribute)
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);
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));
2552 Expr: ExprSingle /* [31] */
2553 | ExpressionSequence
2555 $$ = create(new ExpressionSequence($1), @$, parseInfo);
2558 ExpressionSequence: ExprSingle COMMA ExprSingle /* [X] */
2565 | ExpressionSequence COMMA ExprSingle
2571 ExprSingle: OrExpr /* [32] */
2576 | AVT LPAREN AttrValueContent RPAREN
2578 $$ = createDirAttributeValue($3, parseInfo, @$);
2581 OptionalModes: /* Empty. */ /* [X] */
2583 QVector<QXmlName> result;
2584 result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
2592 OptionalMode: /* Empty. */ /* [X] */
2594 $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
2603 QVector<QXmlName> result;
2613 Mode: QName /* [X] */
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);
2627 const ReflectYYLTYPE ryy(@$, parseInfo);
2629 if(!QXmlUtils::isNCName($1))
2631 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
2632 .arg(formatKeyword($1)),
2633 ReportContext::XTSE0550,
2634 fromYYLTYPE(@$, parseInfo));
2637 $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
2642 FLWORExpr: ForClause /* [33] */
2645 ForClause: FOR DOLLAR VarName TypeDeclaration
2646 PositionalVar IN ExprSingle
2648 /* We're pushing the range variable here, not the positional. */
2649 $<expr>$ = pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
2652 /* It is ok this appears after PositionalVar, because currentRangeSlot()
2653 * uses a different "channel" than currentPositionSlot(), so they can't trash
2655 $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
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)
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));
2676 const Expression::Ptr retBody(create(new ForClause($<enums.slot>9, $<expr>8, $10, $5), @$, parseInfo));
2677 ReturnOrderBy *const rob = locateReturnClause($10);
2680 $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), @$, parseInfo);
2684 parseInfo->finalizePushedVariable();
2686 if($5 != -1) /* We also have a positional variable to remove from the scope. */
2687 parseInfo->finalizePushedVariable();
2690 ForTail: COMMA DOLLAR VarName TypeDeclaration
2691 PositionalVar IN ExprSingle
2693 pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
2696 /* It is ok this appears after PositionalVar, because currentRangeSlot()
2697 * uses a different "channel" than currentPositionSlot(), so they can't trash
2699 $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
2703 $$ = create(new ForClause($<enums.slot>9, $<expr>7, $10, $5), @$, parseInfo);
2705 parseInfo->finalizePushedVariable();
2707 if($5 != -1) /* We also have a positional variable to remove from the scope. */
2708 parseInfo->finalizePushedVariable();
2715 PositionalVar: /* empty */ /* [35] */
2722 pushVariable($3, CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
2723 VariableDeclaration::PositionalVariable, @$, parseInfo);
2724 $$ = parseInfo->currentPositionSlot();
2727 LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
2729 $<expr>$ = pushVariable($4, quantificationType($5), $7, VariableDeclaration::ExpressionVariable, @$, parseInfo);
2733 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
2735 Q_ASSERT(parseInfo->variables.top()->name == $4);
2736 $$ = create(new LetClause($<expr>8, $9, parseInfo->variables.top()), @$, parseInfo);
2737 parseInfo->finalizePushedVariable();
2740 LetTail: COMMA DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
2741 { $<expr>$ = pushVariable($3, quantificationType($4), $6, VariableDeclaration::ExpressionVariable, @$, parseInfo);}
2744 Q_ASSERT(parseInfo->variables.top()->name == $3);
2745 $$ = create(new LetClause($<expr>7, $8, parseInfo->variables.top()), @$, parseInfo);
2746 parseInfo->finalizePushedVariable();
2753 WhereClause: OrderByClause RETURN ExprSingle /* [37] */
2758 $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
2761 | WHERE ExprSingle OrderByClause RETURN ExprSingle
2764 $$ = create(new IfThenClause($2, $5, create(new EmptySequence, @$, parseInfo)), @$, parseInfo);
2766 $$ = create(new IfThenClause($2, createReturnOrderBy($3, $5, parseInfo->orderStability.pop(), @$, parseInfo),
2767 create(new EmptySequence, @$, parseInfo)),
2771 OrderByClause: /* Empty. */ /* [38] */
2773 $$ = OrderSpecTransfer::List();
2775 | MandatoryOrderByClause
2777 MandatoryOrderByClause: OrderByInputOrder OrderSpecList
2782 OrderSpecList: OrderSpecList COMMA OrderSpec /* [39] */
2784 OrderSpecTransfer::List list;
2791 OrderSpecTransfer::List list;
2796 OrderSpec: ExprSingle DirectionModifier EmptynessModifier CollationModifier /* [40] */
2798 $$ = OrderSpecTransfer($1, OrderBy::OrderSpec($2, $3));
2801 DirectionModifier: /* Empty. */ /* [X] */
2803 /* Where does the specification state the default value is ascending?
2805 * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
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:
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."
2816 * which means that if you don't specify anything, or you
2817 * specify ascending, you get the same result.
2819 $$ = OrderBy::OrderSpec::Ascending;
2824 $$ = OrderBy::OrderSpec::Ascending;
2829 $$ = OrderBy::OrderSpec::Descending;
2832 EmptynessModifier: /* Empty. */ /* [X] */
2834 $$ = parseInfo->staticContext->orderingEmptySequence();
2836 | OrderingEmptySequence
2838 CollationModifier: /* Empty. */ /* [X] */
2839 | COLLATION URILiteral
2841 if(parseInfo->isXSLT())
2842 resolveAndCheckCollation<ReportContext::XTDE1035>($2, parseInfo, @$);
2844 resolveAndCheckCollation<ReportContext::XQST0076>($2, parseInfo, @$);
2846 | INTERNAL COLLATION ExprSingle
2848 /* We do nothing. We don't use collations, and we have this non-terminal
2849 * in order to accept expressions. */
2852 OrderByInputOrder: STABLE ORDER BY /* [X] */
2854 parseInfo->orderStability.push(OrderBy::StableOrder);
2858 parseInfo->orderStability.push(OrderBy::UnstableOrder);
2861 QuantifiedExpr: SomeQuantificationExpr /* [42] */
2862 | EveryQuantificationExpr
2864 SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle
2866 pushVariable($3, quantificationType($4), $6,
2867 VariableDeclaration::RangeVariable, @$, parseInfo);
2869 {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
2870 SomeQuantificationTail /* [X] */
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();
2878 SomeQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
2880 $<expr>$ = pushVariable($3, quantificationType($4), $6,
2881 VariableDeclaration::RangeVariable, @$, parseInfo);
2883 {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
2884 SomeQuantificationTail /* [X] */
2886 $$ = create(new QuantifiedExpression($<enums.slot>8,
2887 QuantifiedExpression::Some, $<expr>7, $9), @$, parseInfo);
2888 parseInfo->finalizePushedVariable();
2893 EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle
2895 pushVariable($3, quantificationType($4), $6,
2896 VariableDeclaration::RangeVariable, @$, parseInfo);
2898 {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
2899 EveryQuantificationTail /* [X] */
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();
2907 EveryQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
2909 $<expr>$ = pushVariable($3, quantificationType($4), $6,
2910 VariableDeclaration::RangeVariable, @$, parseInfo);
2912 {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
2913 EveryQuantificationTail /* [X] */
2915 $$ = create(new QuantifiedExpression($<enums.slot>8,
2916 QuantifiedExpression::Every, $<expr>7, $9), @$, parseInfo);
2917 parseInfo->finalizePushedVariable();
2922 SatisfiesClause: SATISFIES ExprSingle /* [X] */
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:
2933 * case element() return <!-- a comment -->
2934 * case $i as attribute(name) return name($i)
2935 * default return "Didn't match"
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"
2949 TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN
2951 parseInfo->typeswitchSource.push($3);
2953 CaseClause /* [43] */
2955 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
2956 parseInfo->typeswitchSource.pop();
2960 CaseClause: CASE CaseVariable SequenceType /* [44] */
2964 pushVariable($2, $3, parseInfo->typeswitchSource.top(),
2965 VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
2970 /* The variable shouldn't be in-scope for other case branches. */
2972 parseInfo->finalizePushedVariable();
2976 const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), $3), @$, parseInfo));
2977 $$ = create(new IfThenClause(instanceOf, $6, $8), @$, parseInfo);
2980 CaseTail: CaseClause /* [X] */
2983 CaseVariable: /* Empty. */ /* [X] */
2988 | DOLLAR ElementName AS
2993 CaseDefault: DEFAULT RETURN ExprSingle /* [X] */
2997 | DEFAULT DOLLAR ElementName
3001 pushVariable($3, parseInfo->typeswitchSource.top()->staticType(),
3002 parseInfo->typeswitchSource.top(),
3003 VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
3009 parseInfo->finalizePushedVariable();
3013 IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle /* [45] */
3015 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3016 $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
3019 OrExpr: AndExpr /* [46] */
3022 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3023 $$ = create(new OrExpression($1, $3), @$, parseInfo);
3026 AndExpr: ComparisonExpr /* [47] */
3027 | AndExpr AND ComparisonExpr
3029 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3030 $$ = create(new AndExpression($1, $3), @$, parseInfo);
3033 ComparisonExpr: RangeExpr /* [48] */
3038 RangeExpr: AdditiveExpr /* [49] */
3039 | AdditiveExpr TO AdditiveExpr
3041 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3042 $$ = create(new RangeExpression($1, $3), @$, parseInfo);
3045 AdditiveExpr: MultiplicativeExpr /* [50] */
3046 | AdditiveExpr AdditiveOperator MultiplicativeExpr
3048 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3049 $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
3052 AdditiveOperator: PLUS {$$ = AtomicMathematician::Add;} /* [X] */
3053 | MINUS {$$ = AtomicMathematician::Substract;}
3055 MultiplicativeExpr: UnionExpr /* [51] */
3056 | MultiplicativeExpr MultiplyOperator UnionExpr
3058 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3059 $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
3062 MultiplyOperator: STAR {$$ = AtomicMathematician::Multiply;} /* [X] */
3063 | DIV {$$ = AtomicMathematician::Div;}
3064 | IDIV {$$ = AtomicMathematician::IDiv;}
3065 | MOD {$$ = AtomicMathematician::Mod;}
3067 UnionExpr: IntersectExceptExpr /* [52] */
3068 | UnionExpr UnionOperator IntersectExceptExpr
3070 allowedIn(QueryLanguages(QXmlQuery::XQuery10
3071 | QXmlQuery::XPath20
3072 | QXmlQuery::XmlSchema11IdentityConstraintField
3073 | QXmlQuery::XmlSchema11IdentityConstraintSelector),
3075 $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
3078 IntersectExceptExpr: InstanceOfExpr /* [53] */
3079 | IntersectExceptExpr IntersectOperator InstanceOfExpr
3081 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3082 $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo);
3085 UnionOperator: UNION /* [X] */
3088 IntersectOperator: INTERSECT /* [X] */
3090 $$ = CombineNodes::Intersect;
3094 $$ = CombineNodes::Except;
3097 InstanceOfExpr: TreatExpr /* [54] */
3098 | TreatExpr INSTANCE OF SequenceType
3100 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3101 $$ = create(new InstanceOf($1,
3102 SequenceType::Ptr($4)), @$, parseInfo);
3105 TreatExpr: CastableExpr /* [55] */
3106 | CastableExpr TREAT AS SequenceType
3108 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3109 $$ = create(new TreatAs($1, $4), @$, parseInfo);
3112 CastableExpr: CastExpr /* [56] */
3113 | CastExpr CASTABLE AS SingleType
3115 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3116 $$ = create(new CastableAs($1, $4), @$, parseInfo);
3119 CastExpr: UnaryExpr /* [57] */
3120 | UnaryExpr CAST AS SingleType
3122 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3123 $$ = create(new CastAs($1, $4), @$, parseInfo);
3126 UnaryExpr: ValueExpr /* [58] */
3127 | UnaryOperator UnaryExpr
3129 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3130 $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo);
3133 UnaryOperator: PLUS /* [X] */
3135 $$ = AtomicMathematician::Add;
3139 $$ = AtomicMathematician::Substract;
3142 ValueExpr: ValidateExpr /* [59] */
3146 GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr /* [60] */
3148 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3149 $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo);
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;}
3159 ValueComp: RangeExpr ValueComparisonOperator RangeExpr /* [61] */
3161 $$ = create(new ValueComparison($1, $2, $3), @$, parseInfo);
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;}
3171 NodeComp: RangeExpr NodeOperator RangeExpr /* [62] */
3173 $$ = create(new NodeComparison($1, $2, $3), @$, parseInfo);
3176 NodeOperator: IS {$$ = QXmlNodeModelIndex::Is;} /* [X] */
3177 | PRECEDES {$$ = QXmlNodeModelIndex::Precedes;}
3178 | FOLLOWS {$$ = QXmlNodeModelIndex::Follows;}
3180 ValidateExpr: ValidationMode EnclosedExpr /* [63] */
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));
3188 $$ = Validate::create($2, $1, parseInfo->staticContext);
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;}
3198 ExtensionExpr: Pragmas EnclosedOptionalExpr /* [65] */
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. */
3208 parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
3209 "Therefore, a fallback expression "
3211 ReportContext::XQST0079, fromYYLTYPE(@$, parseInfo));
3215 EnclosedOptionalExpr: CURLY_LBRACE /* empty */ CURLY_RBRACE /* [X] */
3219 | CURLY_LBRACE Expr CURLY_RBRACE
3224 Pragmas: Pragmas Pragma /* [X] */
3227 Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END /* [66] */
3229 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
3232 PragmaContents: /* empty */ /* [67] */
3235 PathExpr: SLASH RelativePathExpr /* [68] */
3237 /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
3238 $$ = create(new Path(createRootExpression(parseInfo, @$), $2), @$, parseInfo);
3241 | SLASHSLASH RelativePathExpr
3243 $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
3247 /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
3248 $$ = createRootExpression(parseInfo, @$);
3252 /* This is "step", simply. We let bison generate "$$ = $1". */
3254 RelativePathExpr: StepExpr /* [69] */
3255 | RelativePathExpr MapOrSlash StepExpr
3257 $$ = create(new Path($1, $3, $2), @$, parseInfo);
3259 | RelativePathExpr MapOrSlash SORT MandatoryOrderByClause RETURN StepExpr END_SORT
3261 const Expression::Ptr orderBy(createReturnOrderBy($4, $6, parseInfo->orderStability.pop(), @$, parseInfo));
3263 ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
3264 const Expression::Ptr path(create(new Path($1, orderBy, $2), @$, parseInfo));
3266 $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), @$, parseInfo);
3268 | RelativePathExpr SLASHSLASH StepExpr
3270 $$ = createSlashSlashPath($1, $3, @$, parseInfo);
3273 StepExpr: FilteredAxisStep /* [70] */
3275 $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
3278 | CURRENT EnclosedExpr
3280 $$ = create(new CurrentItemStore($2), @$, parseInfo);
3284 const xsDouble version = $1.toDouble();
3286 parseInfo->isBackwardsCompat.push(version != 2);
3288 $<enums.Double>$ = version;
3292 if($<enums.Double>2 < 2)
3293 $$ = createCompatStore($3, @$, parseInfo);
3297 | BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE /* [X] */
3299 allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
3300 Q_ASSERT(!$2.isEmpty());
3301 $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
3304 | DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE /* [X] */
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);
3317 parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
3320 | CALL_TEMPLATE ElementName LPAREN TemplateWithParameters RPAREN
3322 $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
3323 parseInfo->templateWithParametersHandled();
3324 parseInfo->templateCalls.append($$);
3327 TemplateWithParameters:
3329 parseInfo->startParsingWithParam();
3333 parseInfo->endParsingWithParam();
3336 TemplateParameters: /* Empty. */ /* [X] */
3342 | TemplateParameters COMMA TemplateParameter
3346 OptionalTemplateParameters: /* Empty. */ /* [X] */
3349 | LPAREN TemplateParameters RPAREN
3353 TemplateParameter: IsTunnel DOLLAR VarName TypeDeclaration OptionalAssign
3355 /* Note, this grammar rule is invoked for @c xsl:param @em and @c
3356 * xsl:with-param. */
3357 const bool isParsingWithParam = parseInfo->isParsingWithParam();
3360 * @c xsl:param doesn't make life easy:
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.
3366 * Therefore, for that very common case we can't rely on
3367 * the Expression's type, but have to force it to item()*.
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.
3374 SequenceType::Ptr type;
3376 if(!$4->is(CommonSequenceTypes::ZeroOrMoreItems))
3379 Expression::Ptr expr;
3381 /* The default value is an empty sequence. */
3382 if(!$5 && ((type && $4->cardinality().allowsEmpty())
3383 || isParsingWithParam))
3384 expr = create(new EmptySequence, @$, parseInfo);
3388 /* We ensure we have some type, so CallTemplate, Template and friends
3390 if(!isParsingWithParam && !type)
3391 type = CommonSequenceTypes::ZeroOrMoreItems;
3394 /* TODO, handle tunnel parameters. */;
3397 if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, $3)) ||
3398 (isParsingWithParam && parseInfo->templateWithParams.contains($3)))
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));
3406 if(isParsingWithParam)
3407 parseInfo->templateWithParams[$3] = WithParam::Ptr(new WithParam($3, $4, expr));
3411 pushVariable($3, type, expr, VariableDeclaration::TemplateParameter, @$, parseInfo);
3412 parseInfo->templateParameters.append(parseInfo->variables.top());
3418 IsTunnel: /* Empty. */
3427 OptionalAssign: /* Empty. */ /* [X] */
3429 $$ = Expression::Ptr();
3437 * Controls whethers a path expression should sort its result. Used for
3438 * implementing XSL-T's for-each.
3440 MapOrSlash: SLASH /* [X] */
3442 $$ = Path::RegularPath;
3446 $$ = Path::XSLTForEach;
3448 | FOR_APPLY_TEMPLATE
3450 $$ = Path::ForApplyTemplate;
3453 FilteredAxisStep: AxisStep /* [X] */
3454 | FilteredAxisStep LBRACKET Expr RBRACKET
3456 $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@$, parseInfo)), @$, parseInfo);
3459 AxisStep: ForwardStep /* [71] */
3464 if($1 == QXmlNodeModelIndex::AxisAttribute)
3465 parseInfo->nodeTestSource = BuiltinTypes::attribute;
3467 NodeTestInAxisStep /* [72] */
3471 /* A node test was explicitly specified. The un-abbreviated syntax was used. */
3472 $$ = create(new AxisStep($1, $3), @$, parseInfo);
3476 /* Quote from 3.2.1.1 Axes
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. */
3484 if($1 == QXmlNodeModelIndex::AxisAttribute)
3485 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), @$, parseInfo);
3487 $$ = create(new AxisStep($1, BuiltinTypes::element), @$, parseInfo);
3490 parseInfo->restoreNodeTestSource();
3494 NodeTestInAxisStep: NodeTest
3497 Axis: AxisToken COLONCOLON /* [73] */
3499 if($1 == QXmlNodeModelIndex::AxisNamespace)
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));
3512 case QXmlNodeModelIndex::AxisAttribute:
3514 allowedIn(QueryLanguages( QXmlQuery::XPath20
3515 | QXmlQuery::XQuery10
3516 | QXmlQuery::XmlSchema11IdentityConstraintField
3517 | QXmlQuery::XSLT20),
3521 case QXmlNodeModelIndex::AxisChild:
3523 allowedIn(QueryLanguages( QXmlQuery::XPath20
3524 | QXmlQuery::XQuery10
3525 | QXmlQuery::XmlSchema11IdentityConstraintField
3526 | QXmlQuery::XmlSchema11IdentityConstraintSelector
3527 | QXmlQuery::XSLT20),
3533 allowedIn(QueryLanguages( QXmlQuery::XPath20
3534 | QXmlQuery::XQuery10
3535 | QXmlQuery::XSLT20),
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 ;}
3554 AbbrevForwardStep: AT_SIGN
3556 parseInfo->nodeTestSource = BuiltinTypes::attribute;
3560 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$);
3561 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo);
3563 parseInfo->restoreNodeTestSource();
3567 ItemType::Ptr nodeTest;
3569 if(parseInfo->isParsingPattern && *$1 == *BuiltinTypes::node)
3570 nodeTest = BuiltinTypes::xsltNodeTest;
3574 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), @$, parseInfo);
3578 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $1), @$, parseInfo);
3581 ReverseStep: AbbrevReverseStep /* [75] */
3583 AbbrevReverseStep: DOTDOT /* [77] */
3585 $$ = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo);
3588 NodeTest: NameTest /* [78] */
3591 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3594 NameTest: ElementName /* [79] */
3596 $$ = QNameTest::create(parseInfo->nodeTestSource, $1);
3600 WildCard: STAR /* [80] */
3602 $$ = parseInfo->nodeTestSource;
3606 const NamePool::Ptr np(parseInfo->staticContext->namePool());
3607 const ReflectYYLTYPE ryy(@$, parseInfo);
3609 const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix($1), parseInfo->staticContext, &ryy));
3611 $$ = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
3615 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3616 const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
3617 $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
3620 FilterExpr: PrimaryExpr /* [81] */
3621 | FilterExpr LBRACKET Expr RBRACKET
3623 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3624 $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo);
3627 PrimaryExpr: Literal /* [84] */
3634 | APPLY_TEMPLATE OptionalMode LPAREN TemplateWithParameters RPAREN
3636 $$ = create(new ApplyTemplate(parseInfo->modeFor($2),
3637 parseInfo->templateWithParams,
3638 parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
3639 StandardLocalNames::Default))),
3641 parseInfo->templateWithParametersHandled();
3644 Literal: NumericLiteral /* [85] */
3647 $$ = create(new Literal(AtomicString::fromValue($1)), @$, parseInfo);
3650 NumericLiteral: XPATH2_NUMBER /* [86] */
3652 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3653 $$ = createNumericLiteral<Double>($1, @$, parseInfo);
3657 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3658 $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
3661 VarRef: DOLLAR VarName /* [87] */
3663 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3664 $$ = resolveVariable($2, @$, parseInfo, false);
3667 VarName: NCNAME /* [88] */
3669 /* See: http://www.w3.org/TR/xpath20/#id-variables */
3670 $$ = parseInfo->staticContext->namePool()->allocateQName(QString(), $1);
3677 ParenthesizedExpr: LPAREN Expr RPAREN /* [89] */
3679 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3684 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
3685 $$ = create(new EmptySequence, @$, parseInfo);
3688 ContextItemExpr: DOT /* [90] */
3690 $$ = create(new ContextItem(), @$, parseInfo);
3693 OrderingExpr: OrderingMode EnclosedExpr /* [X] */
3698 FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN /* [93] */
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);
3705 const Expression::Ptr
3706 func(parseInfo->staticContext->
3707 functionSignatures()->createFunctionCall($1, $3, parseInfo->staticContext, &ryy));
3710 $$ = create(func, @$, parseInfo);
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));
3718 else /* It's a call to a function created with 'declare function'.*/
3720 $$ = create(new UserFunctionCallsite($1, $3.count()), @$, parseInfo);
3722 $$->setOperands($3);
3723 parseInfo->userFunctionCallsites.append($$);
3727 FunctionArguments: /* empty */ /* [X] */
3729 $$ = Expression::List();
3734 Expression::List list;
3739 | ExpressionSequence
3741 Constructor: DirectConstructor /* [94] */
3743 allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
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. */
3750 DirectConstructor: DirElemConstructor /* [95] */
3751 | DirCommentConstructor
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:
3759 * <element attribute="{prefix:nameTest}" xmlns:prefix="http://example.com/"/>
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.
3766 * This is solved as follows:
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>
3780 * Saxon does this in a similar way. Study net.sf.saxon.expr.QueryParser::parseDirectElementConstructor().
3782 * @see XQueryTokenizer::attributeAsRaw()
3784 DirElemConstructor: G_LT
3787 $<enums.tokenizerPosition>$ = parseInfo->tokenizer->commenceScanOnly();
3788 parseInfo->scanOnlyStack.push(true);
3791 /* This list contains name/string pairs. No embedded
3792 * expressions has been parsed. */
3796 ++parseInfo->elementConstructorDepth;
3797 Expression::List constructors;
3799 parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
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;
3807 /* Whether xmlns="" has been encountered. */
3808 bool hasDefaultDeclaration = false;
3810 /* For each attribute & namespace declaration, do: */
3811 for(int i = 0; i < len; ++i)
3813 QString strLocalName;
3816 XPathHelper::splitQName($4.at(i).first, strPrefix, strLocalName);
3817 const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
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);
3824 /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
3826 if(prefix == StandardPrefixes::xmlns ||
3827 (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
3829 if(localName == StandardPrefixes::xmlns)
3830 hasDefaultDeclaration = true;
3832 /* We have a namespace declaration. */
3834 const Expression::Ptr nsExpr($4.at(i).second);
3836 const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
3838 const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
3840 if(ns == StandardNamespaces::empty)
3842 if(localName != StandardPrefixes::xmlns)
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));
3849 else if(!AnyURI::isValid(strNamespace))
3851 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
3852 ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
3855 if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
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));
3862 if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
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));
3870 if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
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));
3880 if(localName == StandardPrefixes::xmlns)
3881 nb = QXmlName(ns, StandardLocalNames::empty);
3883 nb = QXmlName(ns, StandardLocalNames::empty, localName);
3885 if(usedDeclarations.contains(nb.prefix()))
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));
3893 usedDeclarations.insert(nb.prefix());
3895 /* If the user has bound the XML namespace correctly, we in either
3896 * case don't want to output it.
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)
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))
3908 constructors.append(create(new NamespaceConstructor(nb), @$, parseInfo));
3909 resolver->addBinding(nb);
3915 if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
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));
3923 parseInfo->staticContext->setNamespaceBindings(resolver);
3924 $<expressionList>$ = constructors;
3926 /* Resolve the name of the element, now that the namespace attributes are read. */
3928 const ReflectYYLTYPE ryy(@$, parseInfo);
3930 const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
3931 ReportContext::XPST0081,
3932 ReportContext::XPST0081>($2, parseInfo->staticContext, resolver, &ryy);
3933 parseInfo->tagStack.push(ele);
3936 parseInfo->tokenizer->resumeTokenizationFrom($<enums.tokenizerPosition>3);
3940 DirElemConstructorTail /* [96] */
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. */
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);
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)
3955 QString strLocalName;
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);
3962 if(prefix == StandardPrefixes::xmlns ||
3963 (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
3965 const Expression::ID id = $7.at(i).second->id();
3967 if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
3969 /* It's a namespace declaration, and we've already handled those above. */
3974 parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
3975 "use enclosed expressions."),
3976 ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
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(),
3988 if(declaredAttributes.contains(att))
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));
3996 declaredAttributes.insert(att);
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
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));
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);
4010 attributes.append(ctor);
4014 Expression::Ptr contentOp;
4016 if(attributes.isEmpty())
4020 attributes.append($8);
4021 contentOp = create(new ExpressionSequence(attributes), @$, parseInfo);
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);
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();
4033 --parseInfo->elementConstructorDepth;
4036 DirElemConstructorTail: QUICK_TAG_END
4038 $$ = create(new EmptySequence(), @$, parseInfo);
4040 | G_GT DirElemContent BEGIN_END_TAG ElementName G_GT
4042 if(!$4.isLexicallyEqual(parseInfo->tagStack.top()))
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));
4052 $$ = create(new EmptySequence(), @$, parseInfo);
4053 else if($2.size() == 1)
4056 $$ = create(new ExpressionSequence($2), @$, parseInfo);
4059 DirAttributeList: /* empty */ /* [97] */
4061 $$ = AttributeHolderVector();
4063 | DirAttributeList Attribute
4069 Attribute: LexicalName G_EQ DirAttributeValue /* [X] */
4071 $$ = qMakePair($1, $3);
4074 DirAttributeValue: QUOTE AttrValueContent QUOTE /* [98] */
4076 $$ = createDirAttributeValue($2, parseInfo, @$);
4079 | APOS AttrValueContent APOS
4081 $$ = createDirAttributeValue($2, parseInfo, @$);
4084 AttrValueContent: /* Empty. */ /* [X] */
4086 $$ = Expression::List();
4088 | EnclosedExpr AttrValueContent
4090 Expression::Ptr content($1);
4092 if(parseInfo->isBackwardsCompat.top())
4093 content = create(GenericPredicate::createFirstItem(content), @$, parseInfo);
4095 $2.prepend(createSimpleContent(content, @$, parseInfo));
4098 | StringLiteral AttrValueContent
4100 $2.prepend(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo));
4104 DirElemContent: /* empty */ /* [101] */
4106 $$ = Expression::List();
4107 parseInfo->isPreviousEnclosedExpr = false;
4109 | DirElemContent DirectConstructor
4113 parseInfo->isPreviousEnclosedExpr = false;
4115 | DirElemContent StringLiteral
4117 if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
4118 XPathHelper::isWhitespaceOnly($2))
4124 $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
4126 parseInfo->isPreviousEnclosedExpr = false;
4129 | DirElemContent NON_BOUNDARY_WS
4131 $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
4133 parseInfo->isPreviousEnclosedExpr = false;
4135 | DirElemContent EnclosedExpr
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.
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));
4146 parseInfo->isPreviousEnclosedExpr = true;
4148 $1.append(createCopyOf($2, parseInfo, @$));
4152 DirCommentConstructor: COMMENT_START COMMENT_CONTENT /* [103] */
4154 $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
4157 DirPIConstructor: PI_START PI_TARGET PI_CONTENT /* [105] */
4159 const ReflectYYLTYPE ryy(@$, parseInfo);
4160 NCNameConstructor::validateTargetName<StaticContext::Ptr,
4161 ReportContext::XPST0003,
4162 ReportContext::XPST0003>($2,
4163 parseInfo->staticContext, &ryy);
4165 $$ = create(new ProcessingInstructionConstructor(
4166 create(new Literal(AtomicString::fromValue($2)), @$, parseInfo),
4167 create(new Literal(AtomicString::fromValue($3)), @$, parseInfo)), @$, parseInfo);
4170 ComputedConstructor: CompDocConstructor /* [109] */
4171 | CompElemConstructor
4172 | CompAttrConstructor
4173 | CompTextConstructor
4174 | CompCommentConstructor
4176 | CompNamespaceConstructor
4178 CompDocConstructor: DOCUMENT IsInternal EnclosedExpr /* [110] */
4180 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
4182 $$ = create(new DocumentConstructor($3), @$, parseInfo);
4185 CompElemConstructor: ELEMENT IsInternal CompElementName
4187 /* This value is incremented before the action below is executed. */
4188 ++parseInfo->elementConstructorDepth;
4190 EnclosedOptionalExpr /* [111] */
4193 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
4195 Expression::Ptr effExpr;
4198 effExpr = createCopyOf($5, parseInfo, @$);
4200 effExpr = create(new EmptySequence(), @$, parseInfo);
4202 const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
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)
4208 Expression::List exprList;
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));
4215 exprList.append(effExpr);
4217 effExpr = create(new ExpressionSequence(exprList), @$, parseInfo);
4220 --parseInfo->elementConstructorDepth;
4221 $$ = create(new ElementConstructor($3, effExpr, parseInfo->isXSLT()), @$, parseInfo);
4224 IsInternal: /* Empty. */ /* [X] */
4233 CompAttrConstructor: ATTRIBUTE
4236 EnclosedOptionalExpr /* [113] */
4238 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
4240 const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo));
4243 $$ = create(new AttributeConstructor(name, createSimpleContent($4, @$, parseInfo)), @$, parseInfo);
4245 $$ = create(new AttributeConstructor(name, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
4248 CompTextConstructor: TEXT IsInternal EnclosedExpr /* [114] */
4250 $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
4253 CompCommentConstructor: COMMENT IsInternal EnclosedExpr /* [115] */
4255 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
4257 $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
4260 CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr /* [116] */
4262 allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
4266 $$ = create(new ProcessingInstructionConstructor($2, createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
4269 $$ = create(new ProcessingInstructionConstructor($2, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
4272 CompAttributeName: {
4273 parseInfo->nodeTestSource = BuiltinTypes::attribute;
4277 parseInfo->restoreNodeTestSource();
4280 $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $2))), @$, parseInfo);
4284 CompElementName: ElementName /* [X] */
4286 $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $1))), @$, parseInfo);
4290 CompNameExpr: EnclosedExpr
4292 if(BuiltinTypes::xsQName->xdtTypeMatches($1->staticType()->itemType()))
4296 $$ = create(new QNameConstructor($1,
4297 parseInfo->staticContext->namespaceBindings()),
4303 * We always create an NCNameConstructor here. If will be rewritten away if not needed.
4307 $$ = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo)), @$, parseInfo);
4311 $$ = create(new NCNameConstructor($1), @$, parseInfo);
4315 * This expression is used for implementing XSL-T 2.0's xsl:namespace
4318 CompNamespaceConstructor: NAMESPACE EnclosedExpr EnclosedExpr /* [X] */
4320 $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
4323 SingleType: AtomicType /* [117] */
4325 $$ = makeGenericSequenceType($1, Cardinality::exactlyOne());
4327 | AtomicType QUESTION
4329 $$ = makeGenericSequenceType($1, Cardinality::zeroOrOne());
4332 TypeDeclaration: /* empty */ /* [118] */
4334 $$ = CommonSequenceTypes::ZeroOrMoreItems;
4341 SequenceType: ItemType OccurrenceIndicator /* [119] */
4343 $$ = makeGenericSequenceType($1, $2);
4346 | EMPTY_SEQUENCE EmptyParanteses
4348 $$ = CommonSequenceTypes::Empty;
4351 OccurrenceIndicator: /* empty */ {$$ = Cardinality::exactlyOne();} /* [120] */
4352 | PLUS {$$ = Cardinality::oneOrMore();}
4353 | STAR {$$ = Cardinality::zeroOrMore();}
4354 | QUESTION {$$ = Cardinality::zeroOrOne();}
4356 ItemType: AtomicType /* [121] */
4359 | ITEM EmptyParanteses
4361 $$ = BuiltinTypes::item;
4364 AtomicType: ElementName /* [122] */
4366 const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($1));
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));
4373 else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
4374 $$ = AtomicType::Ptr(t);
4377 /* Try to give an intelligent message. */
4378 if(t->isComplexType())
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));
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));
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] */
4408 AnyKindTest: NODE EmptyParanteses /* [124] */
4410 $$ = BuiltinTypes::node;
4413 DocumentTest: DOCUMENT_NODE EmptyParanteses /* [125] */
4415 $$ = BuiltinTypes::document;
4418 | DOCUMENT_NODE LPAREN AnyElementTest RPAREN
4420 // TODO support for document element testing
4421 $$ = BuiltinTypes::document;
4424 AnyElementTest: ElementTest /* [X] */
4427 TextTest: TEXT EmptyParanteses /* [126] */
4429 $$ = BuiltinTypes::text;
4432 CommentTest: COMMENT EmptyParanteses /* [127] */
4434 $$ = BuiltinTypes::comment;
4437 PITest: PROCESSING_INSTRUCTION EmptyParanteses /* [128] */
4439 $$ = BuiltinTypes::pi;
4442 | PROCESSING_INSTRUCTION LPAREN NCNAME RPAREN
4444 $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
4447 | PROCESSING_INSTRUCTION LPAREN StringLiteral RPAREN
4449 if(QXmlUtils::isNCName($3))
4451 $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
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));
4463 AnyAttributeTest: AttributeTest
4464 | SchemaAttributeTest
4466 AttributeTest: ATTRIBUTE EmptyParanteses /* [129] */
4468 $$ = BuiltinTypes::attribute;
4471 | ATTRIBUTE LPAREN STAR RPAREN
4473 $$ = BuiltinTypes::attribute;
4476 | ATTRIBUTE LPAREN AttributeName RPAREN
4478 $$ = QNameTest::create(BuiltinTypes::attribute, $3);
4480 | ATTRIBUTE LPAREN AttributeName COMMA TypeName RPAREN
4482 const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
4485 $$ = BuiltinTypes::attribute;
4488 parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
4489 ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
4492 | ATTRIBUTE LPAREN STAR COMMA TypeName RPAREN
4494 const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
4497 $$ = BuiltinTypes::attribute;
4500 parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
4501 ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
4505 SchemaAttributeTest: SCHEMA_ATTRIBUTE LPAREN ElementName RPAREN /* [131] */
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));
4515 ElementTest: ELEMENT EmptyParanteses /* [133] */
4517 $$ = BuiltinTypes::element;
4520 | ELEMENT LPAREN STAR RPAREN
4522 $$ = BuiltinTypes::element;
4525 | ELEMENT LPAREN ElementName RPAREN
4527 $$ = QNameTest::create(BuiltinTypes::element, $3);
4530 | ELEMENT LPAREN ElementName COMMA TypeName OptionalQuestionMark RPAREN
4532 const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
4535 $$ = BuiltinTypes::element;
4538 parseInfo->staticContext->error(unknownType()
4539 .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
4540 ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
4544 | ELEMENT LPAREN STAR COMMA TypeName OptionalQuestionMark RPAREN
4546 const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
4549 $$ = BuiltinTypes::element;
4552 parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
4553 .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
4554 ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
4558 OptionalQuestionMark: /* Empty. */
4561 SchemaElementTest: SCHEMA_ELEMENT LPAREN ElementName RPAREN /* [135] */
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));
4571 EmptyParanteses: LPAREN RPAREN /* [X] */
4573 AttributeName: NCNAME /* [137] */
4575 $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
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.
4585 ElementName: NCNAME /* [138] */
4587 if(parseInfo->nodeTestSource == BuiltinTypes::element)
4588 $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), $1);
4590 $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
4594 TypeName: ElementName /* [139] */
4596 FunctionName: NCName /* [X] */
4601 $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
4603 | INTERNAL_NAME NCNAME
4605 $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
4611 PragmaName: NCNAME /* [X] */
4613 parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
4615 ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
4619 URILiteral: StringLiteral /* [140] */
4621 StringLiteral: STRING_LITERAL /* [144] */
4623 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
4625 | XPATH2_STRING_LITERAL
4627 allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
4630 QName: QNAME /* [154] */
4633 const ReflectYYLTYPE ryy(@$, parseInfo);
4635 $$ = QNameConstructor::
4636 expandQName<StaticContext::Ptr,
4637 ReportContext::XPST0081,
4638 ReportContext::XPST0081>($1, parseInfo->staticContext,
4639 parseInfo->staticContext->namespaceBindings(), &ryy);
4644 $$ = parseInfo->staticContext->namePool()->fromClarkName($1);
4649 QString Tokenizer::tokenToString(const Token &token)
4661 case STRING_LITERAL:
4662 return QLatin1Char('"') + token.value + QLatin1Char('"');
4665 const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
4667 /* Remove the quotes. */
4668 if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
4669 return raw.mid(1, raw.length() - 2);
4676 } /* namespace Patternist */
4680 // vim: et:ts=4:sw=4:sts=4:syntax=yacc