source: trunk/src/xmlpatterns/parser/querytransformparser.ypp@ 615

Last change on this file since 615 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 189.0 KB
RevLine 
[2]1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
[561]4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
[2]6**
7** This file is part of the QtXmlPatterns module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
[561]24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
[2]27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
[561]36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
[2]38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51
52%{
53/****************************************************************************
54**
55** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
[561]56** All rights reserved.
57** Contact: Nokia Corporation ([email protected])
[2]58**
59** This file is part of the QtXmlPatterns module of the Qt Toolkit.
60**
61** $QT_BEGIN_LICENSE:LGPL$
62** Commercial Usage
63** Licensees holding valid Qt Commercial licenses may use this file in
64** accordance with the Qt Commercial License Agreement provided with the
65** Software or, alternatively, in accordance with the terms contained in
66** a written agreement between you and Nokia.
67**
68** GNU Lesser General Public License Usage
69** Alternatively, this file may be used under the terms of the GNU Lesser
70** General Public License version 2.1 as published by the Free Software
71** Foundation and appearing in the file LICENSE.LGPL included in the
72** packaging of this file. Please review the following information to
73** ensure the GNU Lesser General Public License version 2.1 requirements
74** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
75**
[561]76** In addition, as a special exception, Nokia gives you certain additional
77** rights. These rights are described in the Nokia Qt LGPL Exception
78** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
[2]79**
80** GNU General Public License Usage
81** Alternatively, this file may be used under the terms of the GNU
82** General Public License version 3.0 as published by the Free Software
83** Foundation and appearing in the file LICENSE.GPL included in the
84** packaging of this file. Please review the following information to
85** ensure the GNU General Public License version 3.0 requirements will be
86** met: http://www.gnu.org/copyleft/gpl.html.
87**
[561]88** If you have questions regarding the use of this file, please contact
89** Nokia at [email protected].
[2]90** $QT_END_LICENSE$
91**
92****************************************************************************/
93
94//
95// W A R N I N G
96// -------------
97//
98// This file is not part of the Qt API. It exists purely as an
99// implementation detail. This header file may change from version to
100// version without notice, or even be removed.
101//
102// We mean it.
103
104#include <limits>
105
106#include <QUrl>
107
108#include "qabstractfloat_p.h"
109#include "qandexpression_p.h"
110#include "qanyuri_p.h"
111#include "qapplytemplate_p.h"
112#include "qargumentreference_p.h"
113#include "qarithmeticexpression_p.h"
114#include "qatomicstring_p.h"
115#include "qattributeconstructor_p.h"
116#include "qattributenamevalidator_p.h"
117#include "qaxisstep_p.h"
118#include "qbuiltintypes_p.h"
119#include "qcalltemplate_p.h"
120#include "qcastableas_p.h"
121#include "qcastas_p.h"
122#include "qcombinenodes_p.h"
123#include "qcommentconstructor_p.h"
124#include "qcommonnamespaces_p.h"
125#include "qcommonsequencetypes_p.h"
126#include "qcommonvalues_p.h"
127#include "qcomputednamespaceconstructor_p.h"
128#include "qcontextitem_p.h"
129#include "qcopyof_p.h"
130#include "qcurrentitemstore_p.h"
131#include "qdebug_p.h"
132#include "qdelegatingnamespaceresolver_p.h"
133#include "qdocumentconstructor_p.h"
134#include "qelementconstructor_p.h"
135#include "qemptysequence_p.h"
136#include "qemptysequencetype_p.h"
137#include "qevaluationcache_p.h"
138#include "qexpressionfactory_p.h"
139#include "qexpressionsequence_p.h"
140#include "qexpressionvariablereference_p.h"
141#include "qexternalvariablereference_p.h"
142#include "qforclause_p.h"
143#include "qfunctioncall_p.h"
144#include "qfunctionfactory_p.h"
145#include "qfunctionsignature_p.h"
146#include "qgeneralcomparison_p.h"
147#include "qgenericpredicate_p.h"
148#include "qgenericsequencetype_p.h"
149#include "qifthenclause_p.h"
150#include "qinstanceof_p.h"
151#include "qletclause_p.h"
152#include "qliteral_p.h"
153#include "qlocalnametest_p.h"
154#include "qnamespaceconstructor_p.h"
155#include "qnamespacenametest_p.h"
156#include "qncnameconstructor_p.h"
157#include "qnodecomparison_p.h"
158#include "qnodesort_p.h"
159#include "qorderby_p.h"
160#include "qorexpression_p.h"
161#include "qparsercontext_p.h"
162#include "qpath_p.h"
163#include "qpatternistlocale_p.h"
164#include "qpositionalvariablereference_p.h"
165#include "qprocessinginstructionconstructor_p.h"
166#include "qqnameconstructor_p.h"
167#include "qqnametest_p.h"
168#include "qqnamevalue_p.h"
169#include "qquantifiedexpression_p.h"
170#include "qrangeexpression_p.h"
171#include "qrangevariablereference_p.h"
172#include "qreturnorderby_p.h"
173#include "qschemanumeric_p.h"
174#include "qschematypefactory_p.h"
175#include "qsimplecontentconstructor_p.h"
176#include "qstaticbaseuristore_p.h"
177#include "qstaticcompatibilitystore_p.h"
178#include "qtemplateparameterreference_p.h"
179#include "qtemplate_p.h"
180#include "qtextnodeconstructor_p.h"
181#include "qtokenizer_p.h"
182#include "qtreatas_p.h"
183#include "qtypechecker_p.h"
184#include "qunaryexpression_p.h"
185#include "qunresolvedvariablereference_p.h"
186#include "quserfunctioncallsite_p.h"
187#include "qvaluecomparison_p.h"
188#include "qxpathhelper_p.h"
189#include "qxsltsimplecontentconstructor_p.h"
190
191/*
192 * The cpp generated with bison 2.1 wants to
193 * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
194 */
195#define YYMALLOC malloc
196#define YYFREE free
197
198QT_BEGIN_NAMESPACE
199
200/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
201 * undocumented reason. */
202namespace QPatternist
203{
204
205/**
206 * "Macro that you define with #define in the Bison declarations
207 * section to request verbose, specific error message strings when
208 * yyerror is called."
209 */
210#define YYERROR_VERBOSE 1
211
212#undef YYLTYPE_IS_TRIVIAL
213#define YYLTYPE_IS_TRIVIAL 0
214
215/* Suppresses `warning: "YYENABLE_NLS" is not defined`
216 * @c YYENABLE_NLS enables Bison internationalization, and we don't
217 * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
218 */
219#define YYENABLE_NLS 0
220
221static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
222 const ParserContext *const parseInfo)
223{
224 return QSourceLocation(parseInfo->tokenizer->queryURI(),
225 sourceLocator.first_line,
226 sourceLocator.first_column);
227}
228
229/**
[561]230 * @internal
231 * @relates QXmlQuery
232 */
233typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
234
235/**
[2]236 * @short Flags invalid expressions and declarations in the currently
237 * parsed language.
238 *
[561]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
[2]242 * languages. However, when dealing with each language individually, we
243 * regularly need to disallow some expressions, such as direct element
244 * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
245 *
246 * This is further complicated by that XSLTTokenizer sometimes generates code
247 * which is allowed in XQuery but not in XPath. For that reason the token
248 * INTERNAL is sometimes generated, which signals that an expression, for
249 * instance the @c let clause, should not be flagged as an error, because it's
250 * used for internal purposes.
251 *
[561]252 * Hence, this function is called from each expression and declaration with @p
253 * allowedLanguages stating what languages it is allowed in.
[2]254 *
255 * If @p isInternal is @c true, no error is raised. Otherwise, if the current
[561]256 * language is not in @p allowedLanguages, an error is raised.
[2]257 */
[561]258static void allowedIn(const QueryLanguages allowedLanguages,
259 const ParserContext *const parseInfo,
260 const YYLTYPE &sourceLocator,
261 const bool isInternal = false)
[2]262{
[561]263 /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
264 * and XSL-T is the language, it's ok. */
265 if(!isInternal &&
266 (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
[2]267 {
[561]268
269 QString langName;
270
271 switch(parseInfo->languageAccent)
272 {
273 case QXmlQuery::XPath20:
274 langName = QLatin1String("XPath 2.0");
275 break;
276 case QXmlQuery::XSLT20:
277 langName = QLatin1String("XSL-T 2.0");
278 break;
279 case QXmlQuery::XQuery10:
280 langName = QLatin1String("XQuery 1.0");
281 break;
282 case QXmlQuery::XmlSchema11IdentityConstraintSelector:
283 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
284 break;
285 case QXmlQuery::XmlSchema11IdentityConstraintField:
286 langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
287 break;
288 }
289
290 parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
291 "which is disallowed in the current language(%1).").arg(langName),
[2]292 ReportContext::XPST0003,
293 fromYYLTYPE(sourceLocator, parseInfo));
294
295 }
296}
297
298static inline bool isVariableReference(const Expression::ID id)
299{
300 return id == Expression::IDExpressionVariableReference
301 || id == Expression::IDRangeVariableReference
302 || id == Expression::IDArgumentReference;
303}
304
305class ReflectYYLTYPE : public SourceLocationReflection
306{
307public:
308 inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
309 const ParserContext *const pi) : m_sl(sourceLocator)
310 , m_parseInfo(pi)
311 {
312 }
313
314 virtual const SourceLocationReflection *actualReflection() const
315 {
316 return this;
317 }
318
319 virtual QSourceLocation sourceLocation() const
320 {
321 return fromYYLTYPE(m_sl, m_parseInfo);
322 }
323
324 virtual QString description() const
325 {
326 Q_ASSERT(false);
327 return QString();
328 }
329
330private:
331 const YYLTYPE &m_sl;
332 const ParserContext *const m_parseInfo;
333};
334
335/**
336 * @short Centralizes a translation string for the purpose of increasing consistency.
337 */
338static inline QString unknownType()
339{
340 return QtXmlPatterns::tr("%1 is an unknown schema type.");
341}
342
343static inline Expression::Ptr create(Expression *const expr,
344 const YYLTYPE &sourceLocator,
345 const ParserContext *const parseInfo)
346{
347 parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
348 return Expression::Ptr(expr);
349}
350
351static inline Template::Ptr create(Template *const expr,
352 const YYLTYPE &sourceLocator,
353 const ParserContext *const parseInfo)
354{
355 parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
356 return Template::Ptr(expr);
357}
358
359static inline Expression::Ptr create(const Expression::Ptr &expr,
360 const YYLTYPE &sourceLocator,
361 const ParserContext *const parseInfo)
362{
363 parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
364 return expr;
365}
366
367static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
368 const YYLTYPE &sourceLocator,
369 const ParserContext *const parseInfo)
370{
371 return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
372 sourceLocator,
373 parseInfo);
374}
375
376static void loadPattern(const Expression::Ptr &matchPattern,
377 TemplatePattern::Vector &ourPatterns,
378 const TemplatePattern::ID id,
379 const PatternPriority priority,
380 const Template::Ptr &temp)
381{
382 Q_ASSERT(temp);
383
384 const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
385
386 ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
387}
388
389static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
390 const SequenceType::Ptr &reqType,
391 const ParserContext *const parseInfo)
392{
393 return TypeChecker::applyFunctionConversion(body, reqType,
394 parseInfo->staticContext,
395 ReportContext::XTTE0505,