summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/parser/qparsercontext_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlpatterns/parser/qparsercontext_p.h')
-rw-r--r--src/xmlpatterns/parser/qparsercontext_p.h433
1 files changed, 433 insertions, 0 deletions
diff --git a/src/xmlpatterns/parser/qparsercontext_p.h b/src/xmlpatterns/parser/qparsercontext_p.h
new file mode 100644
index 0000000..6319db7
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext_p.h
@@ -0,0 +1,433 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ParserContext_H
+#define Patternist_ParserContext_H
+
+#include <QFlags>
+#include <QSharedData>
+#include <QStack>
+#include <QStringList>
+#include <QtGlobal>
+#include <QXmlQuery>
+
+#include "qbuiltintypes_p.h"
+#include "qfunctionsignature_p.h"
+#include "qorderby_p.h"
+#include "qtemplatemode_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "quserfunction_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class Tokenizer;
+
+ /**
+ * @short Contains data used when parsing and tokenizing.
+ *
+ * When ExpressionFactory::create() is called, an instance of this class
+ * is passed to the scanner and parser. It holds all information that is
+ * needed to create the expression.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ParserContext : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ParserContext> Ptr;
+
+ enum PrologDeclaration
+ {
+ BoundarySpaceDecl = 1,
+ DefaultCollationDecl = 2,
+ BaseURIDecl = 4,
+ ConstructionDecl = 8,
+ OrderingModeDecl = 16,
+ EmptyOrderDecl = 32,
+ CopyNamespacesDecl = 64,
+ DeclareDefaultElementNamespace = 128,
+ DeclareDefaultFunctionNamespace = 256
+ };
+
+ typedef QFlags<PrologDeclaration> PrologDeclarations;
+
+ /**
+ * Constructs a ParserContext instance.
+ *
+ * @param context the static context as defined in XPath. This contain
+ * namespace bindings, error handler, and other information necessary
+ * for creating an XPath expression.
+ * @param lang the particular XPath language sub-set that should be parsed
+ * @param tokenizer the Tokenizer to use.
+ * @see ExpressionFactory::LanguageAccent
+ */
+ ParserContext(const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ Tokenizer *const tokenizer);
+
+ /**
+ * @short Removes the recently pushed variables from
+ * scope. The amount of removed variables is @p amount.
+ *
+ * finalizePushedVariable() can be seen as popping the variable.
+ *
+ */
+ void finalizePushedVariable(const int amount = 1,
+ const bool shouldPop = true);
+
+ inline VariableSlotID allocatePositionalSlot()
+ {
+ ++m_positionSlot;
+ return m_positionSlot;
+ }
+
+ inline VariableSlotID allocateExpressionSlot()
+ {
+ const VariableSlotID retval = m_expressionSlot;
+ ++m_expressionSlot;
+ return retval;
+ }
+
+ inline VariableSlotID allocateGlobalVariableSlot()
+ {
+ ++m_globalVariableSlot;
+ return m_globalVariableSlot;
+ }
+
+ inline bool hasDeclaration(const PrologDeclaration decl) const
+ {
+ return m_prologDeclarations.testFlag(decl);
+ }
+
+ inline void registerDeclaration(const PrologDeclaration decl)
+ {
+ m_prologDeclarations |= decl;
+ }
+
+ /**
+ * The namespaces declared with <tt>declare namespace</tt>.
+ */
+ QStringList declaredPrefixes;
+
+ /**
+ * This is a temporary stack, used for keeping variables in scope,
+ * such as for function arguments & let clauses.
+ */
+ VariableDeclaration::Stack variables;
+
+ inline bool isXSLT() const
+ {
+ return languageAccent == QXmlQuery::XSLT20;
+ }
+
+ const StaticContext::Ptr staticContext;
+ /**
+ * We don't store a Tokenizer::Ptr here, because then we would get a
+ * circular referencing between ParserContext and XSLTTokenizer, and
+ * hence they would never destruct.
+ */
+ Tokenizer *const tokenizer;
+ const QXmlQuery::QueryLanguage languageAccent;
+
+ /**
+ * Only used in the case of XSL-T. Is the name of the initial template
+ * to call. If null, no name was provided, and regular template
+ * matching should be done.
+ */
+ QXmlName initialTemplateName;
+
+ /**
+ * Used when parsing direct element constructors. It is used
+ * for ensuring tags are well-balanced.
+ */
+ QStack<QXmlName> tagStack;
+
+ /**
+ * The actual expression, the Query. This member may be @c null,
+ * such as in the case of an XQuery library module.
+ */
+ Expression::Ptr queryBody;
+
+ /**
+ * The user functions declared in the prolog.
+ */
+ UserFunction::List userFunctions;
+
+ /**
+ * Contains all calls to user defined functions.
+ */
+ UserFunctionCallsite::List userFunctionCallsites;
+
+ /**
+ * All variables declared with <tt>declare variable</tt>.
+ */
+ VariableDeclaration::List declaredVariables;
+
+ inline VariableSlotID currentPositionSlot() const
+ {
+ return m_positionSlot;
+ }
+
+ inline VariableSlotID currentExpressionSlot() const
+ {
+ return m_expressionSlot;
+ }
+
+ inline void restoreNodeTestSource()
+ {
+ nodeTestSource = BuiltinTypes::element;
+ }
+
+ inline VariableSlotID allocateCacheSlot()
+ {
+ return ++m_evaluationCacheSlot;
+ }
+
+ inline VariableSlotID allocateCacheSlots(const int count)
+ {
+ const VariableSlotID retval = m_evaluationCacheSlot + 1;
+ m_evaluationCacheSlot += count + 1;
+ return retval;
+ }
+
+ ItemType::Ptr nodeTestSource;
+
+ QStack<Expression::Ptr> typeswitchSource;
+
+ /**
+ * The library module namespace set with <tt>declare module</tt>.
+ */
+ QXmlName::NamespaceCode moduleNamespace;
+
+ /**
+ * When a direct element constructor is processed, resolvers are
+ * created in order to carry the namespace declarations. In such case,
+ * the old resolver is pushed here.
+ */
+ QStack<NamespaceResolver::Ptr> resolvers;
+
+ /**
+ * This is used for handling the following obscene case:
+ *
+ * - <tt>\<e\>{1}{1}\<\/e\></tt> produce <tt>\<e\>11\</e\></tt>
+ * - <tt>\<e\>{1, 1}\<\/e\></tt> produce <tt>\<e\>1 1\</e\></tt>
+ *
+ * This boolean tracks whether the previous reduction inside element
+ * content was done with an enclosed expression.
+ */
+ bool isPreviousEnclosedExpr;
+
+ int elementConstructorDepth;
+
+ QStack<bool> scanOnlyStack;
+
+ QStack<OrderBy::Stability> orderStability;
+
+ /**
+ * Whether any prolog declaration that must occur after the first
+ * group has been encountered.
+ */
+ bool hasSecondPrologPart;
+
+ bool preserveNamespacesMode;
+ bool inheritNamespacesMode;
+
+ /**
+ * Contains all named templates. Since named templates
+ * can also have rules, each body may also be in templateRules.
+ */
+ QHash<QXmlName, Template::Ptr> namedTemplates;
+
+ /**
+ * All the @c xsl:call-template instructions that we have encountered.
+ */
+ QVector<Expression::Ptr> templateCalls;
+
+ /**
+ * If we're in XSL-T, and a variable reference is encountered
+ * which isn't in-scope, it's added to this hash since a global
+ * variable declaration may appear later on.
+ *
+ * We use a multi hash, since we can encounter several references to
+ * the same variable before it's declared.
+ */
+ QMultiHash<QXmlName, Expression::Ptr> unresolvedVariableReferences;
+
+ /**
+ *
+ * Contains the encountered template rules, as opposed
+ * to named templates.
+ *
+ * The key is the name of the template mode. If it's a default
+ * constructed value, it's the default mode.
+ *
+ * Since templates rules may also be named, each body may also be in
+ * namedTemplates.
+ *
+ * To be specific, the values are not the templates, the values are
+ * modes, and the TemplateMode contains the patterns and bodies.
+ */
+ QHash<QXmlName, TemplateMode::Ptr> templateRules;
+
+ /**
+ * @short Returns the TemplateMode for @p modeName or @c null if the
+ * mode being asked for is @c #current.
+ */
+ TemplateMode::Ptr modeFor(const QXmlName &modeName)
+ {
+ /* #current is not a mode, so it cannot contain templates. #current
+ * specifies how to look up templates wrt. mode. This check helps
+ * code that calls us, asking for the mode it needs to lookup in.
+ */
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current))
+ return TemplateMode::Ptr();
+
+ TemplateMode::Ptr &mode = templateRules[modeName];
+
+ if(!mode)
+ mode = TemplateMode::Ptr(new TemplateMode(modeName));
+
+ Q_ASSERT(templateRules[modeName]);
+ return mode;
+ }
+
+ inline TemplatePattern::ID allocateTemplateID()
+ {
+ ++m_currentTemplateID;
+ return m_currentTemplateID;
+ }
+
+ /**
+ * The @c xsl:param appearing inside template.
+ */
+ VariableDeclaration::List templateParameters;
+
+ /**
+ * The @c xsl:with-param appearing in template calling instruction.
+ */
+ WithParam::Hash templateWithParams;
+
+ inline void templateParametersHandled()
+ {
+ finalizePushedVariable(templateParameters.count());
+ templateParameters.clear();
+ }
+
+ inline void templateWithParametersHandled()
+ {
+ templateWithParams.clear();
+ }
+
+ inline bool isParsingWithParam() const
+ {
+ return m_isParsingWithParam.top();
+ }
+
+ void startParsingWithParam()
+ {
+ m_isParsingWithParam.push(true);
+ }
+
+ void endParsingWithParam()
+ {
+ m_isParsingWithParam.pop();
+ }
+
+ /**
+ * This is used to deal with XSL-T's exception to the @c node() type,
+ * which doesn't match document nodes.
+ */
+ bool isParsingPattern;
+
+ ImportPrecedence currentImportPrecedence;
+
+ bool isFirstTemplate() const
+ {
+ return m_currentTemplateID == InitialTemplateID;
+ }
+
+ /**
+ * Whether we're processing XSL-T 1.0 code.
+ */
+ QStack<bool> isBackwardsCompat;
+
+ private:
+ enum
+ {
+ InitialTemplateID = -1
+ };
+
+ VariableSlotID m_evaluationCacheSlot;
+ VariableSlotID m_expressionSlot;
+ VariableSlotID m_positionSlot;
+ PrologDeclarations m_prologDeclarations;
+ VariableSlotID m_globalVariableSlot;
+ TemplatePattern::ID m_currentTemplateID;
+
+ /**
+ * The default is @c false. If we're not parsing @c xsl:with-param,
+ * hence parsing @c xsl:param, the value has changed.
+ */
+ QStack<bool> m_isParsingWithParam;
+ Q_DISABLE_COPY(ParserContext)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif