source: trunk/src/xmlpatterns/parser/qparsercontext_p.h@ 317

Last change on this file since 317 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 13.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
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**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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#ifndef Patternist_ParserContext_H
53#define Patternist_ParserContext_H
54
55#include <QFlags>
56#include <QSharedData>
57#include <QStack>
58#include <QStringList>
59#include <QtGlobal>
60#include <QXmlQuery>
61
62#include "qbuiltintypes_p.h"
63#include "qfunctionsignature_p.h"
64#include "qorderby_p.h"
65#include "qtemplatemode_p.h"
66#include "quserfunctioncallsite_p.h"
67#include "quserfunction_p.h"
68#include "qvariabledeclaration_p.h"
69
70QT_BEGIN_HEADER
71
72QT_BEGIN_NAMESPACE
73
74namespace QPatternist
75{
76 class Tokenizer;
77
78 /**
79 * @short Contains data used when parsing and tokenizing.
80 *
81 * When ExpressionFactory::create() is called, an instance of this class
82 * is passed to the scanner and parser. It holds all information that is
83 * needed to create the expression.
84 *
85 * @author Frans Englich <[email protected]>
86 */
87 class ParserContext : public QSharedData
88 {
89 public:
90 typedef QExplicitlySharedDataPointer<ParserContext> Ptr;
91
92 enum PrologDeclaration
93 {
94 BoundarySpaceDecl = 1,
95 DefaultCollationDecl = 2,
96 BaseURIDecl = 4,
97 ConstructionDecl = 8,
98 OrderingModeDecl = 16,
99 EmptyOrderDecl = 32,
100 CopyNamespacesDecl = 64,
101 DeclareDefaultElementNamespace = 128,
102 DeclareDefaultFunctionNamespace = 256
103 };
104
105 typedef QFlags<PrologDeclaration> PrologDeclarations;
106
107 /**
108 * Constructs a ParserContext instance.
109 *
110 * @param context the static context as defined in XPath. This contain
111 * namespace bindings, error handler, and other information necessary
112 * for creating an XPath expression.
113 * @param lang the particular XPath language sub-set that should be parsed
114 * @param tokenizer the Tokenizer to use.
115 * @see ExpressionFactory::LanguageAccent
116 */
117 ParserContext(const StaticContext::Ptr &context,
118 const QXmlQuery::QueryLanguage lang,
119 Tokenizer *const tokenizer);
120
121 /**
122 * @short Removes the recently pushed variables from
123 * scope. The amount of removed variables is @p amount.
124 *
125 * finalizePushedVariable() can be seen as popping the variable.
126 *
127 */
128 void finalizePushedVariable(const int amount = 1,
129 const bool shouldPop = true);
130
131 inline VariableSlotID allocatePositionalSlot()
132 {
133 ++m_positionSlot;
134 return m_positionSlot;
135 }
136
137 inline VariableSlotID allocateExpressionSlot()
138 {
139 const VariableSlotID retval = m_expressionSlot;
140 ++m_expressionSlot;
141 return retval;
142 }
143
144 inline VariableSlotID allocateGlobalVariableSlot()
145 {
146 ++m_globalVariableSlot;
147 return m_globalVariableSlot;
148 }
149
150 inline bool hasDeclaration(const PrologDeclaration decl) const
151 {
152 return m_prologDeclarations.testFlag(decl);
153 }
154
155 inline void registerDeclaration(const PrologDeclaration decl)
156 {
157 m_prologDeclarations |= decl;
158 }
159
160 /**
161 * The namespaces declared with <tt>declare namespace</tt>.
162 */
163 QStringList declaredPrefixes;
164
165 /**
166 * This is a temporary stack, used for keeping variables in scope,
167 * such as for function arguments & let clauses.
168 */
169 VariableDeclaration::Stack variables;
170
171 inline bool isXSLT() const
172 {
173 return languageAccent == QXmlQuery::XSLT20;
174 }
175
176 const StaticContext::Ptr staticContext;
177 /**
178 * We don't store a Tokenizer::Ptr here, because then we would get a
179 * circular referencing between ParserContext and XSLTTokenizer, and
180 * hence they would never destruct.
181 */
182 Tokenizer *const tokenizer;
183 const QXmlQuery::QueryLanguage languageAccent;
184
185 /**
186 * Only used in the case of XSL-T. Is the name of the initial template
187 * to call. If null, no name was provided, and regular template
188 * matching should be done.
189 */
190 QXmlName initialTemplateName;
191
192 /**
193 * Used when parsing direct element constructors. It is used
194 * for ensuring tags are well-balanced.
195 */
196 QStack<QXmlName> tagStack;
197
198 /**
199 * The actual expression, the Query. This member may be @c null,
200 * such as in the case of an XQuery library module.
201 */
202 Expression::Ptr queryBody;
203
204 /**
205 * The user functions declared in the prolog.
206 */
207 UserFunction::List userFunctions;
208
209 /**
210 * Contains all calls to user defined functions.
211 */
212 UserFunctionCallsite::List userFunctionCallsites;
213
214 /**
215 * All variables declared with <tt>declare variable</tt>.
216 */
217 VariableDeclaration::List declaredVariables;
218
219 inline VariableSlotID currentPositionSlot() const
220 {
221 return m_positionSlot;
222 }
223
224 inline VariableSlotID currentExpressionSlot() const
225 {
226 return m_expressionSlot;
227 }
228
229 inline void restoreNodeTestSource()
230 {
231 nodeTestSource = BuiltinTypes::element;
232 }
233
234 inline VariableSlotID allocateCacheSlot()
235 {
236 return ++m_evaluationCacheSlot;
237 }
238
239 inline VariableSlotID allocateCacheSlots(const int count)
240 {
241 const VariableSlotID retval = m_evaluationCacheSlot + 1;
242 m_evaluationCacheSlot += count + 1;
243 return retval;
244 }
245
246 ItemType::Ptr nodeTestSource;
247
248 QStack<Expression::Ptr> typeswitchSource;
249
250 /**
251 * The library module namespace set with <tt>declare module</tt>.
252 */
253 QXmlName::NamespaceCode moduleNamespace;
254
255 /**
256 * When a direct element constructor is processed, resolvers are
257 * created in order to carry the namespace declarations. In such case,
258 * the old resolver is pushed here.
259 */
260 QStack<NamespaceResolver::Ptr> resolvers;
261
262 /**
263 * This is used for handling the following obscene case:
264 *
265 * - <tt>\<e\>{1}{1}\<\/e\></tt> produce <tt>\<e\>11\</e\></tt>
266 * - <tt>\<e\>{1, 1}\<\/e\></tt> produce <tt>\<e\>1 1\</e\></tt>
267 *
268 * This boolean tracks whether the previous reduction inside element
269 * content was done with an enclosed expression.
270 */
271 bool isPreviousEnclosedExpr;
272
273 int elementConstructorDepth;
274
275 QStack<bool> scanOnlyStack;
276
277 QStack<OrderBy::Stability> orderStability;
278
279 /**
280 * Whether any prolog declaration that must occur after the first
281 * group has been encountered.
282 */
283 bool hasSecondPrologPart;
284
285 bool preserveNamespacesMode;
286 bool inheritNamespacesMode;
287
288 /**
289 * Contains all named templates. Since named templates
290 * can also have rules, each body may also be in templateRules.
291 */
292 QHash<QXmlName, Template::Ptr> namedTemplates;
293
294 /**
295 * All the @c xsl:call-template instructions that we have encountered.
296 */
297 QVector<Expression::Ptr> templateCalls;
298
299 /**
300 * If we're in XSL-T, and a variable reference is encountered
301 * which isn't in-scope, it's added to this hash since a global
302 * variable declaration may appear later on.
303 *
304 * We use a multi hash, since we can encounter several references to
305 * the same variable before it's declared.
306 */
307 QMultiHash<QXmlName, Expression::Ptr> unresolvedVariableReferences;
308
309 /**
310 *
311 * Contains the encountered template rules, as opposed
312 * to named templates.
313 *
314 * The key is the name of the template mode. If it's a default
315 * constructed value, it's the default mode.
316 *
317 * Since templates rules may also be named, each body may also be in
318 * namedTemplates.
319 *
320 * To be specific, the values are not the templates, the values are
321 * modes, and the TemplateMode contains the patterns and bodies.
322 */
323 QHash<QXmlName, TemplateMode::Ptr> templateRules;
324
325 /**
326 * @short Returns the TemplateMode for @p modeName or @c null if the
327 * mode being asked for is @c #current.
328 */
329 TemplateMode::Ptr modeFor(const QXmlName &modeName)
330 {
331 /* #current is not a mode, so it cannot contain templates. #current
332 * specifies how to look up templates wrt. mode. This check helps
333 * code that calls us, asking for the mode it needs to lookup in.
334 */
335 if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current))
336 return TemplateMode::Ptr();
337
338 TemplateMode::Ptr &mode = templateRules[modeName];
339
340 if(!mode)
341 mode = TemplateMode::Ptr(new TemplateMode(modeName));
342
343 Q_ASSERT(templateRules[modeName]);
344 return mode;
345 }
346
347 inline TemplatePattern::ID allocateTemplateID()
348 {
349 ++m_currentTemplateID;
350 return m_currentTemplateID;
351 }
352
353 /**
354 * The @c xsl:param appearing inside template.
355 */
356 VariableDeclaration::List templateParameters;
357
358 /**
359 * The @c xsl:with-param appearing in template calling instruction.
360 */
361 WithParam::Hash templateWithParams;
362
363 inline void templateParametersHandled()
364 {
365 finalizePushedVariable(templateParameters.count());
366 templateParameters.clear();
367 }
368
369 inline void templateWithParametersHandled()
370 {
371 templateWithParams.clear();
372 }
373
374 inline bool isParsingWithParam() const
375 {
376 return m_isParsingWithParam.top();
377 }
378
379 void startParsingWithParam()
380 {
381 m_isParsingWithParam.push(true);
382 }
383
384 void endParsingWithParam()
385 {
386 m_isParsingWithParam.pop();
387 }
388
389 /**
390 * This is used to deal with XSL-T's exception to the @c node() type,
391 * which doesn't match document nodes.
392 */
393 bool isParsingPattern;
394
395 ImportPrecedence currentImportPrecedence;
396
397 bool isFirstTemplate() const
398 {
399 return m_currentTemplateID == InitialTemplateID;
400 }
401
402 /**
403 * Whether we're processing XSL-T 1.0 code.
404 */
405 QStack<bool> isBackwardsCompat;
406
407 private:
408 enum
409 {
410 InitialTemplateID = -1
411 };
412
413 VariableSlotID m_evaluationCacheSlot;
414 VariableSlotID m_expressionSlot;
415 VariableSlotID m_positionSlot;
416 PrologDeclarations m_prologDeclarations;
417 VariableSlotID m_globalVariableSlot;
418 TemplatePattern::ID m_currentTemplateID;
419
420 /**
421 * The default is @c false. If we're not parsing @c xsl:with-param,
422 * hence parsing @c xsl:param, the value has changed.
423 */
424 QStack<bool> m_isParsingWithParam;
425 Q_DISABLE_COPY(ParserContext)
426 };
427}
428
429QT_END_NAMESPACE
430
431QT_END_HEADER
432
433#endif
Note: See TracBrowser for help on using the repository browser.