summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/parser
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commite1b2c9deb5943faae2b29be6a5c006f75bb73f06 (patch)
treefc79e45367c0a8fc71185e9afc33f7503a58653c /src/xmlpatterns/parser
downloadqtxmlpatterns-e1b2c9deb5943faae2b29be6a5c006f75bb73f06.tar.gz
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/xmlpatterns/parser')
-rw-r--r--src/xmlpatterns/parser/.gitattributes4
-rw-r--r--src/xmlpatterns/parser/.gitignore1
-rw-r--r--src/xmlpatterns/parser/TokenLookup.gperf223
-rwxr-xr-xsrc/xmlpatterns/parser/createParser.sh55
-rwxr-xr-xsrc/xmlpatterns/parser/createTokenLookup.sh91
-rwxr-xr-xsrc/xmlpatterns/parser/createXSLTTokenLookup.sh44
-rw-r--r--src/xmlpatterns/parser/parser.pri19
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader.cpp274
-rw-r--r--src/xmlpatterns/parser/qmaintainingreader_p.h234
-rw-r--r--src/xmlpatterns/parser/qparsercontext.cpp100
-rw-r--r--src/xmlpatterns/parser/qparsercontext_p.h433
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser.cpp8035
-rw-r--r--src/xmlpatterns/parser/qquerytransformparser_p.h338
-rw-r--r--src/xmlpatterns/parser/qtokenizer_p.h216
-rw-r--r--src/xmlpatterns/parser/qtokenlookup.cpp444
-rw-r--r--src/xmlpatterns/parser/qtokenrevealer.cpp111
-rw-r--r--src/xmlpatterns/parser/qtokenrevealer_p.h97
-rw-r--r--src/xmlpatterns/parser/qtokensource.cpp53
-rw-r--r--src/xmlpatterns/parser/qtokensource_p.h169
-rw-r--r--src/xmlpatterns/parser/querytransformparser.ypp4680
-rw-r--r--src/xmlpatterns/parser/qxquerytokenizer.cpp2249
-rw-r--r--src/xmlpatterns/parser/qxquerytokenizer_p.h332
-rw-r--r--src/xmlpatterns/parser/qxslttokenizer.cpp2717
-rw-r--r--src/xmlpatterns/parser/qxslttokenizer_p.h481
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup.cpp3006
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup.xml167
-rw-r--r--src/xmlpatterns/parser/qxslttokenlookup_p.h213
-rw-r--r--src/xmlpatterns/parser/trolltechHeader.txt51
-rw-r--r--src/xmlpatterns/parser/winCEWorkaround.sed32
29 files changed, 24869 insertions, 0 deletions
diff --git a/src/xmlpatterns/parser/.gitattributes b/src/xmlpatterns/parser/.gitattributes
new file mode 100644
index 0000000..61b39a8
--- /dev/null
+++ b/src/xmlpatterns/parser/.gitattributes
@@ -0,0 +1,4 @@
+qquerytransformparser.cpp -diff Unset
+qquerytransformparser_p.h -diff Unset
+qxslttokenlookup.cpp -diff Unset
+qxslttokenlookup_p.h -diff Unset
diff --git a/src/xmlpatterns/parser/.gitignore b/src/xmlpatterns/parser/.gitignore
new file mode 100644
index 0000000..615637a
--- /dev/null
+++ b/src/xmlpatterns/parser/.gitignore
@@ -0,0 +1 @@
+qquerytransformparser.output
diff --git a/src/xmlpatterns/parser/TokenLookup.gperf b/src/xmlpatterns/parser/TokenLookup.gperf
new file mode 100644
index 0000000..491e925
--- /dev/null
+++ b/src/xmlpatterns/parser/TokenLookup.gperf
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/**
+ * @file qtokenlookup.cpp
+ * @short This file is generated from TokenLookup.gperf and contains
+ * TokenLookup, a class housing a perfect hash function class for XQuery's keywords.
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+
+/**
+ * @class QPatternist::TokenLookup
+ * @short Contains a perfect hash function for XQuery's keywords.
+ */
+
+/**
+ * @fn QPatternist::TokenLookup::value(const QString &keyword)
+ * Looks up @p keyword and returns a pointer to the corresponding value.
+ *
+ * If @p keyword is not contained in the hash, a null pointer is returned.
+ */
+
+/**
+ * @file
+ * @short This file is the @c gperf declaration for generating TokenLookup.cpp.
+ *
+ * You generate TokenLookup.cpp by running:
+ *
+ * @code
+ * gperf TokenLookup.gperf --output-file=../src/parser/TokenLookup.cpp
+ * @endcode
+ *
+ * @c gperf generates a perfect hash function, which the tokenizer, src/parser/qxquerytokenizer.cpp,
+ * uses for looking up XQuery keywords.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Perfect_hash_function">Perfect hash function, Wikipedia</a>
+ * @see <a href="http://www.gnu.org/software/gperf/manual/gperf.html">Perfect Hash Function Generator</a>
+ */
+
+%language=C++
+
+/* Declare data const such that the compiler can put them
+ * in the read-only section. */
+%readonly-tables
+
+/* Yes, for crisps sake, we want enums instead of macros. */
+%enum
+
+/* Rename in_word_set to value, such that it's more
+ * like QHash::value(). */
+%define lookup-function-name value
+
+/* Rename Perfect_Hash to TokenLookup. More Qt/Patternist'ish. */
+%define class-name TokenLookup
+
+/* Output initializers for the TokenMap struct. Note the lack
+ * of a space between the comma and ERROR. Anything else is
+ * a syntax error to gperf. Rocket science. */
+%define initializer-suffix ,ERROR
+
+%struct-type
+
+struct TokenMap
+{
+ const char *name;
+ const Tokenizer::TokenType token;
+}
+
+%{
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+%}
+
+/* The strings below are in UTF-16 encoding. Subsequently, each ASCII
+ * character is stored as the ASCII character, followed by a null byte.
+ * Sorted alphabetically. */
+%%
+"ancestor", ANCESTOR
+"ancestor-or-self", ANCESTOR_OR_SELF
+"and", AND
+"as", AS
+"ascending", ASCENDING
+"assign", ASSIGN
+"at", AT
+"attribute", ATTRIBUTE
+"base-uri", BASEURI
+"boundary-space", BOUNDARY_SPACE
+"by", BY
+"case", CASE
+"castable", CASTABLE
+"cast", CAST
+"child", CHILD
+"collation", COLLATION
+"comment", COMMENT
+"construction", CONSTRUCTION
+"copy-namespaces", COPY_NAMESPACES
+"declare", DECLARE
+"default", DEFAULT
+"descendant", DESCENDANT
+"descendant-or-self", DESCENDANT_OR_SELF
+"descending", DESCENDING
+"div", DIV
+"document", DOCUMENT
+"document-node", DOCUMENT_NODE
+"element", ELEMENT
+"else", ELSE
+"empty", EMPTY
+"empty-sequence", EMPTY_SEQUENCE
+"encoding", ENCODING
+"eq", EQ
+"every", EVERY
+"except", EXCEPT
+"external", EXTERNAL
+"following", FOLLOWING
+"following-sibling", FOLLOWING_SIBLING
+"follows", FOLLOWS
+"for", FOR
+"function", FUNCTION
+"ge", GE
+"greatest", GREATEST
+"gt", GT
+"idiv", IDIV
+"if", IF
+"import", IMPORT
+"inherit", INHERIT
+"in", IN
+"instance", INSTANCE
+"intersect", INTERSECT
+"is", IS
+"item", ITEM
+"lax", LAX
+"least", LEAST
+"le", LE
+"let", LET
+"lt", LT
+"mod", MOD
+"module", MODULE
+"namespace", NAMESPACE
+"ne", NE
+"node", NODE
+"no-inherit", NO_INHERIT
+"no-preserve", NO_PRESERVE
+"of", OF
+"option", OPTION
+"ordered", ORDERED
+"ordering", ORDERING
+"order", ORDER
+"or", OR
+"parent", PARENT
+"precedes", PRECEDES
+"preceding", PRECEDING
+"preceding-sibling", PRECEDING_SIBLING
+"preserve", PRESERVE
+"processing-instruction", PROCESSING_INSTRUCTION
+"return", RETURN
+"satisfies", SATISFIES
+"schema-attribute", SCHEMA_ATTRIBUTE
+"schema-element", SCHEMA_ELEMENT
+"schema", SCHEMA
+"self", SELF
+"some", SOME
+"stable", STABLE
+"strict", STRICT
+"strip", STRIP
+"text", TEXT
+"then", THEN
+"to", TO
+"treat", TREAT
+"typeswitch", TYPESWITCH
+"union", UNION
+"unordered", UNORDERED
+"validate", VALIDATE
+"variable", VARIABLE
+"version", VERSION
+"where", WHERE
+"xquery", XQUERY
+%%
+
+} /* Close the QPatternist namespace. */
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/createParser.sh b/src/xmlpatterns/parser/createParser.sh
new file mode 100755
index 0000000..5673abc
--- /dev/null
+++ b/src/xmlpatterns/parser/createParser.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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$
+##
+#############################################################################
+
+files="qquerytransformparser_p.h qquerytransformparser.cpp"
+
+#p4 revert $files
+#p4 edit $files
+bison --defines=qquerytransformparser_p.h querytransformparser.ypp
+
+addHeaderScript="1{h; r trolltechHeader.txt
+ D; }
+2{x; G; }"
+sed -i -e "$addHeaderScript" $files
+
+sed -i -f winCEWorkaround.sed qquerytransformparser_p.h
+#p4 revert -a $files
diff --git a/src/xmlpatterns/parser/createTokenLookup.sh b/src/xmlpatterns/parser/createTokenLookup.sh
new file mode 100755
index 0000000..6083732
--- /dev/null
+++ b/src/xmlpatterns/parser/createTokenLookup.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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$
+##
+#############################################################################
+
+outFile="qtokenlookup.cpp"
+
+license=`cat <<EOF
+/****************************************************************************
+**
+** 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\\$
+**
+****************************************************************************/
+EOF`
+echo "$license" > $outFile
+
+# Watch out, the --output option is not supported in the
+# gperf version that apt-get pulls in on Mac OS X.
+gperf TokenLookup.gperf >> $outFile
diff --git a/src/xmlpatterns/parser/createXSLTTokenLookup.sh b/src/xmlpatterns/parser/createXSLTTokenLookup.sh
new file mode 100755
index 0000000..a36d76f
--- /dev/null
+++ b/src/xmlpatterns/parser/createXSLTTokenLookup.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
+## Contact: Nokia Corporation (qt-info@nokia.com)
+##
+## This file is the build configuration utility 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$
+##
+#############################################################################
+
+xmllint --noout --schema ../qtokenautomaton/qtokenautomaton.xsd qxslttokenlookup.xml
+java net.sf.saxon.Transform -xsl:../qtokenautomaton/qautomaton2cpp.xsl qxslttokenlookup.xml
diff --git a/src/xmlpatterns/parser/parser.pri b/src/xmlpatterns/parser/parser.pri
new file mode 100644
index 0000000..6656290
--- /dev/null
+++ b/src/xmlpatterns/parser/parser.pri
@@ -0,0 +1,19 @@
+hpux-g++*:QMAKE_CXXFLAGS += -mbig-switch
+
+HEADERS += $$PWD/qparsercontext_p.h \
+ $$PWD/qmaintainingreader_p.h \
+ $$PWD/qquerytransformparser_p.h \
+ $$PWD/qtokenizer_p.h \
+ $$PWD/qtokenrevealer_p.h \
+ $$PWD/qtokensource_p.h \
+ $$PWD/qxquerytokenizer_p.h \
+ $$PWD/qxslttokenizer_p.h \
+ $$PWD/qxslttokenlookup_p.h
+
+SOURCES += $$PWD/qquerytransformparser.cpp \
+ $$PWD/qparsercontext.cpp \
+ $$PWD/qtokenrevealer.cpp \
+ $$PWD/qtokensource.cpp \
+ $$PWD/qxquerytokenizer.cpp \
+ $$PWD/qxslttokenizer.cpp \
+ $$PWD/qxslttokenlookup.cpp
diff --git a/src/xmlpatterns/parser/qmaintainingreader.cpp b/src/xmlpatterns/parser/qmaintainingreader.cpp
new file mode 100644
index 0000000..6798099
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcastingplatform_p.h.
+ * If you need includes in this file, put them in CasttingPlatform.h,
+ * outside of the namespace.
+ */
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+MaintainingReader<TokenLookupClass, LookupKey>::MaintainingReader(const typename ElementDescription<TokenLookupClass, LookupKey>::Hash &elementDescriptions,
+ const QSet<typename TokenLookupClass::NodeName> &standardAttributes,
+ const ReportContext::Ptr &context,
+ QIODevice *const queryDevice) : QXmlStreamReader(queryDevice)
+ , m_hasHandledStandardAttributes(false)
+ , m_context(context)
+ , m_elementDescriptions(elementDescriptions)
+ , m_standardAttributes(standardAttributes)
+{
+ Q_ASSERT(m_context);
+ Q_ASSERT(!m_elementDescriptions.isEmpty());
+
+ /* We start with stripping. */
+ m_stripWhitespace.push(true);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+MaintainingReader<TokenLookupClass, LookupKey>::~MaintainingReader()
+{
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QSourceLocation MaintainingReader<TokenLookupClass, LookupKey>::currentLocation() const
+{
+ return QSourceLocation(documentURI(),
+ lineNumber(),
+ columnNumber());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QXmlStreamReader::TokenType MaintainingReader<TokenLookupClass, LookupKey>::readNext()
+{
+ const TokenType retval = QXmlStreamReader::readNext();
+
+ switch(retval)
+ {
+ case StartElement:
+ {
+ m_currentElementName = TokenLookupClass::toToken(name());
+ m_currentAttributes = attributes();
+ m_hasHandledStandardAttributes = false;
+
+ if(!m_currentAttributes.hasAttribute(QLatin1String("xml:space")))
+ m_stripWhitespace.push(m_stripWhitespace.top());
+ break;
+ }
+ case EndElement:
+ m_currentElementName = TokenLookupClass::toToken(name());
+ m_stripWhitespace.pop();
+ break;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::isWhitespace() const
+{
+ return QXmlStreamReader::isWhitespace()
+ || XPathHelper::isWhitespaceOnly(text());
+}
+
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::error(const QString &message,
+ const ReportContext::ErrorCode code) const
+{
+ m_context->error(message, code, currentLocation());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::warning(const QString &message) const
+{
+ m_context->warning(message, currentLocation());
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+typename TokenLookupClass::NodeName MaintainingReader<TokenLookupClass, LookupKey>::currentElementName() const
+{
+ return m_currentElementName;
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+void MaintainingReader<TokenLookupClass, LookupKey>::validateElement(const LookupKey elementName) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(m_elementDescriptions.contains(elementName))
+ {
+ // QHash::value breaks in Metrowerks Compiler
+ const ElementDescription<TokenLookupClass, LookupKey> &desc = *m_elementDescriptions.find(elementName);
+ const int attCount = m_currentAttributes.count();
+
+ QSet<typename TokenLookupClass::NodeName> encounteredXSLTAtts;
+
+ for(int i = 0; i < attCount; ++i)
+ {
+ const QXmlStreamAttribute &attr = m_currentAttributes.at(i);
+ if(attr.namespaceUri().isEmpty())
+ {
+ const typename TokenLookupClass::NodeName attrName(TokenLookupClass::toToken(attr.name()));
+ encounteredXSLTAtts.insert(attrName);
+
+ if(!desc.requiredAttributes.contains(attrName) &&
+ !desc.optionalAttributes.contains(attrName) &&
+ !m_standardAttributes.contains(attrName) &&
+ !isAnyAttributeAllowed())
+ {
+ QString translationString;
+
+ QList<typename TokenLookupClass::NodeName> all(desc.requiredAttributes.toList() + desc.optionalAttributes.toList());
+ const int totalCount = all.count();
+ QStringList allowed;
+
+ for(int i = 0; i < totalCount; ++i)
+ allowed.append(QPatternist::formatKeyword(TokenLookupClass::toString(all.at(i))));
+
+ /* Note, we can't run toString() on attrName, because we're in this branch,
+ * the token lookup doesn't have the string(!).*/
+ const QString stringedName(attr.name().toString());
+
+ if(totalCount == 0)
+ {
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only the standard attributes can appear.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()));
+ }
+ else if(totalCount == 1)
+ {
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Only %3 is allowed, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.first());
+ }
+ else if(totalCount == 1)
+ {
+ /* Note, allowed has already had formatKeyword() applied. */
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, %4, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.first(),
+ allowed.last());
+ }
+ else
+ {
+ /* Note, allowed has already had formatKeyword() applied. */
+ translationString = QtXmlPatterns::tr("Attribute %1 cannot appear on the element %2. Allowed is %3, and the standard attributes.")
+ .arg(formatKeyword(stringedName),
+ formatKeyword(name()),
+ allowed.join(QLatin1String(", ")));
+ }
+
+ m_context->error(translationString,
+ ReportContext::XTSE0090,
+ currentLocation());
+ }
+ }
+ else if(attr.namespaceUri() == namespaceUri())
+ {
+ m_context->error(QtXmlPatterns::tr("XSL-T attributes on XSL-T elements must be in the null namespace, not in the XSL-T namespace which %1 is.")
+ .arg(formatKeyword(attr.name())),
+ ReportContext::XTSE0090,
+ currentLocation());
+ }
+ /* Else, attributes in other namespaces are allowed, continue. */
+ }
+
+ const QSet<typename TokenLookupClass::NodeName> requiredButMissing(QSet<typename TokenLookupClass::NodeName>(desc.requiredAttributes).subtract(encounteredXSLTAtts));
+
+ if(!requiredButMissing.isEmpty())
+ {
+ error(QtXmlPatterns::tr("The attribute %1 must appear on element %2.")
+ .arg(QPatternist::formatKeyword(TokenLookupClass::toString(*requiredButMissing.constBegin())),
+ formatKeyword(name())),
+ ReportContext::XTSE0010);
+ }
+ }
+ else
+ {
+ error(QtXmlPatterns::tr("The element with local name %1 does not exist in XSL-T.").arg(formatKeyword(name())),
+ ReportContext::XTSE0010);
+ }
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::hasAttribute(const QString &namespaceURI,
+ const QString &localName) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ return m_currentAttributes.hasAttribute(namespaceURI, localName);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+bool MaintainingReader<TokenLookupClass, LookupKey>::hasAttribute(const QString &localName) const
+{
+ return hasAttribute(QString(), localName);
+}
+
+template<typename TokenLookupClass,
+ typename LookupKey>
+QString MaintainingReader<TokenLookupClass, LookupKey>::readAttribute(const QString &localName,
+ const QString &namespaceURI) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ Q_ASSERT_X(m_currentAttributes.hasAttribute(namespaceURI, localName),
+ Q_FUNC_INFO,
+ "Validation must be done before this function is called.");
+
+ return m_currentAttributes.value(namespaceURI, localName).toString();
+}
+
diff --git a/src/xmlpatterns/parser/qmaintainingreader_p.h b/src/xmlpatterns/parser/qmaintainingreader_p.h
new file mode 100644
index 0000000..e1610bf
--- /dev/null
+++ b/src/xmlpatterns/parser/qmaintainingreader_p.h
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** 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_MaintainingReader_H
+#define Patternist_MaintainingReader_H
+
+#include <QSet>
+#include <QSourceLocation>
+#include <QStack>
+#include <QStringList>
+#include <QXmlStreamReader>
+
+#include "qxpathhelper_p.h"
+#include "qxslttokenlookup_p.h"
+
+class QUrl;
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A structure that lists the optional and required
+ * attributes of an element. Used with MaintainingReader.
+ *
+ * A constant source to misunderstandings is mixing up the order of
+ * arguments for functions that takes a local name and a namespace. Be wary
+ * of this.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ template<typename TokenLookupClass,
+ typename LookupKey = typename TokenLookupClass::NodeName>
+ class ElementDescription
+ {
+ public:
+ typedef QHash<LookupKey, ElementDescription<TokenLookupClass, LookupKey> > Hash;
+ QSet<typename TokenLookupClass::NodeName> requiredAttributes;
+ QSet<typename TokenLookupClass::NodeName> optionalAttributes;
+ };
+
+ /**
+ * @short Base class for tokenizers that reads XML formats. This is
+ * XSLTTokenizer, and the W3C XML Schema parser.
+ *
+ * MaintainingReader is intended for sub-classing.
+ *
+ * @tparam TokenLookupClass The name of the class that is generated by
+ * QTokenAutomaton and which supplies tokenizing tokens. For XSLTTokenizer,
+ * this is XSLTTokenLookup, for instance.
+ *
+ * @tparam LookupKey The type that is passed to validateElement() and is
+ * the key in ElementDescription. For the schema code, where elements have
+ * different interpretations depending on context, the lookup key is hence
+ * not equal element name.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @since 4.5
+ */
+ template<typename TokenLookupClass,
+ typename LookupKey = typename TokenLookupClass::NodeName>
+ class MaintainingReader : public QXmlStreamReader
+ , protected TokenLookupClass
+ {
+ protected:
+
+ MaintainingReader(const typename ElementDescription<TokenLookupClass, LookupKey>::Hash &elementDescriptions,
+ const QSet<typename TokenLookupClass::NodeName> &standardAttributes,
+ const ReportContext::Ptr &context,
+ QIODevice *const queryDevice);
+
+ virtual ~MaintainingReader();
+
+ TokenType readNext();
+
+ /**
+ * Returns the name of the current element.
+ */
+ inline typename TokenLookupClass::NodeName currentElementName() const;
+
+ /**
+ * @short Convenience function for calling ReportContext::error().
+ */
+ void error(const QString &message,
+ const ReportContext::ErrorCode code) const;
+
+ /**
+ * @short Convenience function for calling ReportContext::warning().
+ */
+ void warning(const QString &message) const;
+
+ /**
+ * @short Returns the location of the document that MaintainingReader
+ * is parsing. Used for error reporting
+ */
+ virtual QUrl documentURI() const = 0;
+
+ /**
+ * @short Returns @c true, if any attribute is allowed on the
+ * element currently being validated.
+ */
+ virtual bool isAnyAttributeAllowed() const = 0;
+
+ /**
+ * QXmlStreamReader::isWhitespace() returns true for whitespace that is
+ * not expressed as character references, while XSL-T operatates ontop
+ * of the XDM, which means we needs to return true for those too.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#data-model">4 Data Model</a>
+ */
+ bool isWhitespace() const;
+
+ /**
+ * This function is not merged with handleStandardAttributes() because
+ * handleStandardAttributes() needs to be called for all elements,
+ * while validateElement() only applies to XSL-T elements.
+ *
+ * @see handleStandardAttributes()
+ */
+ void validateElement(const LookupKey name) const;
+
+ QXmlStreamAttributes m_currentAttributes;
+
+ bool m_hasHandledStandardAttributes;
+
+ /**
+ * This stack mirrors the depth of elements in the parsed document. If
+ * no @c xml:space is present on the current element, MaintainingReader
+ * simply pushes the current top(). However, it never sets the value
+ * depending on @c xml:space's value.
+ */
+ QStack<bool> m_stripWhitespace;
+
+ /**
+ * @short Returns the value for attribute by name \a name.
+ *
+ * If it doesn't exist, an error is raised.
+ *
+ * It is assumed that m_reader's current state is
+ * QXmlStreamReader::StartElement.
+ */
+ QString readAttribute(const QString &localName,
+ const QString &namespaceURI = QString()) const;
+
+ /**
+ * @short Returns @c true if the current element has an attribute whose
+ * name is @p namespaceURI and local name is @p localName.
+ */
+ bool hasAttribute(const QString &namespaceURI, const QString &localName) const;
+
+ /**
+ * @short Returns @c true if the current element has an attribute whose
+ * local name is @p localName and namespace URI is null.
+ */
+ inline bool hasAttribute(const QString &localName) const;
+
+ private:
+ typename TokenLookupClass::NodeName m_currentElementName;
+
+ /**
+ * This member is private, see the error() and warning() functions in
+ * this class.
+ */
+ const ReportContext::Ptr m_context;
+
+ /**
+ * Returns the current location that QXmlStreamReader has.
+ */
+ inline QSourceLocation currentLocation() const;
+
+ const typename ElementDescription<TokenLookupClass, LookupKey>::Hash m_elementDescriptions;
+ const QSet<typename TokenLookupClass::NodeName> m_standardAttributes;
+ Q_DISABLE_COPY(MaintainingReader)
+ };
+
+#include "qmaintainingreader.cpp"
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/parser/qparsercontext.cpp b/src/xmlpatterns/parser/qparsercontext.cpp
new file mode 100644
index 0000000..22e6221
--- /dev/null
+++ b/src/xmlpatterns/parser/qparsercontext.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <QtGlobal>
+
+#include "qexpression_p.h"
+#include "qstaticcontext_p.h"
+#include "qtokenizer_p.h"
+
+#include "qparsercontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ParserContext::ParserContext(const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ Tokenizer *const tokener) : staticContext(context)
+ , tokenizer(tokener)
+ , languageAccent(lang)
+ , nodeTestSource(BuiltinTypes::element)
+ , moduleNamespace(StandardNamespaces::empty)
+ , isPreviousEnclosedExpr(false)
+ , elementConstructorDepth(0)
+ , hasSecondPrologPart(false)
+ , preserveNamespacesMode(true)
+ , inheritNamespacesMode(true)
+ , isParsingPattern(false)
+ , currentImportPrecedence(1)
+ , m_evaluationCacheSlot(-1)
+ , m_expressionSlot(0)
+ , m_positionSlot(-1)
+ , m_globalVariableSlot(-1)
+ , m_currentTemplateID(InitialTemplateID)
+{
+ resolvers.push(context->namespaceBindings());
+ Q_ASSERT(tokenizer);
+ Q_ASSERT(context);
+ m_isParsingWithParam.push(false);
+ isBackwardsCompat.push(false);
+}
+
+void ParserContext::finalizePushedVariable(const int amount,
+ const bool shouldPop)
+{
+ for(int i = 0; i < amount; ++i)
+ {
+ const VariableDeclaration::Ptr var(shouldPop ? variables.pop() : variables.top());
+ Q_ASSERT(var);
+
+ if(var->isUsed())
+ continue;
+ else
+ {
+ staticContext->warning(QtXmlPatterns::tr("The variable %1 is unused")
+ .arg(formatKeyword(var, staticContext->namePool())));
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
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
diff --git a/src/xmlpatterns/parser/qquerytransformparser.cpp b/src/xmlpatterns/parser/qquerytransformparser.cpp
new file mode 100644
index 0000000..4858e11
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser.cpp
@@ -0,0 +1,8035 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/* A Bison parser, made by GNU Bison 2.3a. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3a"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names. */
+#define yyparse XPathparse
+#define yylex XPathlex
+#define yyerror XPatherror
+#define yylval XPathlval
+#define yychar XPathchar
+#define yydebug XPathdebug
+#define yynerrs XPathnerrs
+#define yylloc XPathlloc
+
+/* Copy the first part of user declarations. */
+/* Line 164 of yacc.c. */
+#line 22 "querytransformparser.ypp"
+
+#include <limits>
+
+#include <QUrl>
+
+#include "qabstractfloat_p.h"
+#include "qandexpression_p.h"
+#include "qanyuri_p.h"
+#include "qapplytemplate_p.h"
+#include "qargumentreference_p.h"
+#include "qarithmeticexpression_p.h"
+#include "qatomicstring_p.h"
+#include "qattributeconstructor_p.h"
+#include "qattributenamevalidator_p.h"
+#include "qaxisstep_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcalltemplate_p.h"
+#include "qcastableas_p.h"
+#include "qcastas_p.h"
+#include "qcombinenodes_p.h"
+#include "qcommentconstructor_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qcomputednamespaceconstructor_p.h"
+#include "qcontextitem_p.h"
+#include "qcopyof_p.h"
+#include "qcurrentitemstore_p.h"
+#include "qdebug_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qdocumentconstructor_p.h"
+#include "qelementconstructor_p.h"
+#include "qemptysequence_p.h"
+#include "qemptysequencetype_p.h"
+#include "qevaluationcache_p.h"
+#include "qexpressionfactory_p.h"
+#include "qexpressionsequence_p.h"
+#include "qexpressionvariablereference_p.h"
+#include "qexternalvariablereference_p.h"
+#include "qforclause_p.h"
+#include "qfunctioncall_p.h"
+#include "qfunctionfactory_p.h"
+#include "qfunctionsignature_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qgenericpredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qifthenclause_p.h"
+#include "qinstanceof_p.h"
+#include "qletclause_p.h"
+#include "qliteral_p.h"
+#include "qlocalnametest_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnamespacenametest_p.h"
+#include "qncnameconstructor_p.h"
+#include "qnodecomparison_p.h"
+#include "qnodesort_p.h"
+#include "qorderby_p.h"
+#include "qorexpression_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qpatternistlocale_p.h"
+#include "qpositionalvariablereference_p.h"
+#include "qprocessinginstructionconstructor_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnametest_p.h"
+#include "qqnamevalue_p.h"
+#include "qquantifiedexpression_p.h"
+#include "qrangeexpression_p.h"
+#include "qrangevariablereference_p.h"
+#include "qreturnorderby_p.h"
+#include "qschemanumeric_p.h"
+#include "qschematypefactory_p.h"
+#include "qsimplecontentconstructor_p.h"
+#include "qstaticbaseuristore_p.h"
+#include "qstaticcompatibilitystore_p.h"
+#include "qtemplateparameterreference_p.h"
+#include "qtemplate_p.h"
+#include "qtextnodeconstructor_p.h"
+#include "qtokenizer_p.h"
+#include "qtreatas_p.h"
+#include "qtypechecker_p.h"
+#include "qunaryexpression_p.h"
+#include "qunresolvedvariablereference_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "qvaluecomparison_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsltsimplecontentconstructor_p.h"
+
+/*
+ * The cpp generated with bison 2.1 wants to
+ * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
+ */
+#define YYMALLOC malloc
+#define YYFREE free
+
+QT_BEGIN_NAMESPACE
+
+/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
+ * undocumented reason. */
+namespace QPatternist
+{
+
+/**
+ * "Macro that you define with #define in the Bison declarations
+ * section to request verbose, specific error message strings when
+ * yyerror is called."
+ */
+#define YYERROR_VERBOSE 1
+
+#undef YYLTYPE_IS_TRIVIAL
+#define YYLTYPE_IS_TRIVIAL 0
+
+/* Suppresses `warning: "YYENABLE_NLS" is not defined`
+ * @c YYENABLE_NLS enables Bison internationalization, and we don't
+ * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
+ */
+#define YYENABLE_NLS 0
+
+static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return QSourceLocation(parseInfo->tokenizer->queryURI(),
+ sourceLocator.first_line,
+ sourceLocator.first_column);
+}
+
+/**
+ * @internal
+ * @relates QXmlQuery
+ */
+typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
+
+/**
+ * @short Flags invalid expressions and declarations in the currently
+ * parsed language.
+ *
+ * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
+ * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
+ * identity constraints, it is the union of all the constructs in these
+ * languages. However, when dealing with each language individually, we
+ * regularly need to disallow some expressions, such as direct element
+ * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
+ *
+ * This is further complicated by that XSLTTokenizer sometimes generates code
+ * which is allowed in XQuery but not in XPath. For that reason the token
+ * INTERNAL is sometimes generated, which signals that an expression, for
+ * instance the @c let clause, should not be flagged as an error, because it's
+ * used for internal purposes.
+ *
+ * Hence, this function is called from each expression and declaration with @p
+ * allowedLanguages stating what languages it is allowed in.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not in @p allowedLanguages, an error is raised.
+ */
+static void allowedIn(const QueryLanguages allowedLanguages,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
+ * and XSL-T is the language, it's ok. */
+ if(!isInternal &&
+ (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
+ {
+
+ QString langName;
+
+ switch(parseInfo->languageAccent)
+ {
+ case QXmlQuery::XPath20:
+ langName = QLatin1String("XPath 2.0");
+ break;
+ case QXmlQuery::XSLT20:
+ langName = QLatin1String("XSL-T 2.0");
+ break;
+ case QXmlQuery::XQuery10:
+ langName = QLatin1String("XQuery 1.0");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintSelector:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintField:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
+ break;
+ }
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
+ "which is disallowed in the current language(%1).").arg(langName),
+ ReportContext::XPST0003,
+ fromYYLTYPE(sourceLocator, parseInfo));
+
+ }
+}
+
+static inline bool isVariableReference(const Expression::ID id)
+{
+ return id == Expression::IDExpressionVariableReference
+ || id == Expression::IDRangeVariableReference
+ || id == Expression::IDArgumentReference;
+}
+
+class ReflectYYLTYPE : public SourceLocationReflection
+{
+public:
+ inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const pi) : m_sl(sourceLocator)
+ , m_parseInfo(pi)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return this;
+ }
+
+ virtual QSourceLocation sourceLocation() const
+ {
+ return fromYYLTYPE(m_sl, m_parseInfo);
+ }
+
+ virtual QString description() const
+ {
+ Q_ASSERT(false);
+ return QString();
+ }
+
+private:
+ const YYLTYPE &m_sl;
+ const ParserContext *const m_parseInfo;
+};
+
+/**
+ * @short Centralizes a translation string for the purpose of increasing consistency.
+ */
+static inline QString unknownType()
+{
+ return QtXmlPatterns::tr("%1 is an unknown schema type.");
+}
+
+static inline Expression::Ptr create(Expression *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Expression::Ptr(expr);
+}
+
+static inline Template::Ptr create(Template *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Template::Ptr(expr);
+}
+
+static inline Expression::Ptr create(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
+ return expr;
+}
+
+static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
+ sourceLocator,
+ parseInfo);
+}
+
+static void loadPattern(const Expression::Ptr &matchPattern,
+ TemplatePattern::Vector &ourPatterns,
+ const TemplatePattern::ID id,
+ const PatternPriority priority,
+ const Template::Ptr &temp)
+{
+ Q_ASSERT(temp);
+
+ const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
+
+ ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
+}
+
+static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
+ const SequenceType::Ptr &reqType,
+ const ParserContext *const parseInfo)
+{
+ return TypeChecker::applyFunctionConversion(body, reqType,
+ parseInfo->staticContext,
+ ReportContext::XTTE0505,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
+}
+
+static void registerNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &body,
+ ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const Template::Ptr &temp)
+{
+ Template::Ptr &e = parseInfo->namedTemplates[name];
+
+ if(e)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A template with name %1 "
+ "has already been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(),
+ name)),
+ ReportContext::XTSE0660,
+ fromYYLTYPE(sourceLocator, parseInfo));
+ }
+ else
+ {
+ e = temp;
+ e->body = body;
+ }
+}
+
+/**
+ * @short Centralizes code for creating numeric literals.
+ */
+template<typename TNumberClass>
+Expression::Ptr createNumericLiteral(const QString &in,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Item num(TNumberClass::fromLexical(in));
+
+ if(num.template as<AtomicValue>()->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
+ .arg(formatData(in)),
+ ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
+ return Expression::Ptr(); /* Avoid compiler warning. */
+ }
+ else
+ return create(new Literal(num), sl, parseInfo);
+}
+
+/**
+ * @short The generated Bison parser calls this function when there is a parse error.
+ *
+ * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
+ * ReportContext::error() is called.
+ */
+static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
+{
+ Q_UNUSED(sourceLocator);
+ Q_ASSERT(parseInfo);
+
+ parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
+ return 1;
+}
+
+/**
+ * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
+ * as @c where and @c let inbetween. We need to continue through them. This function does that.
+ */
+static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
+{
+ Q_ASSERT(expr);
+
+ const Expression::ID id = expr->id();
+ if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
+ return locateReturnClause(expr->operands()[1]);
+ else if(id == Expression::IDReturnOrderBy)
+ return expr->as<ReturnOrderBy>();
+ else
+ return 0;
+}
+
+static inline bool isPredicate(const Expression::ID id)
+{
+ return id == Expression::IDGenericPredicate ||
+ id == Expression::IDFirstItemPredicate;
+}
+
+/**
+ * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
+ * through the predicates and returns the AxisStep.
+ */
+static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
+ const bool throughStructures = true)
+{
+ Q_ASSERT(expr);
+
+ if(!throughStructures)
+ return expr;
+
+ Expression *candidate = expr.data();
+ Expression::ID id = candidate->id();
+
+ while(isPredicate(id) || id == Expression::IDPath)
+ {
+ const Expression::List &children = candidate->operands();
+ if(children.isEmpty())
+ return Expression::Ptr();
+ else
+ {
+ candidate = children.first().data();
+ id = candidate->id();
+ }
+ }
+
+ if(id == Expression::IDEmptySequence)
+ return Expression::Ptr();
+ else
+ {
+ Q_ASSERT(candidate->is(Expression::IDAxisStep));
+ return Expression::Ptr(candidate);
+ }
+}
+
+static void changeToTopAxis(const Expression::Ptr &op)
+{
+ /* This axis must have been written away by now. */
+ Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
+
+ if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
+ op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
+}
+
+/**
+ * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
+ * into an equivalent XPath expression.
+ *
+ * Essentially, the following rewrite is done:
+ *
+ * <tt>
+ * axis1::test1(a)/axis2::test2(b)
+ * =>
+ * child-or-top::test2(b)[parent::test1(a)]
+ * </tt>
+ *
+ * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
+ * only the first step in a pattern, but since we're doing rewrites more radically,
+ * its line of reasoning cannot be followed.
+ *
+ * Keep in mind the rewrites that non-terminal PatternStep do.
+ *
+ * @see createIdPatternPath()
+ */
+static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandL(findAxisStep(operand1, false));
+
+ if(operandL->is(Expression::IDAxisStep))
+ operandL->as<AxisStep>()->setAxis(axis);
+ else
+ findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
+
+ return create(GenericPredicate::create(operand2, operandL,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Performs the same role as createPatternPath(), but is tailored
+ * for @c fn:key() and @c fn:id().
+ *
+ * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
+ * to be precise) and that poses a challenge to rewriting because what
+ * createPatternPath() is not possible to express, since the functions cannot be
+ * node tests. E.g, this rewrite is not possible:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::id-or-key]
+ * </tt>
+ *
+ * Our approach is to rewrite like this:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::node is id-or-key]
+ * </tt>
+ *
+ * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
+ * the right operand, and @p axis the target axis to rewrite to.
+ *
+ * @see createPatternPath()
+ */
+static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandR(findAxisStep(operand2));
+ Q_ASSERT(operandR);
+ changeToTopAxis(operandR);
+
+ const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
+ sl,
+ parseInfo));
+ const Expression::Ptr isComp(create(new NodeComparison(parentStep,
+ QXmlNodeModelIndex::Is,
+ operand1),
+ sl,
+ parseInfo));
+
+ return create(GenericPredicate::create(operandR, isComp,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Centralizes a translation message, for the
+ * purpose of consistency and modularization.
+ */
+static inline QString prologMessage(const char *const msg)
+{
+ Q_ASSERT(msg);
+ return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
+}
+
+/**
+ * @short Resolves against the static base URI and checks that @p collation
+ * is a supported Unicode Collation.
+ *
+ * "If a default collation declaration specifies a collation by a
+ * relative URI, that relative URI is resolved to an absolute
+ * URI using the base URI in the static context."
+ *
+ * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
+ */
+template<const ReportContext::ErrorCode errorCode>
+static QUrl resolveAndCheckCollation(const QString &collation,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
+
+ if(uri.isRelative())
+ uri = parseInfo->staticContext->baseURI().resolved(uri);
+
+ XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
+
+ return uri;
+}
+
+/* The Bison generated parser declares macros that aren't used
+ * so suppress the warnings by fake usage of them.
+ *
+ * We do the same for some more defines in the first action. */
+#if defined(YYLSP_NEEDED) \
+ || defined(YYBISON) \
+ || defined(YYBISON_VERSION) \
+ || defined(YYPURE) \
+ || defined(yydebug) \
+ || defined(YYSKELETON_NAME)
+#endif
+
+/**
+ * Wraps @p operand with a CopyOf in case it makes any difference.
+ *
+ * There is no need to wrap the return value in a call to create(), it's
+ * already done.
+ */
+static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
+ parseInfo->preserveNamespacesMode), sl, parseInfo);
+}
+
+static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
+ * <tt>fn:root(self::node()) treat as document-node()</tt>.
+ */
+static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
+
+ Expression::List args;
+ args.append(create(new ContextItem(), sl, parseInfo));
+
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
+ ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
+ Q_ASSERT(fnRoot);
+
+ return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
+}
+
+static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
+{
+#ifdef Patternist_DEBUG_PARSER
+ /**
+ * "External integer variable set to zero by default. If yydebug
+ * is given a nonzero value, the parser will output information on
+ * input symbols and parser action. See section Debugging Your Parser."
+ */
+# define YYDEBUG 1
+
+ extern int XPathdebug;
+ XPathdebug = 1;
+#endif
+
+ Q_ASSERT(parseInfo);
+
+ const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
+
+ (*lexVal).sval = tok.value;
+
+ return static_cast<int>(tok.type);
+}
+
+/**
+ * @short Creates a path expression which contains the step <tt>//</tt> between
+ * @p begin and and @p end.
+ *
+ * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
+ *
+ * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
+ */
+static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
+ const Expression::Ptr &end,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
+ const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));
+
+ return create(new Path(p1, end), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
+ */
+static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
+ const Expression::List &args,
+ const YYLTYPE &sourceLocator)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
+ const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
+
+ return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
+ sourceLocator, parseInfo);
+}
+
+static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator)
+{
+ if(content.isEmpty())
+ return create(new EmptySequence(), sourceLocator, parseInfo);
+ else if(content.size() == 1)
+ return content.first();
+ else
+ return createConcatFN(parseInfo, content, sourceLocator);
+}
+
+/**
+ * @short Checks for variable initialization circularity.
+ *
+ * "A recursive function that checks for recursion is full of ironies."
+ *
+ * -- The Salsa Master
+ *
+ * Issues an error via @p parseInfo's StaticContext if the initialization
+ * expression @p checkee for the global variable @p var, contains a variable
+ * reference to @p var. That is, if there's a circularity.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
+ * Query Language, err:XQST0054</a>
+ */
+static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
+ const Expression::Ptr &checkee,
+ const VariableDeclaration::Type type,
+ FunctionSignature::List &signList,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(var);
+ Q_ASSERT(checkee);
+ Q_ASSERT(parseInfo);
+
+ const Expression::ID id = checkee->id();
+
+ if(id == Expression::IDExpressionVariableReference)
+ {
+ const ExpressionVariableReference *const ref =
+ static_cast<const ExpressionVariableReference *>(checkee.data());
+
+ if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
+ "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
+ parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
+ return;
+ }
+ else
+ {
+ /* If the variable we're checking is below another variable, it can be a recursive
+ * dependency through functions, so we need to check variable references too. */
+ checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
+ return;
+ }
+ }
+ else if(id == Expression::IDUserFunctionCallsite)
+ {
+ const UserFunctionCallsite::Ptr callsite(checkee);
+ const FunctionSignature::Ptr sign(callsite->callTargetDescription());
+ const FunctionSignature::List::const_iterator end(signList.constEnd());
+ FunctionSignature::List::const_iterator it(signList.constBegin());
+ bool noMatch = true;
+
+ for(; it != end; ++it)
+ {
+ if(*it == sign)
+ {
+ /* The variable we're checking is depending on a function that's recursive. The
+ * user has written a weird query, in other words. Since it's the second time
+ * we've encountered a callsite, we now skip it. */
+ noMatch = false;
+ break;
+ }
+ }
+
+ if(noMatch)
+ {
+ signList.append(sign);
+ /* Check the body of the function being called. */
+ checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
+ }
+ /* Continue with the operands, such that we also check the arguments of the callsite. */
+ }
+ else if(id == Expression::IDUnresolvedVariableReference)
+ {
+ /* We're called before it has rewritten itself. */
+ checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
+ }
+
+ /* Check the operands. */
+ const Expression::List ops(checkee->operands());
+ if(ops.isEmpty())
+ return;
+
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkVariableCircularity(var, *it, type, signList, parseInfo);
+}
+
+static void variableUnavailable(const QXmlName &variableName,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &location)
+{
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No variable with name %1 exists")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
+ ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
+}
+
+/**
+ * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
+ * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
+ *
+ * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
+ * Cardinality + on range variables</a>
+ * @see ParserContext::finalizePushedVariable()
+ */
+static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
+{
+ Q_ASSERT(type);
+ return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
+}
+
+/**
+ * @p seqType and @p expr may be @c null.
+ */
+static Expression::Ptr pushVariable(const QXmlName name,
+ const SequenceType::Ptr &seqType,
+ const Expression::Ptr &expr,
+ const VariableDeclaration::Type type,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool checkSource = true)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
+ VariableSlotID slot = -2;
+
+ switch(type)
+ {
+ case VariableDeclaration::FunctionArgument:
+ /* Fallthrough. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ slot = parseInfo->allocateExpressionSlot();
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ {
+ slot = parseInfo->allocateGlobalVariableSlot();
+ break;
+ }
+ case VariableDeclaration::RangeVariable:
+ {
+ slot = parseInfo->staticContext->allocateRangeSlot();
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ slot = parseInfo->allocatePositionalSlot();
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ /* Fallthrough. We do nothing, template parameters
+ * doesn't use context slots at all, they're hashed
+ * on the name. */
+ case VariableDeclaration::ExternalVariable:
+ /* We do nothing, external variables doesn't use
+ *context slots/stack frames at all. */
+ ;
+ }
+
+ const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
+
+ Expression::Ptr checked;
+
+ if(checkSource && seqType)
+ {
+ if(expr)
+ {
+ /* We only want to add conversion for function arguments, and variables
+ * if we're XSL-T.
+ *
+ * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
+ * pass hasn't set up the focus yet, since that's the parent's responsibility. */
+ const TypeChecker::Options options(( type == VariableDeclaration::FunctionArgument
+ || type == VariableDeclaration::TemplateParameter
+ || parseInfo->isXSLT())
+ ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());
+
+ checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
+ parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ options);
+ }
+ }
+ else
+ checked = expr;
+
+ /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
+ * positional variables because in the end they are calls to Iterator::position(). Similarly,
+ * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
+ *
+ * We don't do it for function arguments because the Expression being cached depends -- it depends
+ * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
+ *
+ * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
+ * optimizes itself away. */
+ if(type == VariableDeclaration::ExpressionVariable)
+ checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+ else if(type == VariableDeclaration::GlobalVariable)
+ checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+
+ var->setExpression(checked);
+
+ parseInfo->variables.push(var);
+ return checked;
+}
+
+static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* We walk the list backwards. */
+ const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
+ VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ Q_ASSERT(*it);
+ if((*it)->name == name)
+ return *it;
+ }
+
+ return VariableDeclaration::Ptr();
+}
+
+static Expression::Ptr resolveVariable(const QXmlName &name,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool raiseErrorOnUnavailability)
+{
+ const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
+ Expression::Ptr retval;
+
+ if(var && var->type != VariableDeclaration::ExternalVariable)
+ {
+ switch(var->type)
+ {
+ case VariableDeclaration::RangeVariable:
+ {
+ retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
+ * a difference between a global and a local expression variable. However, the cache
+ * mechanism must. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::FunctionArgument:
+ {
+ retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ {
+ retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::ExternalVariable:
+ /* This code path will never be hit, but the case
+ * label silences a warning. See above. */
+ ;
+ }
+ Q_ASSERT(retval);
+ var->references.append(retval);
+ }
+ else
+ {
+ /* Let's see if your external variable loader can provide us with one. */
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));
+
+ if(varType)
+ {
+ const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
+ retval = checked;
+ }
+ else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
+ {
+ /* In XSL-T, global variables are in scope for the whole
+ * stylesheet, so we must resolve this first at the end. */
+ retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
+ parseInfo->unresolvedVariableReferences.insert(name, retval);
+ }
+ else
+ variableUnavailable(name, parseInfo, sourceLocator);
+ }
+
+ return retval;
+}
+
+static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
+ const Expression::Ptr &returnExpr,
+ const OrderBy::Stability stability,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ // TODO do resize(orderSpec.size() + 1)
+ Expression::List exprs;
+ OrderBy::OrderSpec::Vector orderSpecs;
+
+ exprs.append(returnExpr);
+
+ const int len = orderSpecTransfer.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ exprs.append(orderSpecTransfer.at(i).expression);
+ orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
+ }
+
+ return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
+}
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ STRING_LITERAL = 258,
+ NON_BOUNDARY_WS = 259,
+ XPATH2_STRING_LITERAL = 260,
+ QNAME = 261,
+ NCNAME = 262,
+ CLARK_NAME = 263,
+ ANY_LOCAL_NAME = 264,
+ ANY_PREFIX = 265,
+ NUMBER = 266,
+ XPATH2_NUMBER = 267,
+ ANCESTOR = 268,
+ ANCESTOR_OR_SELF = 269,
+ AND = 270,
+ APOS = 271,
+ APPLY_TEMPLATE = 272,
+ AS = 273,
+ ASCENDING = 274,
+ ASSIGN = 275,
+ AT = 276,
+ AT_SIGN = 277,
+ ATTRIBUTE = 278,
+ AVT = 279,
+ BAR = 280,
+ BASEURI = 281,
+ BEGIN_END_TAG = 282,
+ BOUNDARY_SPACE = 283,
+ BY = 284,
+ CALL_TEMPLATE = 285,
+ CASE = 286,
+ CASTABLE = 287,
+ CAST = 288,
+ CHILD = 289,
+ COLLATION = 290,
+ COLONCOLON = 291,
+ COMMA = 292,
+ COMMENT = 293,
+ COMMENT_START = 294,
+ CONSTRUCTION = 295,
+ COPY_NAMESPACES = 296,
+ CURLY_LBRACE = 297,
+ CURLY_RBRACE = 298,
+ DECLARE = 299,
+ DEFAULT = 300,
+ DESCENDANT = 301,
+ DESCENDANT_OR_SELF = 302,
+ DESCENDING = 303,
+ DIV = 304,
+ DOCUMENT = 305,
+ DOCUMENT_NODE = 306,
+ DOLLAR = 307,
+ DOT = 308,
+ DOTDOT = 309,
+ ELEMENT = 310,
+ ELSE = 311,
+ EMPTY = 312,
+ EMPTY_SEQUENCE = 313,
+ ENCODING = 314,
+ END_SORT = 315,
+ EQ = 316,
+ ERROR = 317,
+ EVERY = 318,
+ EXCEPT = 319,
+ EXTERNAL = 320,
+ FOLLOWING = 321,
+ FOLLOWING_SIBLING = 322,
+ FOLLOWS = 323,
+ FOR_APPLY_TEMPLATE = 324,
+ FOR = 325,
+ FUNCTION = 326,
+ GE = 327,
+ G_EQ = 328,
+ G_GE = 329,
+ G_GT = 330,
+ G_LE = 331,
+ G_LT = 332,
+ G_NE = 333,
+ GREATEST = 334,
+ GT = 335,
+ IDIV = 336,
+ IF = 337,
+ IMPORT = 338,
+ INHERIT = 339,
+ IN = 340,
+ INSTANCE = 341,
+ INTERSECT = 342,
+ IS = 343,
+ ITEM = 344,
+ LAX = 345,
+ LBRACKET = 346,
+ LEAST = 347,
+ LE = 348,
+ LET = 349,
+ LPAREN = 350,
+ LT = 351,
+ MAP = 352,
+ MATCHES = 353,
+ MINUS = 354,
+ MODE = 355,
+ MOD = 356,
+ MODULE = 357,
+ NAME = 358,
+ NAMESPACE = 359,
+ NE = 360,
+ NODE = 361,
+ NO_INHERIT = 362,
+ NO_PRESERVE = 363,
+ OF = 364,
+ OPTION = 365,
+ ORDERED = 366,
+ ORDERING = 367,
+ ORDER = 368,
+ OR = 369,
+ PARENT = 370,
+ PI_START = 371,
+ PLUS = 372,
+ POSITION_SET = 373,
+ PRAGMA_END = 374,
+ PRAGMA_START = 375,
+ PRECEDES = 376,
+ PRECEDING = 377,
+ PRECEDING_SIBLING = 378,
+ PRESERVE = 379,
+ PRIORITY = 380,
+ PROCESSING_INSTRUCTION = 381,
+ QUESTION = 382,
+ QUICK_TAG_END = 383,
+ QUOTE = 384,
+ RBRACKET = 385,
+ RETURN = 386,
+ RPAREN = 387,
+ SATISFIES = 388,
+ SCHEMA_ATTRIBUTE = 389,
+ SCHEMA_ELEMENT = 390,
+ SCHEMA = 391,
+ SELF = 392,
+ SEMI_COLON = 393,
+ SLASH = 394,
+ SLASHSLASH = 395,
+ SOME = 396,
+ SORT = 397,
+ STABLE = 398,
+ STAR = 399,
+ STRICT = 400,
+ STRIP = 401,
+ SUCCESS = 402,
+ COMMENT_CONTENT = 403,
+ PI_CONTENT = 404,
+ PI_TARGET = 405,
+ XSLT_VERSION = 406,
+ TEMPLATE = 407,
+ TEXT = 408,
+ THEN = 409,
+ TO = 410,
+ TREAT = 411,
+ TUNNEL = 412,
+ TYPESWITCH = 413,
+ UNION = 414,
+ UNORDERED = 415,
+ VALIDATE = 416,
+ VARIABLE = 417,
+ VERSION = 418,
+ WHERE = 419,
+ XQUERY = 420,
+ INTERNAL = 421,
+ INTERNAL_NAME = 422,
+ CURRENT = 423
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+/* Line 221 of yacc.c. */
+#line 1323 "qquerytransformparser.cpp"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 2052
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 169
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 237
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 472
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 812
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 423
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
+ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 6, 9, 10, 16, 17, 20, 23,
+ 26, 33, 34, 37, 40, 43, 46, 49, 52, 55,
+ 58, 66, 67, 68, 84, 85, 88, 89, 91, 94,
+ 96, 98, 100, 102, 104, 106, 108, 110, 112, 114,
+ 122, 127, 129, 131, 133, 135, 142, 149, 155, 160,
+ 162, 164, 170, 173, 176, 183, 185, 187, 189, 191,
+ 197, 203, 210, 211, 215, 219, 226, 227, 231, 232,
+ 235, 237, 241, 251, 253, 256, 257, 260, 265, 267,
+ 269, 270, 282, 283, 285, 289, 293, 295, 297, 301,
+ 303, 305, 309, 311, 313, 316, 319, 321, 325, 329,
+ 331, 333, 337, 341, 343, 345, 347, 351, 355, 357,
+ 359, 361, 363, 365, 370, 371, 374, 375, 378, 380,
+ 384, 386, 388, 390, 392, 393, 394, 405, 406, 407,
+ 418, 420, 422, 424, 425, 429, 430, 440, 441, 450,
+ 452, 454, 456, 460, 466, 467, 469, 472, 476, 478,
+ 483, 484, 486, 488, 489, 491, 492, 495, 499, 503,
+ 506, 508, 510, 511, 512, 522, 523, 524, 534, 536,
+ 537, 538, 548, 549, 550, 560, 562, 565, 566, 573,
+ 574, 575, 584, 586, 588, 589, 593, 597, 598, 605,
+ 614, 616, 620, 622, 626, 628, 630, 632, 634, 636,
+ 640, 642, 646, 648, 650, 652, 656, 658, 660, 662,
+ 664, 666, 670, 672, 676, 678, 680, 682, 684, 686,
+ 691, 693, 698, 700, 705, 707, 712, 714, 717, 719,
+ 721, 723, 725, 727, 731, 733, 735, 737, 739, 741,
+ 743, 747, 749, 751, 753, 755, 757, 759, 763, 765,
+ 767, 769, 772, 774, 777, 780, 783, 786, 790, 793,
+ 795, 800, 801, 803, 806, 809, 811, 813, 815, 819,
+ 827, 831, 833, 835, 838, 839, 843, 849, 850, 860,
+ 866, 867, 870, 871, 873, 877, 878, 882, 888, 889,
+ 891, 892, 895, 897, 899, 901, 903, 908, 910, 912,
+ 913, 917, 919, 921, 923, 926, 928, 930, 932, 934,
+ 936, 938, 940, 942, 944, 946, 948, 950, 951, 955,
+ 957, 959, 961, 963, 965, 967, 969, 971, 973, 975,
+ 977, 979, 984, 986, 988, 990, 992, 994, 996, 998,
+ 1004, 1006, 1008, 1010, 1012, 1015, 1017, 1019, 1023, 1026,
+ 1028, 1031, 1036, 1037, 1039, 1041, 1043, 1045, 1047, 1049,
+ 1051, 1052, 1053, 1062, 1064, 1070, 1071, 1074, 1078, 1082,
+ 1086, 1087, 1090, 1093, 1094, 1097, 1100, 1103, 1106, 1109,
+ 1113, 1115, 1117, 1119, 1121, 1123, 1125, 1127, 1131, 1132,
+ 1138, 1139, 1141, 1146, 1150, 1154, 1158, 1159, 1160, 1164,
+ 1166, 1168, 1170, 1172, 1174, 1176, 1180, 1182, 1185, 1186,
+ 1189, 1192, 1195, 1196, 1198, 1200, 1202, 1204, 1206, 1208,
+ 1211, 1213, 1215, 1217, 1219, 1221, 1223, 1225, 1227, 1230,
+ 1233, 1238, 1240, 1242, 1245, 1248, 1251, 1256, 1261, 1263,
+ 1265, 1268, 1273, 1278, 1285, 1292, 1297, 1300, 1305, 1310,
+ 1318, 1326, 1327, 1329, 1334, 1337, 1339, 1341, 1343, 1345,
+ 1347, 1349, 1351, 1353, 1356, 1358, 1360, 1362, 1364, 1366,
+ 1368, 1370, 1372
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 170, 0, -1, 171, 174, -1, 171, 173, -1, -1,
+ 165, 163, 404, 172, 185, -1, -1, 59, 404, -1,
+ 176, 219, -1, 175, 176, -1, 102, 104, 7, 73,
+ 403, 185, -1, -1, 176, 189, -1, 176, 183, -1,
+ 176, 186, -1, 176, 184, -1, 176, 177, -1, 176,
+ 208, -1, 176, 213, -1, 176, 192, -1, 44, 152,
+ 182, 317, 377, 305, 185, -1, -1, -1, 44, 152,
+ 181, 98, 95, 178, 220, 179, 132, 228, 180, 317,
+ 377, 305, 185, -1, -1, 125, 404, -1, -1, 182,
+ -1, 103, 397, -1, 187, -1, 200, -1, 201, -1,
+ 211, -1, 193, -1, 195, -1, 197, -1, 202, -1,
+ 204, -1, 138, -1, 44, 104, 7, 73, 403, 364,
+ 185, -1, 44, 28, 188, 185, -1, 146, -1, 124,
+ -1, 190, -1, 191, -1, 44, 45, 55, 104, 403,
+ 185, -1, 44, 45, 71, 104, 403, 185, -1, 44,
+ 110, 397, 404, 185, -1, 44, 112, 194, 185, -1,
+ 111, -1, 160, -1, 44, 45, 113, 196, 185, -1,
+ 57, 92, -1, 57, 79, -1, 44, 41, 198, 37,
+ 199, 185, -1, 124, -1, 108, -1, 84, -1, 107,
+ -1, 44, 45, 35, 404, 185, -1, 44, 26, 364,
+ 403, 185, -1, 83, 136, 203, 403, 206, 185, -1,
+ -1, 45, 55, 104, -1, 104, 7, 73, -1, 83,
+ 102, 205, 403, 206, 185, -1, -1, 104, 7, 73,
+ -1, -1, 21, 207, -1, 403, -1, 207, 37, 403,
+ -1, 44, 162, 364, 52, 341, 377, 209, 210, 185,
+ -1, 65, -1, 20, 227, -1, -1, 20, 227, -1,
+ 44, 40, 212, 185, -1, 146, -1, 124, -1, -1,
+ 44, 71, 364, 399, 95, 215, 132, 214, 377, 217,
+ 185, -1, -1, 216, -1, 215, 37, 216, -1, 52,
+ 341, 377, -1, 65, -1, 218, -1, 42, 225, 43,
+ -1, 225, -1, 221, -1, 220, 25, 221, -1, 223,
+ -1, 139, -1, 139, 223, -1, 140, 223, -1, 222,
+ -1, 222, 139, 223, -1, 222, 140, 223, -1, 345,
+ -1, 224, -1, 223, 139, 224, -1, 223, 140, 224,
+ -1, 322, -1, 227, -1, 226, -1, 227, 37, 227,
+ -1, 226, 37, 227, -1, 277, -1, 232, -1, 253,
+ -1, 267, -1, 276, -1, 24, 95, 356, 132, -1,
+ -1, 100, 230, -1, -1, 100, 231, -1, 231, -1,
+ 230, 37, 231, -1, 405, -1, 7, -1, 233, -1,
+ 240, -1, -1, -1, 70, 52, 341, 377, 239, 85,
+ 227, 234, 235, 236, -1, -1, -1, 37, 52, 341,
+ 377, 239, 85, 227, 237, 238, 236, -1, 244, -1,
+ 233, -1, 240, -1, -1, 21, 52, 341, -1, -1,
+ 94, 364, 52, 341, 377, 20, 227, 241, 242, -1,
+ -1, 37, 52, 341, 377, 20, 227, 243, 242, -1,
+ 244, -1, 233, -1, 240, -1, 245, 131, 227, -1,
+ 164, 227, 245, 131, 227, -1, -1, 246, -1, 252,
+ 247, -1, 247, 37, 248, -1, 248, -1, 227, 249,
+ 250, 251, -1, -1, 19, -1, 48, -1, -1, 196,
+ -1, -1, 35, 403, -1, 166, 35, 227, -1, 143,
+ 113, 29, -1, 113, 29, -1, 254, -1, 260, -1,
+ -1, -1, 141, 52, 341, 377, 85, 227, 255, 256,
+ 257, -1, -1, -1, 37, 52, 341, 377, 85, 227,
+ 258, 259, 257, -1, 266, -1, -1, -1, 63, 52,
+ 341, 377, 85, 227, 261, 262, 263, -1, -1, -1,
+ 37, 52, 341, 377, 85, 227, 264, 265, 263, -1,
+ 266, -1, 133, 227, -1, -1, 158, 95, 225, 132,
+ 268, 269, -1, -1, -1, 31, 273, 378, 270, 131,
+ 227, 271, 272, -1, 269, -1, 274, -1, -1, 52,
+ 397, 18, -1, 45, 131, 227, -1, -1, 45, 52,
+ 397, 275, 131, 227, -1, 82, 95, 225, 132, 154,
+ 227, 56, 227, -1, 278, -1, 277, 114, 278, -1,
+ 279, -1, 278, 15, 279, -1, 280, -1, 298, -1,
+ 296, -1, 300, -1, 281, -1, 281, 155, 281, -1,
+ 283, -1, 281, 282, 283, -1, 117, -1, 99, -1,
+ 285, -1, 283, 284, 285, -1, 144, -1, 49, -1,
+ 81, -1, 101, -1, 286, -1, 285, 287, 286, -1,
+ 289, -1, 286, 288, 289, -1, 159, -1, 25, -1,
+ 87, -1, 64, -1, 290, -1, 290, 86, 109, 378,
+ -1, 291, -1, 291, 156, 18, 378, -1, 292, -1,
+ 292, 32, 18, 376, -1, 293, -1, 293, 33, 18,
+ 376, -1, 295, -1, 294, 293, -1, 117, -1, 99,
+ -1, 302, -1, 309, -1, 304, -1, 280, 297, 280,
+ -1, 73, -1, 78, -1, 74, -1, 75, -1, 76,
+ -1, 77, -1, 280, 299, 280, -1, 61, -1, 105,
+ -1, 72, -1, 80, -1, 93, -1, 96, -1, 280,
+ 301, 280, -1, 88, -1, 121, -1, 68, -1, 303,
+ 218, -1, 161, -1, 161, 145, -1, 161, 90, -1,
+ 306, 305, -1, 42, 43, -1, 42, 225, 43, -1,
+ 306, 307, -1, 307, -1, 120, 402, 308, 119, -1,
+ -1, 404, -1, 139, 310, -1, 140, 310, -1, 139,
+ -1, 310, -1, 311, -1, 310, 321, 311, -1, 310,
+ 321, 142, 246, 131, 311, 60, -1, 310, 140, 311,
+ -1, 322, -1, 336, -1, 168, 218, -1, -1, 151,
+ 312, 218, -1, 26, 404, 42, 225, 43, -1, -1,
+ 44, 104, 7, 73, 3, 42, 313, 225, 43, -1,
+ 30, 397, 95, 314, 132, -1, -1, 315, 316, -1,
+ -1, 318, -1, 316, 37, 318, -1, -1, 95, 316,
+ 132, -1, 319, 52, 341, 377, 320, -1, -1, 157,
+ -1, -1, 20, 227, -1, 139, -1, 97, -1, 69,
+ -1, 323, -1, 322, 91, 225, 130, -1, 324, -1,
+ 331, -1, -1, 327, 325, 326, -1, 329, -1, 333,
+ -1, 389, -1, 328, 36, -1, 14, -1, 13, -1,
+ 23, -1, 34, -1, 47, -1, 46, -1, 66, -1,
+ 122, -1, 67, -1, 123, -1, 115, -1, 137, -1,
+ -1, 22, 330, 333, -1, 333, -1, 389, -1, 332,
+ -1, 54, -1, 334, -1, 382, -1, 397, -1, 335,
+ -1, 144, -1, 9, -1, 10, -1, 337, -1, 336,
+ 91, 225, 130, -1, 338, -1, 340, -1, 342, -1,
+ 343, -1, 345, -1, 344, -1, 347, -1, 17, 229,
+ 95, 314, 132, -1, 339, -1, 404, -1, 12, -1,
+ 11, -1, 52, 341, -1, 7, -1, 405, -1, 95,
+ 225, 132, -1, 95, 132, -1, 53, -1, 194, 218,
+ -1, 399, 95, 346, 132, -1, -1, 227, -1, 226,
+ -1, 348, -1, 360, -1, 349, -1, 358, -1, 359,
+ -1, -1, -1, 77, 401, 350, 353, 351, 118, 353,
+ 352, -1, 128, -1, 75, 357, 27, 397, 75, -1,
+ -1, 353, 354, -1, 401, 73, 355, -1, 129, 356,
+ 129, -1, 16, 356, 16, -1, -1, 218, 356, -1,
+ 404, 356, -1, -1, 357, 348, -1, 357, 404, -1,
+ 357, 4, -1, 357, 218, -1, 39, 148, -1, 116,
+ 150, 149, -1, 361, -1, 362, -1, 365, -1, 366,
+ -1, 367, -1, 368, -1, 375, -1, 50, 364, 218,
+ -1, -1, 55, 364, 372, 363, 305, -1, -1, 166,
+ -1, 23, 364, 369, 305, -1, 153, 364, 218, -1,
+ 38, 364, 218, -1, 126, 374, 305, -1, -1, -1,
+ 370, 397, 371, -1, 373, -1, 397, -1, 373, -1,
+ 218, -1, 7, -1, 218, -1, 104, 218, 218, -1,
+ 381, -1, 381, 127, -1, -1, 18, 378, -1, 380,
+ 379, -1, 58, 395, -1, -1, 117, -1, 144, -1,
+ 127, -1, 381, -1, 382, -1, 389, -1, 89, 395,
+ -1, 397, -1, 384, -1, 392, -1, 394, -1, 388,
+ -1, 387, -1, 386, -1, 383, -1, 106, 395, -1,
+ 51, 395, -1, 51, 95, 385, 132, -1, 392, -1,
+ 394, -1, 153, 395, -1, 38, 395, -1, 126, 395,
+ -1, 126, 95, 7, 132, -1, 126, 95, 404, 132,
+ -1, 390, -1, 391, -1, 23, 395, -1, 23, 95,
+ 144, 132, -1, 23, 95, 396, 132, -1, 23, 95,
+ 396, 37, 398, 132, -1, 23, 95, 144, 37, 398,
+ 132, -1, 134, 95, 397, 132, -1, 55, 395, -1,
+ 55, 95, 144, 132, -1, 55, 95, 397, 132, -1,
+ 55, 95, 397, 37, 398, 393, 132, -1, 55, 95,
+ 144, 37, 398, 393, 132, -1, -1, 127, -1, 135,
+ 95, 397, 132, -1, 95, 132, -1, 7, -1, 405,
+ -1, 7, -1, 405, -1, 397, -1, 400, -1, 405,
+ -1, 7, -1, 167, 7, -1, 7, -1, 6, -1,
+ 7, -1, 405, -1, 404, -1, 3, -1, 5, -1,
+ 6, -1, 8, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 1375, 1375, 1376, 1378, 1379, 1410, 1411, 1427, 1525,
+ 1527, 1533, 1535, 1542, 1548, 1554, 1561, 1564, 1568, 1572,
+ 1592, 1606, 1610, 1604, 1673, 1677, 1694, 1697, 1699, 1704,
+ 1705, 1709, 1710, 1714, 1718, 1722, 1724, 1725, 1727, 1729,
+ 1775, 1789, 1794, 1799, 1800, 1802, 1817, 1832, 1842, 1857,
+ 1861, 1866, 1880, 1884, 1889, 1903, 1908, 1913, 1918, 1923,
+ 1939, 1962, 1970, 1971, 1972, 1974, 1991, 1992, 1994, 1995,
+ 1997, 1998, 2000, 2055, 2059, 2065, 2068, 2073, 2087, 2091,
+ 2097, 2096, 2205, 2208, 2214, 2235, 2241, 2245, 2247, 2252,
+ 2262, 2263, 2268, 2269, 2278, 2348, 2359, 2360, 2364, 2369,
+ 2438, 2439, 2443, 2448, 2492, 2493, 2498, 2505, 2511, 2512,
+ 2513, 2514, 2515, 2516, 2522, 2527, 2533, 2536, 2541, 2547,
+ 2553, 2557, 2582, 2583, 2587, 2591, 2585, 2632, 2635, 2630,
+ 2651, 2652, 2653, 2656, 2660, 2668, 2667, 2681, 2680, 2689,
+ 2690, 2691, 2693, 2701, 2712, 2715, 2717, 2722, 2729, 2736,
+ 2742, 2762, 2767, 2773, 2776, 2778, 2779, 2786, 2792, 2796,
+ 2801, 2802, 2805, 2809, 2804, 2819, 2823, 2818, 2831, 2834,
+ 2838, 2833, 2848, 2852, 2847, 2860, 2862, 2890, 2889, 2901,
+ 2909, 2900, 2920, 2921, 2924, 2928, 2933, 2938, 2937, 2953,
+ 2959, 2960, 2966, 2967, 2973, 2974, 2975, 2976, 2978, 2979,
+ 2985, 2986, 2992, 2993, 2995, 2996, 3002, 3003, 3004, 3005,
+ 3007, 3008, 3018, 3019, 3025, 3026, 3028, 3032, 3037, 3038,
+ 3045, 3046, 3052, 3053, 3059, 3060, 3066, 3067, 3073, 3077,
+ 3082, 3083, 3084, 3086, 3092, 3093, 3094, 3095, 3096, 3097,
+ 3099, 3104, 3105, 3106, 3107, 3108, 3109, 3111, 3116, 3117,
+ 3118, 3120, 3134, 3135, 3136, 3138, 3155, 3159, 3164, 3165,
+ 3167, 3172, 3173, 3175, 3181, 3185, 3191, 3194, 3195, 3199,
+ 3208, 3213, 3217, 3218, 3223, 3222, 3237, 3245, 3244, 3260,
+ 3268, 3268, 3277, 3279, 3282, 3287, 3289, 3293, 3359, 3362,
+ 3368, 3371, 3380, 3384, 3388, 3393, 3394, 3399, 3400, 3403,
+ 3402, 3432, 3434, 3435, 3437, 3481, 3482, 3483, 3484, 3485,
+ 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3495, 3494, 3505,
+ 3516, 3521, 3523, 3528, 3529, 3534, 3538, 3540, 3544, 3553,
+ 3560, 3561, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574,
+ 3584, 3585, 3590, 3595, 3601, 3607, 3612, 3617, 3622, 3628,
+ 3633, 3638, 3668, 3672, 3679, 3681, 3685, 3690, 3691, 3692,
+ 3726, 3735, 3724, 3976, 3980, 4000, 4003, 4009, 4014, 4019,
+ 4025, 4028, 4038, 4045, 4049, 4055, 4069, 4075, 4092, 4097,
+ 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4118, 4126, 4125,
+ 4165, 4168, 4173, 4188, 4193, 4200, 4212, 4216, 4212, 4222,
+ 4224, 4228, 4230, 4245, 4249, 4258, 4263, 4267, 4273, 4276,
+ 4281, 4286, 4291, 4292, 4293, 4294, 4296, 4297, 4298, 4299,
+ 4304, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4348, 4353,
+ 4358, 4364, 4365, 4367, 4372, 4377, 4382, 4387, 4403, 4404,
+ 4406, 4411, 4416, 4420, 4432, 4445, 4455, 4460, 4465, 4470,
+ 4484, 4498, 4499, 4501, 4511, 4513, 4518, 4525, 4532, 4534,
+ 4536, 4537, 4539, 4543, 4548, 4549, 4551, 4557, 4559, 4561,
+ 4565, 4570, 4582
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "\"end of file\"", "error", "$undefined", "\"<string literal>\"",
+ "\"<non-boundary text node>\"", "\"<string literal(XPath 2.0)>\"",
+ "\"QName\"", "\"NCName\"", "\"ClarkName\"", "ANY_LOCAL_NAME",
+ "ANY_PREFIX", "\"<number literal>\"", "\"<number literal(XPath 2.0)>\"",
+ "\"ancestor\"", "\"ancestor-or-self\"", "\"and\"", "\"'\"",
+ "\"apply-template\"", "\"as\"", "\"ascending\"", "\":=\"", "\"at\"",
+ "\"@\"", "\"attribute\"", "AVT", "\"|\"", "\"base-uri\"", "\"</\"",
+ "\"boundary-space\"", "\"by\"", "\"call-template\"", "\"case\"",
+ "\"castable\"", "\"cast\"", "\"child\"", "\"collation\"", "\"::\"",
+ "\",\"", "\"comment\"", "\"<!--\"", "\"construction\"",
+ "\"copy-namespaces\"", "\"{\"", "\"}\"", "\"declare\"", "\"default\"",
+ "\"descendant\"", "\"descendant-or-self\"", "\"descending\"", "\"div\"",
+ "\"document\"", "\"document-node\"", "\"$\"", "\".\"", "\"..\"",
+ "\"element\"", "\"else\"", "\"empty\"", "\"empty-sequence\"",
+ "\"encoding\"", "\"end_sort\"", "\"eq\"", "\"unknown keyword\"",
+ "\"every\"", "\"except\"", "\"external\"", "\"following\"",
+ "\"following-sibling\"", "\">>\"", "\"for-apply-template\"", "\"for\"",
+ "\"function\"", "\"ge\"", "\"=\"", "\">=\"", "\">\"", "\"<=\"", "\"<\"",
+ "\"!=\"", "\"greatest\"", "\"gt\"", "\"idiv\"", "\"if\"", "\"import\"",
+ "\"inherit\"", "\"in\"", "\"instance\"", "\"intersect\"", "\"is\"",
+ "\"item\"", "\"lax\"", "\"[\"", "\"least\"", "\"le\"", "\"let\"",
+ "\"(\"", "\"lt\"", "\"map\"", "\"matches\"", "\"-\"", "\"mode\"",
+ "\"mod\"", "\"module\"", "\"name\"", "\"namespace\"", "\"ne\"",
+ "\"node\"", "\"no-inherit\"", "\"no-preserve\"", "\"of\"", "\"option\"",
+ "\"ordered\"", "\"ordering\"", "\"order\"", "\"or\"", "\"parent\"",
+ "\"<?\"", "\"+\"", "POSITION_SET", "\"#)\"", "\"(#\"", "\"<<\"",
+ "\"preceding\"", "\"preceding-sibling\"", "\"preserve\"", "\"priority\"",
+ "\"processing-instruction\"", "\"?\"", "\"/>\"", "\"\\\"\"", "\"]\"",
+ "\"return\"", "\")\"", "\"satisfies\"", "\"schema-attribute\"",
+ "\"schema-element\"", "\"schema\"", "\"self\"", "\";\"", "\"/\"",
+ "\"//\"", "\"some\"", "\"sort\"", "\"stable\"", "\"*\"", "\"strict\"",
+ "\"strip\"", "SUCCESS", "COMMENT_CONTENT", "PI_CONTENT", "PI_TARGET",
+ "XSLT_VERSION", "\"template\"", "\"text\"", "\"then\"", "\"to\"",
+ "\"treat\"", "\"tunnel\"", "\"typeswitch\"", "\"union\"",
+ "\"unordered\"", "\"validate\"", "\"variable\"", "\"version\"",
+ "\"where\"", "\"xquery\"", "\"internal\"", "\"internal-name\"",
+ "\"current\"", "$accept", "Module", "VersionDecl", "Encoding",
+ "MainModule", "LibraryModule", "ModuleDecl", "Prolog", "TemplateDecl",
+ "@1", "@2", "OptionalPriority", "OptionalTemplateName", "TemplateName",
+ "Setter", "Import", "Separator", "NamespaceDecl", "BoundarySpaceDecl",
+ "BoundarySpacePolicy", "DefaultNamespaceDecl",
+ "DeclareDefaultElementNamespace", "DeclareDefaultFunctionNamespace",
+ "OptionDecl", "OrderingModeDecl", "OrderingMode", "EmptyOrderDecl",
+ "OrderingEmptySequence", "CopyNamespacesDecl", "PreserveMode",
+ "InheritMode", "DefaultCollationDecl", "BaseURIDecl", "SchemaImport",
+ "SchemaPrefix", "ModuleImport", "ModuleNamespaceDecl", "FileLocations",
+ "FileLocation", "VarDecl", "VariableValue", "OptionalDefaultValue",
+ "ConstructionDecl", "ConstructionMode", "FunctionDecl", "@3",
+ "ParamList", "Param", "FunctionBody", "EnclosedExpr", "QueryBody",
+ "Pattern", "PathPattern", "IdKeyPattern", "RelativePathPattern",
+ "PatternStep", "Expr", "ExpressionSequence", "ExprSingle",
+ "OptionalModes", "OptionalMode", "Modes", "Mode", "FLWORExpr",
+ "ForClause", "@4", "@5", "ForTail", "@6", "@7", "PositionalVar",
+ "LetClause", "@8", "LetTail", "@9", "WhereClause", "OrderByClause",
+ "MandatoryOrderByClause", "OrderSpecList", "OrderSpec",
+ "DirectionModifier", "EmptynessModifier", "CollationModifier",
+ "OrderByInputOrder", "QuantifiedExpr", "SomeQuantificationExpr", "@10",
+ "@11", "SomeQuantificationTail", "@12", "@13", "EveryQuantificationExpr",
+ "@14", "@15", "EveryQuantificationTail", "@16", "@17", "SatisfiesClause",
+ "TypeswitchExpr", "@18", "CaseClause", "@19", "@20", "CaseTail",
+ "CaseVariable", "CaseDefault", "@21", "IfExpr", "OrExpr", "AndExpr",
+ "ComparisonExpr", "RangeExpr", "AdditiveExpr", "AdditiveOperator",
+ "MultiplicativeExpr", "MultiplyOperator", "UnionExpr",
+ "IntersectExceptExpr", "UnionOperator", "IntersectOperator",
+ "InstanceOfExpr", "TreatExpr", "CastableExpr", "CastExpr", "UnaryExpr",
+ "UnaryOperator", "ValueExpr", "GeneralComp", "GeneralComparisonOperator",
+ "ValueComp", "ValueComparisonOperator", "NodeComp", "NodeOperator",
+ "ValidateExpr", "ValidationMode", "ExtensionExpr",
+ "EnclosedOptionalExpr", "Pragmas", "Pragma", "PragmaContents",
+ "PathExpr", "RelativePathExpr", "StepExpr", "@22", "@23",
+ "TemplateWithParameters", "@24", "TemplateParameters",
+ "OptionalTemplateParameters", "TemplateParameter", "IsTunnel",
+ "OptionalAssign", "MapOrSlash", "FilteredAxisStep", "AxisStep",
+ "ForwardStep", "@25", "NodeTestInAxisStep", "Axis", "AxisToken",
+ "AbbrevForwardStep", "@26", "ReverseStep", "AbbrevReverseStep",
+ "NodeTest", "NameTest", "WildCard", "FilterExpr", "PrimaryExpr",
+ "Literal", "NumericLiteral", "VarRef", "VarName", "ParenthesizedExpr",
+ "ContextItemExpr", "OrderingExpr", "FunctionCallExpr",
+ "FunctionArguments", "Constructor", "DirectConstructor",
+ "DirElemConstructor", "@27", "@28", "DirElemConstructorTail",
+ "DirAttributeList", "Attribute", "DirAttributeValue", "AttrValueContent",
+ "DirElemContent", "DirCommentConstructor", "DirPIConstructor",
+ "ComputedConstructor", "CompDocConstructor", "CompElemConstructor",
+ "@29", "IsInternal", "CompAttrConstructor", "CompTextConstructor",
+ "CompCommentConstructor", "CompPIConstructor", "CompAttributeName",
+ "@30", "@31", "CompElementName", "CompNameExpr", "CompPIName",
+ "CompNamespaceConstructor", "SingleType", "TypeDeclaration",
+ "SequenceType", "OccurrenceIndicator", "ItemType", "AtomicType",
+ "KindTest", "AnyKindTest", "DocumentTest", "AnyElementTest", "TextTest",
+ "CommentTest", "PITest", "AnyAttributeTest", "AttributeTest",
+ "SchemaAttributeTest", "ElementTest", "OptionalQuestionMark",
+ "SchemaElementTest", "EmptyParanteses", "AttributeName", "ElementName",
+ "TypeName", "FunctionName", "NCName", "LexicalName", "PragmaName",
+ "URILiteral", "StringLiteral", "QName", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
+ 395, 396, 397, 398, 399, 400, 401, 402, 403, 404,
+ 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
+ 415, 416, 417, 418, 419, 420, 421, 422, 423
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 169, 170, 170, 171, 171, 172, 172, 173, 174,
+ 175, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 177, 178, 179, 177, 180, 180, 181, 181, 182, 183,
+ 183, 183, 183, 183, 183, 183, 184, 184, 185, 186,
+ 187, 188, 188, 189, 189, 190, 191, 192, 193, 194,
+ 194, 195, 196, 196, 197, 198, 198, 199, 199, 200,
+ 201, 202, 203, 203, 203, 204, 205, 205, 206, 206,
+ 207, 207, 208, 209, 209, 210, 210, 211, 212, 212,
+ 214, 213, 215, 215, 215, 216, 217, 217, 218, 219,
+ 220, 220, 221, 221, 221, 221, 221, 221, 221, 222,
+ 223, 223, 223, 224, 225, 225, 226, 226, 227, 227,
+ 227, 227, 227, 227, 228, 228, 229, 229, 230, 230,
+ 231, 231, 232, 232, 234, 235, 233, 237, 238, 236,
+ 236, 236, 236, 239, 239, 241, 240, 243, 242, 242,
+ 242, 242, 244, 244, 245, 245, 246, 247, 247, 248,
+ 249, 249, 249, 250, 250, 251, 251, 251, 252, 252,
+ 253, 253, 255, 256, 254, 258, 259, 257, 257, 261,
+ 262, 260, 264, 265, 263, 263, 266, 268, 267, 270,
+ 271, 269, 272, 272, 273, 273, 274, 275, 274, 276,
+ 277, 277, 278, 278, 279, 279, 279, 279, 280, 280,
+ 281, 281, 282, 282, 283, 283, 284, 284, 284, 284,
+ 285, 285, 286, 286, 287, 287, 288, 288, 289, 289,
+ 290, 290, 291, 291, 292, 292, 293, 293, 294, 294,
+ 295, 295, 295, 296, 297, 297, 297, 297, 297, 297,
+ 298, 299, 299, 299, 299, 299, 299, 300, 301, 301,
+ 301, 302, 303, 303, 303, 304, 305, 305, 306, 306,
+ 307, 308, 308, 309, 309, 309, 309, 310, 310, 310,
+ 310, 311, 311, 311, 312, 311, 311, 313, 311, 311,
+ 315, 314, 316, 316, 316, 317, 317, 318, 319, 319,
+ 320, 320, 321, 321, 321, 322, 322, 323, 323, 325,
+ 324, 324, 326, 326, 327, 328, 328, 328, 328, 328,
+ 328, 328, 328, 328, 328, 328, 328, 330, 329, 329,
+ 329, 331, 332, 333, 333, 334, 334, 335, 335, 335,
+ 336, 336, 337, 337, 337, 337, 337, 337, 337, 337,
+ 338, 338, 339, 339, 340, 341, 341, 342, 342, 343,
+ 344, 345, 346, 346, 346, 347, 347, 348, 348, 348,
+ 350, 351, 349, 352, 352, 353, 353, 354, 355, 355,
+ 356, 356, 356, 357, 357, 357, 357, 357, 358, 359,
+ 360, 360, 360, 360, 360, 360, 360, 361, 363, 362,
+ 364, 364, 365, 366, 367, 368, 370, 371, 369, 369,
+ 372, 372, 373, 374, 374, 375, 376, 376, 377, 377,
+ 378, 378, 379, 379, 379, 379, 380, 380, 380, 380,
+ 381, 382, 382, 382, 382, 382, 382, 382, 383, 384,
+ 384, 385, 385, 386, 387, 388, 388, 388, 389, 389,
+ 390, 390, 390, 390, 390, 391, 392, 392, 392, 392,
+ 392, 393, 393, 394, 395, 396, 396, 397, 397, 398,
+ 399, 399, 400, 400, 401, 401, 402, 402, 403, 404,
+ 404, 405, 405
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 2, 2, 0, 5, 0, 2, 2, 2,
+ 6, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 7, 0, 0, 15, 0, 2, 0, 1, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 7,
+ 4, 1, 1, 1, 1, 6, 6, 5, 4, 1,
+ 1, 5, 2, 2, 6, 1, 1, 1, 1, 5,
+ 5, 6, 0, 3, 3, 6, 0, 3, 0, 2,
+ 1, 3, 9, 1, 2, 0, 2, 4, 1, 1,
+ 0, 11, 0, 1, 3, 3, 1, 1, 3, 1,
+ 1, 3, 1, 1, 2, 2, 1, 3, 3, 1,
+ 1, 3, 3, 1, 1, 1, 3, 3, 1, 1,
+ 1, 1, 1, 4, 0, 2, 0, 2, 1, 3,
+ 1, 1, 1, 1, 0, 0, 10, 0, 0, 10,
+ 1, 1, 1, 0, 3, 0, 9, 0, 8, 1,
+ 1, 1, 3, 5, 0, 1, 2, 3, 1, 4,
+ 0, 1, 1, 0, 1, 0, 2, 3, 3, 2,
+ 1, 1, 0, 0, 9, 0, 0, 9, 1, 0,
+ 0, 9, 0, 0, 9, 1, 2, 0, 6, 0,
+ 0, 8, 1, 1, 0, 3, 3, 0, 6, 8,
+ 1, 3, 1, 3, 1, 1, 1, 1, 1, 3,
+ 1, 3, 1, 1, 1, 3, 1, 1, 1, 1,
+ 1, 3, 1, 3, 1, 1, 1, 1, 1, 4,
+ 1, 4, 1, 4, 1, 4, 1, 2, 1, 1,
+ 1, 1, 1, 3, 1, 1, 1, 1, 1, 1,
+ 3, 1, 1, 1, 1, 1, 1, 3, 1, 1,
+ 1, 2, 1, 2, 2, 2, 2, 3, 2, 1,
+ 4, 0, 1, 2, 2, 1, 1, 1, 3, 7,
+ 3, 1, 1, 2, 0, 3, 5, 0, 9, 5,
+ 0, 2, 0, 1, 3, 0, 3, 5, 0, 1,
+ 0, 2, 1, 1, 1, 1, 4, 1, 1, 0,
+ 3, 1, 1, 1, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 1, 1, 1, 1, 1, 1, 1, 5,
+ 1, 1, 1, 1, 2, 1, 1, 3, 2, 1,
+ 2, 4, 0, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 8, 1, 5, 0, 2, 3, 3, 3,
+ 0, 2, 2, 0, 2, 2, 2, 2, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 3, 0, 5,
+ 0, 1, 4, 3, 3, 3, 0, 0, 3, 1,
+ 1, 1, 1, 1, 1, 3, 1, 2, 0, 2,
+ 2, 2, 0, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 4, 1, 1, 2, 2, 2, 4, 4, 1, 1,
+ 2, 4, 4, 6, 6, 4, 2, 4, 4, 7,
+ 7, 0, 1, 4, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 4, 0, 0, 11, 0, 1, 0, 3, 2, 11,
+ 0, 469, 470, 6, 0, 9, 471, 457, 472, 328,
+ 329, 343, 342, 306, 305, 116, 317, 390, 0, 0,
+ 0, 308, 390, 0, 0, 310, 309, 390, 0, 0,
+ 349, 322, 390, 0, 311, 313, 0, 0, 0, 0,
+ 390, 0, 229, 0, 0, 49, 315, 0, 228, 0,
+ 312, 314, 0, 0, 0, 316, 265, 0, 0, 327,
+ 274, 390, 0, 50, 252, 0, 0, 16, 13, 15,
+ 14, 29, 12, 43, 44, 19, 33, 0, 34, 35,
+ 30, 31, 36, 37, 17, 32, 18, 8, 89, 105,
+ 104, 109, 122, 123, 110, 160, 161, 111, 112, 108,
+ 190, 192, 194, 198, 200, 204, 210, 212, 218, 220,
+ 222, 224, 0, 226, 196, 195, 197, 230, 0, 232,
+ 0, 259, 231, 266, 267, 271, 295, 297, 299, 0,
+ 301, 298, 321, 319, 323, 326, 272, 330, 332, 340,
+ 333, 334, 335, 337, 336, 338, 355, 357, 358, 359,
+ 356, 380, 381, 382, 383, 384, 385, 386, 324, 427,
+ 421, 426, 425, 424, 320, 438, 439, 422, 423, 325,
+ 0, 460, 341, 458, 0, 0, 0, 0, 0, 0,
+ 0, 0, 391, 396, 440, 370, 0, 457, 0, 458,
+ 0, 0, 434, 378, 390, 0, 0, 0, 0, 390,
+ 0, 0, 0, 26, 390, 0, 0, 429, 345, 344,
+ 346, 0, 0, 446, 0, 0, 465, 464, 360, 0,
+ 66, 62, 0, 0, 348, 0, 0, 0, 428, 0,
+ 466, 261, 467, 403, 0, 404, 0, 435, 0, 0,
+ 263, 264, 0, 0, 0, 433, 0, 254, 253, 463,
+ 273, 350, 0, 0, 0, 0, 241, 250, 243, 234,
+ 236, 237, 238, 239, 235, 244, 248, 245, 246, 242,
+ 249, 0, 0, 0, 203, 202, 0, 0, 207, 208,
+ 209, 206, 0, 215, 214, 0, 217, 216, 0, 0,
+ 0, 0, 0, 227, 251, 0, 255, 258, 294, 293,
+ 292, 0, 0, 0, 0, 304, 0, 352, 7, 38,
+ 5, 0, 0, 121, 117, 120, 280, 0, 0, 0,
+ 0, 318, 455, 454, 0, 0, 456, 402, 0, 0,
+ 399, 370, 0, 370, 0, 280, 394, 0, 42, 41,
+ 0, 79, 78, 0, 56, 55, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 285, 0, 387,
+ 0, 431, 432, 0, 0, 388, 401, 400, 408, 408,
+ 365, 0, 0, 0, 0, 0, 0, 0, 0, 347,
+ 0, 405, 379, 0, 262, 0, 0, 395, 0, 0,
+ 408, 275, 393, 0, 107, 106, 191, 193, 233, 240,
+ 247, 199, 201, 205, 211, 213, 0, 0, 0, 0,
+ 256, 0, 270, 0, 268, 0, 0, 300, 302, 303,
+ 0, 354, 353, 0, 0, 468, 0, 0, 282, 0,
+ 441, 0, 442, 392, 397, 371, 113, 372, 0, 0,
+ 0, 40, 77, 0, 0, 0, 0, 0, 0, 462,
+ 0, 461, 0, 0, 48, 28, 0, 282, 408, 0,
+ 430, 0, 447, 0, 448, 0, 0, 0, 133, 361,
+ 0, 0, 68, 0, 0, 68, 408, 0, 88, 260,
+ 436, 437, 445, 453, 0, 177, 0, 0, 219, 412,
+ 416, 417, 418, 420, 221, 223, 406, 225, 257, 0,
+ 0, 0, 0, 296, 331, 351, 10, 0, 339, 289,
+ 281, 283, 0, 459, 0, 0, 398, 276, 279, 60,
+ 57, 58, 0, 59, 0, 0, 53, 52, 51, 82,
+ 469, 390, 47, 21, 0, 0, 408, 451, 451, 389,
+ 409, 0, 0, 0, 0, 366, 0, 0, 67, 0,
+ 0, 63, 64, 0, 0, 0, 0, 0, 411, 419,
+ 413, 415, 414, 410, 407, 159, 0, 0, 150, 146,
+ 148, 288, 0, 444, 443, 54, 45, 46, 0, 0,
+ 83, 277, 0, 0, 286, 0, 0, 452, 0, 0,
+ 169, 0, 0, 365, 0, 0, 69, 70, 65, 61,
+ 0, 0, 162, 184, 178, 158, 0, 151, 152, 153,
+ 0, 284, 408, 408, 0, 80, 0, 39, 307, 93,
+ 0, 22, 90, 96, 92, 100, 103, 99, 20, 0,
+ 73, 75, 450, 449, 170, 134, 124, 0, 370, 370,
+ 367, 0, 0, 135, 163, 0, 0, 269, 154, 155,
+ 147, 290, 85, 84, 408, 0, 94, 95, 0, 0,
+ 0, 0, 0, 0, 74, 0, 0, 0, 125, 373,
+ 363, 362, 0, 0, 189, 71, 144, 0, 0, 179,
+ 0, 0, 149, 0, 287, 0, 278, 91, 114, 97,
+ 98, 101, 102, 76, 72, 0, 0, 171, 175, 144,
+ 0, 369, 368, 0, 0, 140, 141, 136, 139, 0,
+ 145, 0, 164, 168, 185, 0, 156, 0, 291, 86,
+ 0, 87, 0, 24, 0, 176, 0, 131, 126, 132,
+ 130, 376, 0, 377, 374, 375, 0, 144, 0, 0,
+ 0, 157, 81, 115, 118, 0, 285, 408, 0, 0,
+ 408, 0, 142, 408, 180, 0, 25, 408, 0, 408,
+ 364, 0, 0, 0, 0, 119, 0, 0, 133, 0,
+ 143, 0, 0, 182, 181, 183, 0, 172, 0, 137,
+ 165, 0, 0, 23, 173, 0, 144, 166, 187, 186,
+ 0, 127, 138, 0, 0, 174, 128, 167, 0, 144,
+ 188, 129
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 2, 3, 185, 7, 8, 9, 10, 77, 593,
+ 669, 756, 366, 367, 78, 79, 320, 80, 81, 350,
+ 82, 83, 84, 85, 86, 87, 88, 458, 89, 356,
+ 532, 90, 91, 92, 386, 93, 383, 560, 606, 94,
+ 641, 676, 95, 353, 96, 664, 589, 590, 730, 341,
+ 97, 631, 632, 633, 634, 635, 98, 99, 100, 733,
+ 189, 753, 324, 101, 102, 678, 709, 738, 806, 809,
+ 553, 103, 686, 717, 796, 718, 719, 720, 579, 580,
+ 619, 659, 692, 512, 104, 105, 654, 687, 722, 797,
+ 803, 106, 644, 677, 707, 794, 800, 708, 107, 567,
+ 614, 725, 774, 784, 656, 785, 804, 108, 109, 110,
+ 111, 112, 113, 287, 114, 292, 115, 116, 295, 298,
+ 117, 118, 119, 120, 121, 122, 123, 124, 281, 125,
+ 282, 126, 283, 127, 128, 129, 306, 130, 131, 393,
+ 132, 133, 134, 253, 626, 437, 438, 520, 468, 521,
+ 522, 694, 312, 135, 136, 137, 314, 427, 138, 139,
+ 140, 190, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 219, 151, 152, 153, 154, 433, 155, 156,
+ 157, 380, 554, 681, 479, 555, 650, 342, 710, 158,
+ 159, 160, 161, 162, 475, 193, 163, 164, 165, 166,
+ 338, 339, 526, 375, 340, 246, 167, 505, 477, 498,
+ 573, 499, 500, 168, 169, 170, 370, 171, 172, 173,
+ 174, 175, 176, 177, 598, 178, 194, 335, 179, 524,
+ 180, 181, 556, 241, 541, 182, 183
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -668
+static const yytype_int16 yypact[] =
+{
+ -63, -28, 185, 86, 337, -668, 117, -668, -668, -668,
+ 734, -668, -668, 181, 253, 156, -668, 213, -668, -668,
+ -668, -668, -668, -668, -668, 212, -668, -12, 230, 337,
+ 342, -668, -38, 189, 298, -668, -668, 188, 272, 353,
+ -668, -668, 71, 316, -668, -668, 318, 239, 276, 134,
+ 188, 900, -668, 334, 282, -668, -668, 233, -668, 367,
+ -668, -668, 133, 290, 295, -668, 1730, 1730, 345, -668,
+ -668, -38, 305, -668, -36, 396, 334, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 334, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, 369,
+ 370, -668, -668, -668, -668, -668, -668, -668, -668, 307,
+ 389, -668, 601, 173, 24, -22, 32, -668, 338, 267,
+ 393, 394, 1398, -668, -668, -668, -668, -668, 334, -668,
+ 59, -668, -668, 166, -668, 339, -668, -668, -668, 395,
+ -668, -668, -668, -668, -668, -668, 341, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ 340, -668, -668, 347, 337, 291, 360, 493, 373, 349,
+ 1885, 64, -668, 334, -668, 226, 392, -668, 358, -668,
+ 304, 334, -668, -668, 188, 167, 174, 206, 21, 188,
+ 430, 342, -53, 351, 188, 334, 6, -668, -668, -668,
+ -668, 79, 287, -668, 353, 353, -668, -668, -668, 1232,
+ 336, 18, 403, 344, -668, 324, 1232, 334, -668, 308,
+ -668, 337, -668, -668, 23, -668, 416, -668, 342, 342,
+ 166, 166, 353, 334, 334, -668, 1232, -668, -668, -668,
+ -668, -668, 1232, 1232, 1398, 1398, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, -668, -668, -668,
+ -668, 1398, 1398, 1398, -668, -668, 1398, 1398, -668, -668,
+ -668, -668, 1398, -668, -668, 1398, -668, -668, 1398, 352,
+ 447, 448, 449, -668, -668, 1066, -668, -668, -668, -668,
+ -668, 1730, 1564, 1232, 108, -668, 1232, 1232, -668, -668,
+ -668, 337, 461, -668, -668, -668, -668, 282, 374, 378,
+ 282, -668, -668, -668, 0, 51, -668, -668, 416, 342,
+ -668, 226, 343, 226, 1232, -668, -668, 337, -668, -668,
+ 291, -668, -668, 291, -668, -668, 437, 337, 372, 376,
+ 421, 26, 408, 337, 291, 342, 384, -1, 431, -668,
+ 355, -668, -668, 52, 69, -668, -668, -668, 466, 466,
+ -668, 356, 482, 337, 435, 484, 337, 353, 485, -668,
+ 453, -668, -668, 379, -668, 365, 368, -668, 371, 377,
+ 466, -668, -668, 380, -668, -668, 389, -668, -668, -668,
+ -668, 168, 24, -22, 32, -668, 456, 456, 342, 342,
+ -668, 459, -668, 191, -668, 375, 404, -668, -668, -668,
+ 383, 369, 370, 386, 291, -668, 442, 388, -6, 342,
+ -668, 342, -668, -668, -668, -668, -668, -668, 465, 391,
+ 291, -668, -668, 157, 291, 337, 337, 16, 291, -668,
+ 409, -668, 348, 291, -668, -668, 415, -6, 466, 353,
+ -668, 342, -668, 342, -668, 416, 456, 440, 495, 239,
+ 381, 454, 507, 425, 457, 507, 466, 463, -668, -668,
+ -668, -668, -668, -668, 462, -668, 282, 282, -668, 121,
+ -668, -668, -668, -668, -668, -668, 412, -668, -668, 512,
+ 433, 417, 1232, -668, -668, -668, -668, 337, -668, -668,
+ 513, -668, 497, -668, 422, 423, -668, -668, -668, -668,
+ -668, -668, 291, -668, 291, 291, -668, -668, -668, 504,
+ 515, 188, -668, -668, 83, 416, 466, 432, 432, -668,
+ -668, 1232, 508, 476, 450, -668, 492, 1232, -668, 337,
+ 291, -668, -668, 291, 547, 566, 1232, 539, -668, -668,
+ -668, -668, -668, -668, -668, -668, 543, 1730, 62, 536,
+ -668, 419, 353, -668, -668, -668, -668, -668, 353, 84,
+ -668, -668, 291, 1804, -668, 291, 46, -668, 445, 446,
+ -668, 353, 1232, -668, 33, 524, 550, -668, -668, -668,
+ 1232, 515, -668, 537, -668, -668, 528, -668, -668, 421,
+ 1232, -668, 466, 466, 504, -668, 1232, -668, 404, 1899,
+ 1899, 567, -668, 140, 148, -668, 339, -668, -668, 1232,
+ -668, 573, -668, -668, -668, -668, -668, 92, 226, 226,
+ -668, 1232, 337, -668, -668, 342, 456, -668, -668, -23,
+ -668, 574, -668, -668, 466, 552, 148, 148, 1804, 464,
+ 1899, 1899, 1899, 1899, -668, 1232, 291, 11, -668, -668,
+ -668, -668, 582, 472, -668, -668, 10, 47, 584, -668,
+ 337, 569, -668, 1232, -668, 234, -668, -668, 506, 148,
+ 148, -668, -668, -668, -668, 555, 1232, -668, -668, 63,
+ 250, -668, -668, 556, 1232, -668, -668, -668, -668, 479,
+ -668, 559, -668, -668, -668, 481, -668, 1232, -668, -668,
+ 291, -668, 373, 488, 353, -668, 562, -668, -668, -668,
+ -668, -668, 342, -668, -668, -668, 353, 191, 1232, 353,
+ 1232, -668, -668, 578, -668, 337, 521, 466, 353, 542,
+ 466, 487, -668, 466, -668, 373, -668, 466, 534, 466,
+ -668, 600, 1232, 538, 125, -668, 416, 1232, 495, 1232,
+ -668, 1232, -2, -668, -668, -668, 291, -668, 544, -668,
+ -668, 342, 1232, -668, -668, 1232, 10, -668, -668, -668,
+ 11, -668, -668, 47, 490, -668, -668, -668, 1232, 63,
+ -668, -668
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -668, -668, -668, -668, -668, -668, -668, 613, -668, -668,
+ -668, -668, -668, -668, -668, -668, -285, -668, -668, -668,
+ -668, -668, -668, -668, -668, 418, -668, 5, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 142, -668, -668,
+ -668, -668, -668, -668, -668, -668, -668, 4, -668, -51,
+ -668, -668, -35, -668, -397, -340, -47, 317, -255, -668,
+ -668, -668, -641, -668, -619, -668, -668, -174, -668, -668,
+ -142, -583, -668, -159, -668, -657, -109, 216, -668, 27,
+ -668, -668, -668, -668, -668, -668, -668, -668, -157, -668,
+ -668, -668, -668, -668, -152, -668, -668, -667, -668, -668,
+ -125, -668, -668, -668, -668, -668, -668, -668, -668, 387,
+ 385, 131, 366, -668, 397, -668, 361, 359, -668, -668,
+ 362, -668, -668, -668, 535, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -668, -668, -245, -668, 526, -668,
+ -668, 279, -294, -668, -668, 313, -668, 194, -91, 85,
+ -668, -668, -668, -87, -668, -668, -668, -668, -668, -668,
+ -668, -668, -668, -668, -175, -668, -668, -668, -668, -668,
+ -668, -668, -183, -668, -668, -668, -538, -668, -668, -42,
+ -668, -668, -668, -668, 67, -668, -668, -327, -668, -668,
+ -668, -668, -668, -668, -668, 3, -668, -668, -668, -668,
+ -668, -668, -668, -668, 458, -668, -668, 252, -341, -412,
+ -668, -668, -55, -394, -668, -668, -668, -668, -668, -668,
+ -304, -668, -668, 467, 124, 469, -11, -668, -24, -170,
+ 321, -668, 639, -668, -308, 15, -30
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -463
+static const yytype_int16 yytable[] =
+{
+ 199, 397, 237, 293, 235, 504, 198, 404, 405, 220,
+ 429, 245, 690, 434, 445, 331, 447, 422, 424, 13,
+ 723, 202, 501, 501, -307, 260, 11, 217, 12, 242,
+ 395, 223, 16, 459, 18, 201, 261, 439, 478, 450,
+ 215, 378, 379, 238, 196, 222, -288, 713, 705, 648,
+ 791, 247, 740, 232, 257, 637, 357, 200, 55, 494,
+ 255, 328, 432, 384, 550, 451, 639, 715, 452, 400,
+ 16, 332, 18, 288, 254, 482, 358, 304, 485, 464,
+ 46, 617, 501, 191, 721, 16, 197, 18, 441, 471,
+ 737, 754, 359, 443, 467, 536, 296, -27, 226, 227,
+ 736, 305, 1, 716, 50, 289, 473, 73, 537, 258,
+ 618, 640, 502, 502, 16, 197, 18, 19, 20, 297,
+ 581, 624, 385, 509, 775, 290, 739, 545, 192, 792,
+ 637, 426, 440, 46, 360, 4, 723, 294, 333, 428,
+ 243, 64, 337, 691, 706, 564, 327, 534, 535, 516,
+ 346, 519, 740, 510, 192, 333, 613, 50, 325, 38,
+ 199, 336, 649, 328, 369, 529, 221, 679, 291, 533,
+ 782, 337, 502, 538, 714, 236, 509, 715, 542, 59,
+ 706, 199, 381, 442, 472, 5, 391, 363, 6, 390,
+ 737, 199, 199, 75, 220, 220, 333, 374, 377, 318,
+ 187, 474, 401, 402, 486, 596, 510, 347, 334, 403,
+ 343, 333, 361, 716, 54, 594, 625, 368, 199, 199,
+ 680, 14, 220, 373, 398, 399, 739, 714, 244, 11,
+ 549, 12, 666, 667, 329, 308, 230, 192, 570, 49,
+ 184, 530, 63, 64, 689, 226, 227, 585, 571, 586,
+ 587, 607, 69, 11, 741, 12, 394, 578, 421, 396,
+ 186, 330, 501, 309, 531, 572, 425, 284, 236, 430,
+ 231, 525, 284, 699, 700, 608, 236, 742, 609, 670,
+ 671, 661, 662, 616, 199, 285, 546, 672, 673, 33,
+ 285, 348, 236, 16, 197, 18, 600, 448, 351, 729,
+ 595, 547, 605, 548, 509, 310, 311, 627, -462, 199,
+ 638, 612, 188, 349, 354, 444, 202, 223, 247, 255,
+ 352, 682, 683, 695, 204, 195, 205, 47, 286, 236,
+ 355, 461, 701, 702, 510, 199, 435, 203, 206, 207,
+ 11, 465, 12, 208, 685, 250, 251, 646, 16, 197,
+ 18, 540, 502, 12, 192, 653, 343, 220, 343, 16,
+ 218, 18, 435, 506, 506, 578, 57, 216, 224, 209,
+ 225, 229, 454, 16, 240, 18, 236, 200, 463, 16,
+ 323, 18, 726, 239, 674, 248, 199, 199, 199, 199,
+ 249, 704, 503, 503, 503, 503, 684, 252, 435, 622,
+ 256, 435, 210, 259, 265, 623, 262, 263, 211, 199,
+ 212, 199, 408, 409, 410, 523, 768, 523, 645, 771,
+ 703, 264, 773, 300, 299, 301, 776, 302, 778, 319,
+ 313, 315, 316, 321, 344, 317, 333, 362, 728, 220,
+ 382, 199, -461, 199, 326, 752, 199, 523, 388, 523,
+ 213, 735, 503, 345, 365, 387, 389, 392, 305, 747,
+ 214, 416, 16, 197, 18, 417, 418, 419, 436, 221,
+ 435, 435, 751, 244, 453, 446, 455, 435, 457, 426,
+ 456, 462, 466, 469, 476, 568, 569, 470, 480, 481,
+ 483, 484, 487, 762, 327, 764, 488, 490, 489, 191,
+ 491, 793, 508, 492, 539, 513, 636, 38, 527, 493,
+ 543, 328, 495, 514, 496, 517, 552, 780, 515, 204,
+ 518, 205, 787, 528, 789, 551, 790, 558, 559, 561,
+ 562, 786, 435, 206, 207, 557, 565, 799, 208, 574,
+ 801, 575, 636, 636, 592, 497, 576, 566, 577, 582,
+ 581, 757, 220, 810, 583, 584, 588, 591, 220, 597,
+ 601, 602, 54, 760, 209, 604, 763, 610, 603, 611,
+ 613, 220, 615, 620, 435, 769, 519, 642, 643, 665,
+ 651, 636, 329, 636, 636, 636, 636, 652, 657, 655,
+ 63, 64, 668, 675, 693, 696, 698, 322, 711, 199,
+ 199, 712, 724, 211, 727, 212, 732, 734, 746, 330,
+ 748, 749, 750, 755, 758, 765, 467, 770, 772, 777,
+ 779, 808, 15, 781, 658, 199, 199, 563, 663, 795,
+ 364, 688, 503, 697, 431, 811, 788, 802, 761, 511,
+ 199, 199, 199, 199, 731, 213, 807, 660, 805, 783,
+ 407, 406, 411, 413, 414, 214, 307, 303, 449, 743,
+ 415, 544, 266, 343, 343, 767, 621, 435, 744, 267,
+ 647, 507, 599, 268, 269, 270, 271, 272, 273, 274,
+ 376, 275, 460, 371, 412, 372, 228, 0, 0, 276,
+ 0, 0, 0, 0, 277, 0, 0, 278, 0, 0,
+ 0, 0, 325, 0, 220, 435, 279, 0, 0, 0,
+ 0, 0, 199, 0, 0, 0, 220, 0, 759, 220,
+ 0, 0, 280, 0, 0, 745, 0, 0, 220, 0,
+ 0, 0, 0, 0, 0, 325, 0, 11, 0, 12,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
+ 0, 25, 0, 0, 0, 0, 26, 27, 28, 0,
+ 29, 199, 0, 0, 30, 0, 0, 798, 31, 0,
+ 766, 0, 32, 33, 0, 0, 0, 0, 34, 0,
+ 35, 36, 0, 0, 37, 38, 39, 40, 41, 42,
+ 0, 0, 0, 0, 0, 0, 0, 43, 0, 0,
+ 44, 45, 0, 0, 46, 0, 0, 0, 0, 0,
+ 0, 47, 0, 0, 0, 0, 48, 49, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 50, 51,
+ 0, 0, 0, 52, 0, 0, 0, 0, 53, 0,
+ 54, 0, 0, 0, 0, 55, 0, 0, 0, 56,
+ 57, 58, 0, 0, 59, 0, 60, 61, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 63, 64,
+ 0, 65, 0, 66, 67, 68, 0, 0, 69, 0,
+ 0, 0, 0, 0, 0, 70, 0, 71, 0, 0,
+ 0, 0, 72, 0, 73, 74, 0, 0, 0, 0,
+ 0, 75, 76, 11, 0, 12, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 0, 0, 25, 0, 0,
+ 0, 0, 26, 27, 28, 0, 29, 0, 0, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 32, 33,
+ 0, 0, 0, 0, 233, 0, 35, 36, 0, 0,
+ 37, 38, 39, 40, 41, 42, 0, 0, 0, 0,
+ 0, 0, 0, 43, 0, 0, 44, 45, 0, 0,
+ 46, 0, 0, 0, 0, 0, 0, 47, 0, 0,
+ 0, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 50, 51, 0, 0, 0, 52,
+ 0, 0, 0, 0, 53, 0, 54, 0, 0, 0,
+ 0, 55, 0, 0, 0, 56, 57, 58, 0, 0,
+ 59, 0, 60, 61, 0, 0, 62, 0, 0, 0,
+ 0, 0, 234, 0, 63, 64, 0, 65, 0, 66,
+ 67, 68, 0, 0, 69, 0, 0, 0, 0, 0,
+ 0, 70, 0, 71, 0, 0, 0, 0, 72, 0,
+ 73, 74, 0, 0, 0, 0, 0, 75, 76, 11,
+ 0, 12, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 0, 0, 25, 0, 0, 0, 0, 26, 27,
+ 28, 0, 29, 0, 0, 0, 30, 0, 0, 0,
+ 31, 0, 0, 0, 32, 33, 0, 0, 0, 420,
+ 233, 0, 35, 36, 0, 0, 37, 38, 39, 40,
+ 41, 42, 0, 0, 0, 0, 0, 0, 0, 43,
+ 0, 0, 44, 45, 0, 0, 46, 0, 0, 0,
+ 0, 0, 0, 47, 0, 0, 0, 0, 48, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 50, 51, 0, 0, 0, 52, 0, 0, 0, 0,
+ 53, 0, 54, 0, 0, 0, 0, 55, 0, 0,
+ 0, 56, 57, 58, 0, 0, 59, 0, 60, 61,
+ 0, 0, 62, 0, 0, 0, 0, 0, 0, 0,
+ 63, 64, 0, 65, 0, 66, 67, 68, 0, 0,
+ 69, 0, 0, 0, 0, 0, 0, 70, 0, 71,
+ 0, 0, 0, 0, 72, 0, 73, 74, 0, 0,
+ 0, 0, 0, 75, 76, 11, 0, 12, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 0, 0, 25,
+ 0, 0, 0, 0, 26, 27, 28, 0, 29, 0,
+ 0, 0, 30, 0, 0, 0, 31, 0, 0, 0,
+ 32, 33, 0, 0, 0, 0, 233, 0, 35, 36,
+ 0, 0, 37, 38, 39, 40, 41, 42, 0, 0,
+ 0, 0, 0, 0, 0, 43, 0, 0, 44, 45,
+ 0, 0, 46, 0, 0, 0, 0, 0, 0, 47,
+ 0, 0, 0, 0, 48, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 50, 51, 0, 0,
+ 0, 52, 0, 0, 0, 0, 53, 0, 54, 0,
+ 0, 0, 0, 55, 0, 0, 0, 56, 57, 58,
+ 0, 0, 59, 0, 60, 61, 0, 0, 62, 0,
+ 0, 0, 0, 0, 0, 0, 63, 64, 0, 65,
+ 0, 66, 67, 68, 0, 0, 69, 0, 0, 0,
+ 0, 0, 0, 70, 0, 71, 0, 0, 0, 0,
+ 72, 0, 73, 74, 0, 0, 0, 0, 0, 75,
+ 76, 11, 0, 12, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 0, 0, 25, 0, 0, 0, 0,
+ 26, 27, 0, 0, 29, 0, 0, 0, 30, 0,
+ 0, 0, 31, 0, 0, 0, 32, 33, 0, 0,
+ 0, 0, 233, 0, 35, 36, 0, 0, 37, 38,
+ 39, 40, 41, 42, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 44, 45, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 51, 0, 0, 0, 52, 0, 0,
+ 0, 0, 53, 0, 54, 0, 0, 0, 0, 55,
+ 0, 0, 0, 56, 57, 58, 0, 0, 59, 0,
+ 60, 61, 0, 0, 62, 0, 0, 0, 0, 0,
+ 0, 0, 63, 64, 0, 65, 0, 66, 67, 0,
+ 0, 0, 69, 0, 0, 0, 0, 0, 0, 70,
+ 0, 71, 0, 0, 0, 0, 0, 0, 73, 74,
+ 0, 0, 0, 0, 0, 75, 76, 11, 0, 12,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 0,
+ 0, 25, 0, 0, 0, 0, 26, 27, 0, 0,
+ 29, 0, 0, 0, 30, 0, 0, 0, 31, 0,
+ 0, 0, 32, 33, 0, 0, 0, 0, 233, 0,
+ 35, 36, 0, 0, 37, 38, 39, 40, 41, 42,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 44, 45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 47, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 53, 0,
+ 54, 0, 0, 0, 0, 55, 0, 0, 0, 56,
+ 57, 0, 0, 0, 0, 0, 60, 61, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 63, 64,
+ 0, 65, 0, 0, 0, 0, 423, 0, 69, 0,
+ 0, 0, 0, 0, 0, 70, 0, 71, 0, 0,
+ 0, 0, 0, 0, 73, 0, 0, 0, 0, 0,
+ 0, 75, 76, 11, 0, 12, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 0, 0, 25, 0, 0,
+ 0, 0, 26, 27, 0, 0, 29, 0, 0, 0,
+ 30, 0, 0, 0, 31, 0, 0, 0, 32, 33,
+ 0, 0, 0, 0, 233, 0, 35, 36, 0, 0,
+ 37, 38, 39, 40, 41, 42, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 44, 45, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 47, 0, 0,
+ 16, 17, 18, 19, 20, 0, 0, 23, 24, 0,
+ 0, 0, 0, 0, 0, 51, 26, 628, 0, 0,
+ 0, 0, 0, 0, 53, 0, 54, 0, 31, 0,
+ 0, 55, 327, 0, 0, 56, 57, 0, 0, 0,
+ 35, 36, 60, 61, 0, 38, 62, 0, 41, 328,
+ 0, 0, 0, 0, 63, 64, 0, 65, 0, 0,
+ 44, 45, 0, 0, 69, 0, 0, 0, 0, 0,
+ 0, 70, 0, 71, 0, 0, 0, 0, 0, 0,
+ 73, 16, 197, 18, 19, 20, 0, 75, 76, 0,
+ 0, 0, 0, 0, 0, 16, 197, 18, 19, 20,
+ 54, 0, 23, 24, 0, 0, 0, 0, 0, 56,
+ 0, 26, 628, 327, 0, 0, 60, 61, 0, 0,
+ 329, 0, 0, 31, 0, 0, 38, 327, 63, 64,
+ 328, 65, 0, 629, 630, 35, 36, 0, 69, 0,
+ 38, 0, 0, 41, 328, 0, 0, 330, 0, 0,
+ 0, 0, 0, 0, 0, 44, 45, 0, 0, 0,
+ 0, 75, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 0, 0,
+ 0, 329, 0, 0, 56, 0, 0, 0, 0, 0,
+ 64, 60, 61, 0, 0, 329, 0, 0, 0, 69,
+ 0, 0, 0, 63, 64, 0, 65, 0, 330, 0,
+ 0, 0, 0, 69, 0, 0, 0, 0, 0, 0,
+ 0, 0, 330
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 30, 246, 53, 25, 51, 417, 30, 262, 263, 39,
+ 314, 62, 35, 321, 341, 190, 343, 311, 312, 4,
+ 687, 32, 416, 417, 36, 76, 3, 38, 5, 59,
+ 7, 42, 6, 7, 8, 32, 87, 37, 379, 347,
+ 37, 224, 225, 54, 29, 42, 52, 37, 37, 16,
+ 52, 62, 709, 50, 90, 593, 35, 95, 111, 400,
+ 71, 55, 317, 45, 476, 350, 20, 686, 353, 252,
+ 6, 7, 8, 49, 71, 383, 55, 128, 386, 364,
+ 70, 19, 476, 95, 37, 6, 7, 8, 37, 37,
+ 709, 732, 71, 338, 95, 79, 64, 98, 6, 7,
+ 37, 42, 165, 686, 94, 81, 37, 160, 92, 145,
+ 48, 65, 416, 417, 6, 7, 8, 9, 10, 87,
+ 37, 37, 104, 113, 765, 101, 709, 468, 166, 131,
+ 668, 23, 132, 70, 113, 163, 803, 159, 132, 314,
+ 7, 135, 193, 166, 133, 486, 38, 455, 456, 434,
+ 201, 157, 809, 143, 166, 132, 31, 94, 188, 51,
+ 190, 191, 129, 55, 215, 450, 95, 75, 144, 454,
+ 45, 222, 476, 458, 164, 42, 113, 796, 463, 120,
+ 133, 211, 229, 132, 132, 0, 237, 211, 102, 236,
+ 809, 221, 222, 167, 224, 225, 132, 221, 222, 184,
+ 44, 132, 253, 254, 387, 546, 143, 204, 144, 256,
+ 195, 132, 209, 796, 106, 132, 132, 214, 248, 249,
+ 128, 104, 252, 144, 248, 249, 809, 164, 95, 3,
+ 475, 5, 629, 630, 126, 69, 102, 166, 117, 83,
+ 59, 84, 134, 135, 656, 6, 7, 532, 127, 534,
+ 535, 559, 144, 3, 4, 5, 241, 512, 305, 244,
+ 7, 153, 656, 97, 107, 144, 313, 99, 42, 316,
+ 136, 441, 99, 670, 671, 560, 42, 27, 563, 139,
+ 140, 622, 623, 577, 314, 117, 469, 139, 140, 39,
+ 117, 124, 42, 6, 7, 8, 551, 344, 124, 65,
+ 545, 471, 557, 473, 113, 139, 140, 592, 95, 339,
+ 595, 566, 100, 146, 108, 339, 327, 328, 329, 330,
+ 146, 648, 649, 664, 26, 95, 28, 77, 155, 42,
+ 124, 361, 672, 673, 143, 365, 321, 148, 40, 41,
+ 3, 365, 5, 45, 652, 66, 67, 602, 6, 7,
+ 8, 3, 656, 5, 166, 610, 341, 387, 343, 6,
+ 7, 8, 347, 418, 419, 620, 116, 95, 52, 71,
+ 52, 95, 357, 6, 7, 8, 42, 95, 363, 6,
+ 7, 8, 690, 150, 639, 95, 416, 417, 418, 419,
+ 95, 676, 416, 417, 418, 419, 651, 52, 383, 582,
+ 95, 386, 104, 7, 15, 588, 37, 37, 110, 439,
+ 112, 441, 281, 282, 283, 439, 757, 441, 601, 760,
+ 675, 114, 763, 156, 86, 32, 767, 33, 769, 138,
+ 91, 36, 91, 73, 42, 95, 132, 7, 693, 469,
+ 104, 471, 95, 473, 95, 730, 476, 471, 104, 473,
+ 152, 706, 476, 95, 103, 52, 132, 149, 42, 714,
+ 162, 109, 6, 7, 8, 18, 18, 18, 7, 95,
+ 455, 456, 727, 95, 37, 132, 104, 462, 57, 23,
+ 104, 73, 98, 52, 18, 496, 497, 132, 132, 7,
+ 55, 7, 7, 748, 38, 750, 43, 132, 119, 95,
+ 132, 786, 43, 132, 95, 130, 593, 51, 43, 132,
+ 95, 55, 132, 130, 58, 73, 21, 772, 132, 26,
+ 132, 28, 777, 132, 779, 85, 781, 73, 21, 104,
+ 73, 776, 517, 40, 41, 154, 73, 792, 45, 127,
+ 795, 29, 629, 630, 541, 89, 113, 85, 131, 52,
+ 37, 734, 582, 808, 132, 132, 52, 42, 588, 127,
+ 52, 85, 106, 746, 71, 73, 749, 20, 118, 3,
+ 31, 601, 29, 37, 559, 758, 157, 132, 132, 626,
+ 56, 668, 126, 670, 671, 672, 673, 37, 60, 52,
+ 134, 135, 25, 20, 20, 43, 132, 104, 16, 629,
+ 630, 129, 18, 110, 35, 112, 100, 52, 52, 153,
+ 131, 52, 131, 125, 52, 37, 95, 75, 131, 85,
+ 20, 131, 9, 85, 619, 655, 656, 485, 624, 85,
+ 212, 655, 656, 668, 317, 809, 778, 796, 747, 423,
+ 670, 671, 672, 673, 695, 152, 803, 620, 800, 774,
+ 265, 264, 286, 292, 295, 162, 130, 122, 345, 710,
+ 298, 467, 61, 648, 649, 756, 581, 652, 710, 68,
+ 603, 419, 548, 72, 73, 74, 75, 76, 77, 78,
+ 222, 80, 361, 216, 287, 216, 47, -1, -1, 88,
+ -1, -1, -1, -1, 93, -1, -1, 96, -1, -1,
+ -1, -1, 732, -1, 734, 690, 105, -1, -1, -1,
+ -1, -1, 742, -1, -1, -1, 746, -1, 742, 749,
+ -1, -1, 121, -1, -1, 710, -1, -1, 758, -1,
+ -1, -1, -1, -1, -1, 765, -1, 3, -1, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, 17, -1, -1, -1, -1, 22, 23, 24, -1,
+ 26, 791, -1, -1, 30, -1, -1, 791, 34, -1,
+ 755, -1, 38, 39, -1, -1, -1, -1, 44, -1,
+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
+ -1, -1, -1, -1, -1, -1, -1, 63, -1, -1,
+ 66, 67, -1, -1, 70, -1, -1, -1, -1, -1,
+ -1, 77, -1, -1, -1, -1, 82, 83, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 94, 95,
+ -1, -1, -1, 99, -1, -1, -1, -1, 104, -1,
+ 106, -1, -1, -1, -1, 111, -1, -1, -1, 115,
+ 116, 117, -1, -1, 120, -1, 122, 123, -1, -1,
+ 126, -1, -1, -1, -1, -1, -1, -1, 134, 135,
+ -1, 137, -1, 139, 140, 141, -1, -1, 144, -1,
+ -1, -1, -1, -1, -1, 151, -1, 153, -1, -1,
+ -1, -1, 158, -1, 160, 161, -1, -1, -1, -1,
+ -1, 167, 168, 3, -1, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, 17, -1, -1,
+ -1, -1, 22, 23, 24, -1, 26, -1, -1, -1,
+ 30, -1, -1, -1, 34, -1, -1, -1, 38, 39,
+ -1, -1, -1, -1, 44, -1, 46, 47, -1, -1,
+ 50, 51, 52, 53, 54, 55, -1, -1, -1, -1,
+ -1, -1, -1, 63, -1, -1, 66, 67, -1, -1,
+ 70, -1, -1, -1, -1, -1, -1, 77, -1, -1,
+ -1, -1, 82, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 94, 95, -1, -1, -1, 99,
+ -1, -1, -1, -1, 104, -1, 106, -1, -1, -1,
+ -1, 111, -1, -1, -1, 115, 116, 117, -1, -1,
+ 120, -1, 122, 123, -1, -1, 126, -1, -1, -1,
+ -1, -1, 132, -1, 134, 135, -1, 137, -1, 139,
+ 140, 141, -1, -1, 144, -1, -1, -1, -1, -1,
+ -1, 151, -1, 153, -1, -1, -1, -1, 158, -1,
+ 160, 161, -1, -1, -1, -1, -1, 167, 168, 3,
+ -1, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, -1, -1, 17, -1, -1, -1, -1, 22, 23,
+ 24, -1, 26, -1, -1, -1, 30, -1, -1, -1,
+ 34, -1, -1, -1, 38, 39, -1, -1, -1, 43,
+ 44, -1, 46, 47, -1, -1, 50, 51, 52, 53,
+ 54, 55, -1, -1, -1, -1, -1, -1, -1, 63,
+ -1, -1, 66, 67, -1, -1, 70, -1, -1, -1,
+ -1, -1, -1, 77, -1, -1, -1, -1, 82, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 94, 95, -1, -1, -1, 99, -1, -1, -1, -1,
+ 104, -1, 106, -1, -1, -1, -1, 111, -1, -1,
+ -1, 115, 116, 117, -1, -1, 120, -1, 122, 123,
+ -1, -1, 126, -1, -1, -1, -1, -1, -1, -1,
+ 134, 135, -1, 137, -1, 139, 140, 141, -1, -1,
+ 144, -1, -1, -1, -1, -1, -1, 151, -1, 153,
+ -1, -1, -1, -1, 158, -1, 160, 161, -1, -1,
+ -1, -1, -1, 167, 168, 3, -1, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, -1, -1, 17,
+ -1, -1, -1, -1, 22, 23, 24, -1, 26, -1,
+ -1, -1, 30, -1, -1, -1, 34, -1, -1, -1,
+ 38, 39, -1, -1, -1, -1, 44, -1, 46, 47,
+ -1, -1, 50, 51, 52, 53, 54, 55, -1, -1,
+ -1, -1, -1, -1, -1, 63, -1, -1, 66, 67,
+ -1, -1, 70, -1, -1, -1, -1, -1, -1, 77,
+ -1, -1, -1, -1, 82, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 94, 95, -1, -1,
+ -1, 99, -1, -1, -1, -1, 104, -1, 106, -1,
+ -1, -1, -1, 111, -1, -1, -1, 115, 116, 117,
+ -1, -1, 120, -1, 122, 123, -1, -1, 126, -1,
+ -1, -1, -1, -1, -1, -1, 134, 135, -1, 137,
+ -1, 139, 140, 141, -1, -1, 144, -1, -1, -1,
+ -1, -1, -1, 151, -1, 153, -1, -1, -1, -1,
+ 158, -1, 160, 161, -1, -1, -1, -1, -1, 167,
+ 168, 3, -1, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, -1, -1, 17, -1, -1, -1, -1,
+ 22, 23, -1, -1, 26, -1, -1, -1, 30, -1,
+ -1, -1, 34, -1, -1, -1, 38, 39, -1, -1,
+ -1, -1, 44, -1, 46, 47, -1, -1, 50, 51,
+ 52, 53, 54, 55, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 66, 67, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 77, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 95, -1, -1, -1, 99, -1, -1,
+ -1, -1, 104, -1, 106, -1, -1, -1, -1, 111,
+ -1, -1, -1, 115, 116, 117, -1, -1, 120, -1,
+ 122, 123, -1, -1, 126, -1, -1, -1, -1, -1,
+ -1, -1, 134, 135, -1, 137, -1, 139, 140, -1,
+ -1, -1, 144, -1, -1, -1, -1, -1, -1, 151,
+ -1, 153, -1, -1, -1, -1, -1, -1, 160, 161,
+ -1, -1, -1, -1, -1, 167, 168, 3, -1, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1,
+ -1, 17, -1, -1, -1, -1, 22, 23, -1, -1,
+ 26, -1, -1, -1, 30, -1, -1, -1, 34, -1,
+ -1, -1, 38, 39, -1, -1, -1, -1, 44, -1,
+ 46, 47, -1, -1, 50, 51, 52, 53, 54, 55,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 66, 67, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 77, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 95,
+ -1, -1, -1, -1, -1, -1, -1, -1, 104, -1,
+ 106, -1, -1, -1, -1, 111, -1, -1, -1, 115,
+ 116, -1, -1, -1, -1, -1, 122, 123, -1, -1,
+ 126, -1, -1, -1, -1, -1, -1, -1, 134, 135,
+ -1, 137, -1, -1, -1, -1, 142, -1, 144, -1,
+ -1, -1, -1, -1, -1, 151, -1, 153, -1, -1,
+ -1, -1, -1, -1, 160, -1, -1, -1, -1, -1,
+ -1, 167, 168, 3, -1, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, -1, 17, -1, -1,
+ -1, -1, 22, 23, -1, -1, 26, -1, -1, -1,
+ 30, -1, -1, -1, 34, -1, -1, -1, 38, 39,
+ -1, -1, -1, -1, 44, -1, 46, 47, -1, -1,
+ 50, 51, 52, 53, 54, 55, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 66, 67, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 77, -1, -1,
+ 6, 7, 8, 9, 10, -1, -1, 13, 14, -1,
+ -1, -1, -1, -1, -1, 95, 22, 23, -1, -1,
+ -1, -1, -1, -1, 104, -1, 106, -1, 34, -1,
+ -1, 111, 38, -1, -1, 115, 116, -1, -1, -1,
+ 46, 47, 122, 123, -1, 51, 126, -1, 54, 55,
+ -1, -1, -1, -1, 134, 135, -1, 137, -1, -1,
+ 66, 67, -1, -1, 144, -1, -1, -1, -1, -1,
+ -1, 151, -1, 153, -1, -1, -1, -1, -1, -1,
+ 160, 6, 7, 8, 9, 10, -1, 167, 168, -1,
+ -1, -1, -1, -1, -1, 6, 7, 8, 9, 10,
+ 106, -1, 13, 14, -1, -1, -1, -1, -1, 115,
+ -1, 22, 23, 38, -1, -1, 122, 123, -1, -1,
+ 126, -1, -1, 34, -1, -1, 51, 38, 134, 135,
+ 55, 137, -1, 139, 140, 46, 47, -1, 144, -1,
+ 51, -1, -1, 54, 55, -1, -1, 153, -1, -1,
+ -1, -1, -1, -1, -1, 66, 67, -1, -1, -1,
+ -1, 167, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 106, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 106, -1, -1, -1, -1,
+ -1, 126, -1, -1, 115, -1, -1, -1, -1, -1,
+ 135, 122, 123, -1, -1, 126, -1, -1, -1, 144,
+ -1, -1, -1, 134, 135, -1, 137, -1, 153, -1,
+ -1, -1, -1, 144, -1, -1, -1, -1, -1, -1,
+ -1, -1, 153
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 165, 170, 171, 163, 0, 102, 173, 174, 175,
+ 176, 3, 5, 404, 104, 176, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 17, 22, 23, 24, 26,
+ 30, 34, 38, 39, 44, 46, 47, 50, 51, 52,
+ 53, 54, 55, 63, 66, 67, 70, 77, 82, 83,
+ 94, 95, 99, 104, 106, 111, 115, 116, 117, 120,
+ 122, 123, 126, 134, 135, 137, 139, 140, 141, 144,
+ 151, 153, 158, 160, 161, 167, 168, 177, 183, 184,
+ 186, 187, 189, 190, 191, 192, 193, 194, 195, 197,
+ 200, 201, 202, 204, 208, 211, 213, 219, 225, 226,
+ 227, 232, 233, 240, 253, 254, 260, 267, 276, 277,
+ 278, 279, 280, 281, 283, 285, 286, 289, 290, 291,
+ 292, 293, 294, 295, 296, 298, 300, 302, 303, 304,
+ 306, 307, 309, 310, 311, 322, 323, 324, 327, 328,
+ 329, 331, 332, 333, 334, 335, 336, 337, 338, 339,
+ 340, 342, 343, 344, 345, 347, 348, 349, 358, 359,
+ 360, 361, 362, 365, 366, 367, 368, 375, 382, 383,
+ 384, 386, 387, 388, 389, 390, 391, 392, 394, 397,
+ 399, 400, 404, 405, 59, 172, 7, 44, 100, 229,
+ 330, 95, 166, 364, 395, 95, 404, 7, 397, 405,
+ 95, 364, 395, 148, 26, 28, 40, 41, 45, 71,
+ 104, 110, 112, 152, 162, 364, 95, 395, 7, 341,
+ 405, 95, 364, 395, 52, 52, 6, 7, 401, 95,
+ 102, 136, 364, 44, 132, 225, 42, 218, 395, 150,
+ 7, 402, 405, 7, 95, 218, 374, 395, 95, 95,
+ 310, 310, 52, 312, 364, 395, 95, 90, 145, 7,
+ 218, 218, 37, 37, 114, 15, 61, 68, 72, 73,
+ 74, 75, 76, 77, 78, 80, 88, 93, 96, 105,
+ 121, 297, 299, 301, 99, 117, 155, 282, 49, 81,
+ 101, 144, 284, 25, 159, 287, 64, 87, 288, 86,
+ 156, 32, 33, 293, 218, 42, 305, 307, 69, 97,
+ 139, 140, 321, 91, 325, 36, 91, 95, 404, 138,
+ 185, 73, 104, 7, 231, 405, 95, 38, 55, 126,
+ 153, 333, 7, 132, 144, 396, 405, 218, 369, 370,
+ 373, 218, 356, 404, 42, 95, 218, 364, 124, 146,
+ 188, 124, 146, 212, 108, 124, 198, 35, 55, 71,
+ 113, 364, 7, 397, 194, 103, 181, 182, 364, 218,
+ 385, 392, 394, 144, 397, 372, 373, 397, 341, 341,
+ 350, 225, 104, 205, 45, 104, 203, 52, 104, 132,
+ 225, 218, 149, 308, 404, 7, 404, 305, 397, 397,
+ 341, 218, 218, 225, 227, 227, 278, 279, 280, 280,
+ 280, 281, 283, 285, 286, 289, 109, 18, 18, 18,
+ 43, 225, 311, 142, 311, 225, 23, 326, 333, 389,
+ 225, 226, 227, 346, 403, 404, 7, 314, 315, 37,
+ 132, 37, 132, 305, 397, 356, 132, 356, 225, 314,
+ 403, 185, 185, 37, 404, 104, 104, 57, 196, 7,
+ 399, 405, 73, 404, 185, 397, 98, 95, 317, 52,
+ 132, 37, 132, 37, 132, 363, 18, 377, 377, 353,
+ 132, 7, 403, 55, 7, 403, 341, 7, 43, 119,
+ 132, 132, 132, 132, 377, 132, 58, 89, 378, 380,
+ 381, 382, 389, 397, 378, 376, 381, 376, 43, 113,
+ 143, 246, 252, 130, 130, 132, 185, 73, 132, 157,
+ 316, 318, 319, 397, 398, 398, 371, 43, 132, 185,
+ 84, 107, 199, 185, 403, 403, 79, 92, 185, 95,
+ 3, 403, 185, 95, 316, 377, 341, 398, 398, 305,
+ 378, 85, 21, 239, 351, 354, 401, 154, 73, 21,
+ 206, 104, 73, 206, 377, 73, 85, 268, 395, 395,
+ 117, 127, 144, 379, 127, 29, 113, 131, 227, 247,
+ 248, 37, 52, 132, 132, 185, 185, 185, 52, 215,
+ 216, 42, 364, 178, 132, 305, 377, 127, 393, 393,
+ 227, 52, 85, 118, 73, 227, 207, 403, 185, 185,
+ 20, 3, 227, 31, 269, 29, 311, 19, 48, 249,
+ 37, 318, 341, 341, 37, 132, 313, 185, 23, 139,
+ 140, 220, 221, 222, 223, 224, 322, 345, 185, 20,
+ 65, 209, 132, 132, 261, 341, 227, 353, 16, 129,
+ 355, 56, 37, 227, 255, 52, 273, 60, 196, 250,
+ 248, 377, 377, 216, 214, 225, 223, 223, 25, 179,
+ 139, 140, 139, 140, 227, 20, 210, 262, 234, 75,
+ 128, 352, 356, 356, 227, 403, 241, 256, 397, 378,
+ 35, 166, 251, 20, 320, 377, 43, 221, 132, 223,
+ 223, 224, 224, 227, 185, 37, 133, 263, 266, 235,
+ 357, 16, 129, 37, 164, 233, 240, 242, 244, 245,
+ 246, 37, 257, 266, 18, 270, 403, 35, 227, 65,
+ 217, 218, 100, 228, 52, 227, 37, 233, 236, 240,
+ 244, 4, 27, 218, 348, 404, 52, 227, 131, 52,
+ 131, 227, 185, 230, 231, 125, 180, 341, 52, 397,
+ 341, 245, 227, 341, 227, 37, 404, 317, 377, 341,
+ 75, 377, 131, 377, 271, 231, 377, 85, 377, 20,
+ 227, 85, 45, 269, 272, 274, 305, 227, 239, 227,
+ 227, 52, 131, 185, 264, 85, 243, 258, 397, 227,
+ 265, 227, 242, 259, 275, 263, 237, 257, 131, 238,
+ 227, 236
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, parseInfo, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, parseInfo)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, parseInfo); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (parseInfo);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parseInfo);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, ParserContext *const parseInfo)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, parseInfo)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ ParserContext *const parseInfo;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , parseInfo);
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, parseInfo); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, ParserContext *const parseInfo)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, parseInfo)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ ParserContext *const parseInfo;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (parseInfo);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (ParserContext *const parseInfo);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (ParserContext *const parseInfo)
+#else
+int
+yyparse (parseInfo)
+ ParserContext *const parseInfo;
+#endif
+#endif
+{
+ /* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+#if YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+ YYSTACK_RELOCATE (yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 5:
+/* Line 1269 of yacc.c. */
+#line 1380 "querytransformparser.ypp"
+ {
+
+/* Suppress more compiler warnings about unused defines. */
+#if defined(YYNNTS) \
+ || defined(yyerrok) \
+ || defined(YYNSTATES) \
+ || defined(YYRHSLOC) \
+ || defined(YYRECOVERING) \
+ || defined(YYFAIL) \
+ || defined(YYERROR) \
+ || defined(YYNRULES) \
+ || defined(YYBACKUP) \
+ || defined(YYMAXDEPTH) \
+ || defined(yyclearin) \
+ || defined(YYERRCODE) \
+ || defined(YY_LOCATION_PRINT) \
+ || defined(YYLLOC_DEFAULT)
+#endif
+
+ if((yyvsp[(3) - (5)].sval) != QLatin1String("1.0"))
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
+ "XQuery version is 1.0.")
+ .arg(formatData((yyvsp[(3) - (5)].sval))),
+ ReportContext::XQST0031, &ryy);
+ }
+ }
+ break;
+
+ case 7:
+/* Line 1269 of yacc.c. */
+#line 1412 "querytransformparser.ypp"
+ {
+ const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
+
+ if(!encNameRegExp.exactMatch((yyvsp[(2) - (2)].sval)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
+ "It must contain Latin characters only, "
+ "must not contain whitespace, and must match "
+ "the regular expression %2.")
+ .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
+ formatExpression(encNameRegExp.pattern())),
+ ReportContext::XQST0087, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 8:
+/* Line 1269 of yacc.c. */
+#line 1428 "querytransformparser.ypp"
+ {
+ /* In XSL-T, we can have dangling variable references, so resolve them
+ * before we proceed with other steps, such as checking circularity. */
+ if(parseInfo->isXSLT())
+ {
+ typedef QHash<QXmlName, Expression::Ptr> Hash;
+ const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
+
+ for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
+ {
+ const Expression::Ptr body(resolveVariable(it.key(), (yyloc), parseInfo, true)); // TODO source locations vaise
+ Q_ASSERT(body);
+ it.value()->as<UnresolvedVariableReference>()->bindTo(body);
+ }
+ }
+
+ /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
+ {
+ const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
+ UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
+ for(; cit != cend; ++cit) /* For each callsite. */
+ {
+ const UserFunctionCallsite::Ptr callsite(*cit);
+ Q_ASSERT(callsite);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it) /* For each UserFunction. */
+ {
+ const FunctionSignature::Ptr sign((*it)->signature());
+ Q_ASSERT(sign);
+
+ if(callsite->isSignatureValid(sign))
+ {
+ callsite->setSource((*it),
+ parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
+ break;
+ }
+ }
+ if(it == end)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
+ .arg(formatFunction(callsite)),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+
+ /* Mark callsites in UserFunction bodies as recursive, if they are. */
+ {
+ const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
+ for(; fit != fend; ++fit)
+ {
+ CallTargetDescription::List signList;
+ signList.append((*fit)->signature());
+ CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
+ }
+ }
+
+ /* Now, check all global variables for circularity. This is done
+ * backwards because global variables are only in scope below them,
+ * in XQuery. */
+ {
+ const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
+ VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
+ continue; /* We want to ignore 'external' variables. */
+
+ FunctionSignature::List signList;
+ checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
+ ExpressionFactory::registerLastPath((*it)->expression());
+ parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
+ }
+ }
+
+ /* Generate code for doing initial template name calling. One problem
+ * is that we compilation in the initial template name, since we throw away the
+ * code if we don't have the requested template. */
+ if(parseInfo->languageAccent == QXmlQuery::XSLT20
+ && !parseInfo->initialTemplateName.isNull()
+ && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
+ {
+ parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
+ WithParam::Hash()),
+ (yyloc), parseInfo);
+ parseInfo->templateCalls.append(parseInfo->queryBody);
+ /* We just discard the template body that XSLTTokenizer generated. */
+ }
+ else
+ parseInfo->queryBody = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 10:
+/* Line 1269 of yacc.c. */
+#line 1528 "querytransformparser.ypp"
+ {
+ // TODO add to namespace context
+ parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(3) - (6)].sval));
+ }
+ break;
+
+ case 12:
+/* Line 1269 of yacc.c. */
+#line 1536 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 13:
+/* Line 1269 of yacc.c. */
+#line 1543 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 14:
+/* Line 1269 of yacc.c. */
+#line 1549 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 15:
+/* Line 1269 of yacc.c. */
+#line 1555 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 17:
+/* Line 1269 of yacc.c. */
+#line 1565 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 18:
+/* Line 1269 of yacc.c. */
+#line 1569 "querytransformparser.ypp"
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 19:
+/* Line 1269 of yacc.c. */
+#line 1573 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->hasSecondPrologPart = true;
+ }
+ break;
+
+ case 20:
+/* Line 1269 of yacc.c. */
+#line 1596 "querytransformparser.ypp"
+ {
+ Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, (yyvsp[(5) - (7)].sequenceType)), (yyloc), parseInfo));
+
+ registerNamedTemplate((yyvsp[(3) - (7)].qName), typeCheckTemplateBody((yyvsp[(6) - (7)].expr), (yyvsp[(5) - (7)].sequenceType), parseInfo),
+ parseInfo, (yylsp[(1) - (7)]), temp);
+ temp->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+ }
+ break;
+
+ case 21:
+/* Line 1269 of yacc.c. */
+#line 1606 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = true;
+ }
+ break;
+
+ case 22:
+/* Line 1269 of yacc.c. */
+#line 1610 "querytransformparser.ypp"
+ {
+ parseInfo->isParsingPattern = false;
+ }
+ break;
+
+ case 23:
+/* Line 1269 of yacc.c. */
+#line 1619 "querytransformparser.ypp"
+ {
+ /* In this grammar branch, we're guaranteed to be a template rule, but
+ * may also be a named template. */
+
+ const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
+ Expression::Ptr pattern((yyvsp[(7) - (15)].expr));
+ const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
+
+ Template::Ptr templ(create(new Template(ip, (yyvsp[(13) - (15)].sequenceType)), (yyloc), parseInfo));
+ templ->body = typeCheckTemplateBody((yyvsp[(14) - (15)].expr), (yyvsp[(13) - (15)].sequenceType), parseInfo);
+ templ->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+
+ TemplatePattern::Vector ourPatterns;
+ /* We do it as per 6.4 Conflict Resolution for Template Rules:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives." */
+ while(pattern->is(Expression::IDCombineNodes))
+ {
+ const Expression::List operands(pattern->operands());
+ pattern = operands.first();
+
+ loadPattern(operands.at(1), ourPatterns, templateID, (yyvsp[(11) - (15)].enums.Double), templ);
+ }
+
+ loadPattern(pattern, ourPatterns, templateID, (yyvsp[(11) - (15)].enums.Double), templ);
+
+ if(!(yyvsp[(3) - (15)].qName).isNull())
+ registerNamedTemplate((yyvsp[(3) - (15)].qName), (yyvsp[(14) - (15)].expr), parseInfo, (yylsp[(1) - (15)]), templ);
+
+ /* Now, let's add it to all the relevant templates. */
+ for(int i = 0; i < (yyvsp[(10) - (15)].qNameVector).count(); ++i) /* For each mode. */
+ {
+ const QXmlName &modeName = (yyvsp[(10) - (15)].qNameVector).at(i);
+
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && (yyvsp[(10) - (15)].qNameVector).count() > 1)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
+ .arg(formatKeyword(QLatin1String("#all"))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ /* For each pattern the template use. */
+ const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
+ for(int t = 0; t < ourPatterns.count(); ++t)
+ mode->templatePatterns.append(ourPatterns.at(t));
+ }
+ }
+ break;
+
+ case 24:
+/* Line 1269 of yacc.c. */
+#line 1673 "querytransformparser.ypp"
+ {
+ (yyval.enums.Double) = std::numeric_limits<xsDouble>::quiet_NaN();
+ }
+ break;
+
+ case 25:
+/* Line 1269 of yacc.c. */
+#line 1678 "querytransformparser.ypp"
+ {
+ const AtomicValue::Ptr val(Decimal::fromLexical((yyvsp[(2) - (2)].sval)));
+ if(val->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
+ .arg(formatKeyword(QLatin1String("priority")),
+ formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
+ formatData((yyvsp[(2) - (2)].sval))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ (yyval.enums.Double) = val->as<Numeric>()->toDouble();
+ }
+ break;
+
+ case 26:
+/* Line 1269 of yacc.c. */
+#line 1694 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 28:
+/* Line 1269 of yacc.c. */
+#line 1700 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 30:
+/* Line 1269 of yacc.c. */
+#line 1706 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 32:
+/* Line 1269 of yacc.c. */
+#line 1711 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 33:
+/* Line 1269 of yacc.c. */
+#line 1715 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 34:
+/* Line 1269 of yacc.c. */
+#line 1719 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 39:
+/* Line 1269 of yacc.c. */
+#line 1730 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(6) - (7)].enums.Bool))
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+
+ if((yyvsp[(3) - (7)].sval) == QLatin1String("xmlns"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
+ .arg(formatKeyword(QLatin1String("xmlns"))),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if ((yyvsp[(5) - (7)].sval) == CommonNamespaces::XML || (yyvsp[(3) - (7)].sval) == QLatin1String("xml"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The prefix %1 cannot be bound. By default, it is already bound "
+ "to the namespace %2.")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(CommonNamespaces::XML)),
+ ReportContext::XQST0070,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(parseInfo->declaredPrefixes.contains((yyvsp[(3) - (7)].sval)))
+ {
+ /* This includes the case where the user has bound a default prefix(such
+ * as 'local') and now tries to do it again. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
+ .arg(formatKeyword((yyvsp[(3) - (7)].sval))),
+ ReportContext::XQST0033, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->declaredPrefixes.append((yyvsp[(3) - (7)].sval));
+
+ if((yyvsp[(5) - (7)].sval).isEmpty())
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix((yyvsp[(3) - (7)].sval))));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding((yyvsp[(3) - (7)].sval), (yyvsp[(5) - (7)].sval)));
+ }
+ }
+ }
+ break;
+
+ case 40:
+/* Line 1269 of yacc.c. */
+#line 1776 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare boundary-space"),
+ ReportContext::XQST0068, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setBoundarySpacePolicy((yyvsp[(3) - (4)].enums.boundarySpacePolicy));
+ parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
+ }
+ }
+ break;
+
+ case 41:
+/* Line 1269 of yacc.c. */
+#line 1790 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPStrip;
+ }
+ break;
+
+ case 42:
+/* Line 1269 of yacc.c. */
+#line 1795 "querytransformparser.ypp"
+ {
+ (yyval.enums.boundarySpacePolicy) = StaticContext::BSPPreserve;
+ }
+ break;
+
+ case 45:
+/* Line 1269 of yacc.c. */
+#line 1804 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default element namespace"),
+ ReportContext::XQST0066, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(5) - (6)].sval)), StandardLocalNames::empty));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
+ }
+ }
+ break;
+
+ case 46:
+/* Line 1269 of yacc.c. */
+#line 1819 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default function namespace"),
+ ReportContext::XQST0066, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setDefaultFunctionNamespace((yyvsp[(5) - (6)].sval));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
+ }
+ }
+ break;
+
+ case 47:
+/* Line 1269 of yacc.c. */
+#line 1833 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (5)].qName).prefix() == StandardPrefixes::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
+ "There is no default namespace for options."),
+ ReportContext::XPST0081, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 48:
+/* Line 1269 of yacc.c. */
+#line 1843 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0065, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
+ parseInfo->staticContext->setOrderingMode((yyvsp[(3) - (4)].enums.orderingMode));
+ }
+ }
+ break;
+
+ case 49:
+/* Line 1269 of yacc.c. */
+#line 1858 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Ordered;
+ }
+ break;
+
+ case 50:
+/* Line 1269 of yacc.c. */
+#line 1862 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingMode) = StaticContext::Unordered;
+ }
+ break;
+
+ case 51:
+/* Line 1269 of yacc.c. */
+#line 1867 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default order"),
+ ReportContext::XQST0069, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
+ parseInfo->staticContext->setOrderingEmptySequence((yyvsp[(4) - (5)].enums.orderingEmptySequence));
+ }
+ }
+ break;
+
+ case 52:
+/* Line 1269 of yacc.c. */
+#line 1881 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Least;
+ }
+ break;
+
+ case 53:
+/* Line 1269 of yacc.c. */
+#line 1885 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = StaticContext::Greatest;
+ }
+ break;
+
+ case 54:
+/* Line 1269 of yacc.c. */
+#line 1891 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
+ ReportContext::XQST0055, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
+ }
+ }
+ break;
+
+ case 55:
+/* Line 1269 of yacc.c. */
+#line 1904 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = true;
+ }
+ break;
+
+ case 56:
+/* Line 1269 of yacc.c. */
+#line 1909 "querytransformparser.ypp"
+ {
+ parseInfo->preserveNamespacesMode = false;
+ }
+ break;
+
+ case 57:
+/* Line 1269 of yacc.c. */
+#line 1914 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = true;
+ }
+ break;
+
+ case 58:
+/* Line 1269 of yacc.c. */
+#line 1919 "querytransformparser.ypp"
+ {
+ parseInfo->inheritNamespacesMode = false;
+ }
+ break;
+
+ case 59:
+/* Line 1269 of yacc.c. */
+#line 1924 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default collation"),
+ ReportContext::XQST0038, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>((yyvsp[(4) - (5)].sval), parseInfo, (yyloc)));
+
+ parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
+ parseInfo->staticContext->setDefaultCollation(coll);
+ }
+ }
+ break;
+
+ case 60:
+/* Line 1269 of yacc.c. */
+#line 1940 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc), (yyvsp[(3) - (5)].enums.Bool));
+ if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare base-uri"),
+ ReportContext::XQST0032, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>((yyvsp[(4) - (5)].sval), parseInfo->staticContext, &ryy));
+ /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */
+
+ if(toBeBase.isRelative())
+ toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
+
+ parseInfo->staticContext->setBaseURI(toBeBase);
+ }
+ }
+ break;
+
+ case 61:
+/* Line 1269 of yacc.c. */
+#line 1963 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
+ "and therefore %1 declarations cannot occur.")
+ .arg(formatKeyword("import schema")),
+ ReportContext::XQST0009, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 65:
+/* Line 1269 of yacc.c. */
+#line 1975 "querytransformparser.ypp"
+ {
+ if((yyvsp[(4) - (6)].sval).isEmpty())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
+ .arg(formatKeyword("module import")),
+ ReportContext::XQST0088, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ {
+ /* This is temporary until we have implemented it. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
+ ReportContext::XQST0016, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 72:
+/* Line 1269 of yacc.c. */
+#line 2002 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (9)].enums.Bool));
+ if(variableByName((yyvsp[(5) - (9)].qName), parseInfo))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A variable with name %1 has already "
+ "been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical((yyvsp[(5) - (9)].qName)))),
+ parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ if((yyvsp[(7) - (9)].expr)) /* We got a value assigned. */
+ {
+ const Expression::Ptr checked
+ (TypeChecker::applyFunctionConversion((yyvsp[(7) - (9)].expr), (yyvsp[(6) - (9)].sequenceType), parseInfo->staticContext,
+ (yyvsp[(3) - (9)].enums.Bool) ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ (yyvsp[(3) - (9)].enums.Bool) ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));
+
+ pushVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType), checked, VariableDeclaration::GlobalVariable, (yyloc), parseInfo);
+ parseInfo->declaredVariables.append(parseInfo->variables.last());
+ }
+ else /* We got an 'external' declaration. */
+ {
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType)));
+
+ if(varType)
+ {
+ /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
+ * any references to it. */
+ pushVariable((yyvsp[(5) - (9)].qName), varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, (yyloc), parseInfo);
+ }
+ else if((yyvsp[(8) - (9)].expr))
+ {
+ /* Ok, the xsl:param got a default value, we make it
+ * available as a regular variable declaration. */
+ // TODO turn into checked
+ pushVariable((yyvsp[(5) - (9)].qName), (yyvsp[(6) - (9)].sequenceType), (yyvsp[(8) - (9)].expr), VariableDeclaration::GlobalVariable, (yyloc), parseInfo);
+ // TODO ensure that duplicates are trapped.
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
+ "variable with name %1.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (9)].qName))),
+ parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+ }
+ break;
+
+ case 73:
+/* Line 1269 of yacc.c. */
+#line 2056 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 74:
+/* Line 1269 of yacc.c. */
+#line 2060 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 75:
+/* Line 1269 of yacc.c. */
+#line 2065 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 76:
+/* Line 1269 of yacc.c. */
+#line 2069 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 77:
+/* Line 1269 of yacc.c. */
+#line 2074 "querytransformparser.ypp"
+ {
+ if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0067, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
+ parseInfo->staticContext->setConstructionMode((yyvsp[(3) - (4)].enums.constructionMode));
+ }
+ }
+ break;
+
+ case 78:
+/* Line 1269 of yacc.c. */
+#line 2088 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMStrip;
+ }
+ break;
+
+ case 79:
+/* Line 1269 of yacc.c. */
+#line 2092 "querytransformparser.ypp"
+ {
+ (yyval.enums.constructionMode) = StaticContext::CMPreserve;
+ }
+ break;
+
+ case 80:
+/* Line 1269 of yacc.c. */
+#line 2097 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = parseInfo->currentExpressionSlot() - (yyvsp[(6) - (7)].functionArguments).count();
+ }
+ break;
+
+ case 81:
+/* Line 1269 of yacc.c. */
+#line 2101 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (11)].enums.Bool))
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(3) - (11)].enums.Bool));
+
+ /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
+ const QXmlName::NamespaceCode ns((yyvsp[(4) - (11)].qName).namespaceURI());
+
+ if(parseInfo->isXSLT() && !(yyvsp[(4) - (11)].qName).hasPrefix())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
+ ReportContext::XTSE0740,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if((yyvsp[(10) - (11)].expr)) /* We got a function body. */
+ {
+ if(ns == StandardNamespaces::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
+ "cannot be empty (try the predefined "
+ "prefix %1 which exists for cases "
+ "like this)")
+ .arg(formatKeyword("local")),
+ ReportContext::XQST0060, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(XPathHelper::isReservedNamespace(ns))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace %1 is reserved; therefore "
+ "user defined functions may not use it. "
+ "Try the predefined prefix %2, which "
+ "exists for these cases.")
+ .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
+ parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
+ ns != parseInfo->moduleNamespace)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace of a user defined "
+ "function in a library module must be "
+ "equivalent to the module namespace. "
+ "In other words, it should be %1 instead "
+ "of %2")
+ .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
+ formatURI(parseInfo->staticContext->namePool(), ns)),
+ ReportContext::XQST0048, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ /* Apply function conversion such that the body matches the declared
+ * return type. */
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion((yyvsp[(10) - (11)].expr), (yyvsp[(9) - (11)].sequenceType),
+ parseInfo->staticContext,
+ ReportContext::XPTY0004,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert |
+ TypeChecker::CheckFocus |
+ TypeChecker::GeneratePromotion)));
+
+ const int argCount = (yyvsp[(6) - (11)].functionArguments).count();
+ const FunctionSignature::Ptr sign(new FunctionSignature((yyvsp[(4) - (11)].qName) /* name */,
+ argCount /* minArgs */,
+ argCount /* maxArgs */,
+ (yyvsp[(9) - (11)].sequenceType) /* returnType */));
+ sign->setArguments((yyvsp[(6) - (11)].functionArguments));
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(*(*it)->signature() == *sign)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
+ "the signature %1.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
+ parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+
+ VariableDeclaration::List argDecls;
+
+ for(int i = 0; i < argCount; ++i)
+ argDecls.append(parseInfo->variables.at(i));
+
+ if((yyvsp[(8) - (11)].enums.slot) > -1)
+ {
+ /* We have allocated slots, so now push them out of scope. */
+ parseInfo->finalizePushedVariable(argCount);
+ }
+
+ parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, (yyvsp[(8) - (11)].enums.slot), argDecls)));
+ }
+ }
+ else /* We got an 'external' declaration. */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
+ "All supported functions can be used directly, "
+ "without first declaring them as external"),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 82:
+/* Line 1269 of yacc.c. */
+#line 2205 "querytransformparser.ypp"
+ {
+ (yyval.functionArguments) = FunctionArgument::List();
+ }
+ break;
+
+ case 83:
+/* Line 1269 of yacc.c. */
+#line 2209 "querytransformparser.ypp"
+ {
+ FunctionArgument::List l;
+ l.append((yyvsp[(1) - (1)].functionArgument));
+ (yyval.functionArguments) = l;
+ }
+ break;
+
+ case 84:
+/* Line 1269 of yacc.c. */
+#line 2215 "querytransformparser.ypp"
+ {
+ FunctionArgument::List::const_iterator it((yyvsp[(1) - (3)].functionArguments).constBegin());
+ const FunctionArgument::List::const_iterator end((yyvsp[(1) - (3)].functionArguments).constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name() == (yyvsp[(3) - (3)].functionArgument)->name())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An argument with name %1 has already "
+ "been declared. Every argument name "
+ "must be unique.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (3)].functionArgument)->name())),
+ ReportContext::XQST0039, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+
+ (yyvsp[(1) - (3)].functionArguments).append((yyvsp[(3) - (3)].functionArgument));
+ (yyval.functionArguments) = (yyvsp[(1) - (3)].functionArguments);
+ }
+ break;
+
+ case 85:
+/* Line 1269 of yacc.c. */
+#line 2236 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType), Expression::Ptr(), VariableDeclaration::FunctionArgument, (yyloc), parseInfo);
+ (yyval.functionArgument) = FunctionArgument::Ptr(new FunctionArgument((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType)));
+ }
+ break;
+
+ case 86:
+/* Line 1269 of yacc.c. */
+#line 2242 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 88:
+/* Line 1269 of yacc.c. */
+#line 2248 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 91:
+/* Line 1269 of yacc.c. */
+#line 2264 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 93:
+/* Line 1269 of yacc.c. */
+#line 2270 "querytransformparser.ypp"
+ {
+ /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
+ * "Similarly, / matches a document node, and only a document node,
+ * because the result of the expression root(.)//(/) returns the root
+ * node of the tree containing the context node if and only if it is a
+ * document node." */
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), (yyloc), parseInfo);
+ }
+ break;
+
+ case 94:
+/* Line 1269 of yacc.c. */
+#line 2279 "querytransformparser.ypp"
+ {
+ /* /axis::node-test
+ * =>
+ * axis::node-test[parent::document-node()]
+ *
+ * In practice it looks like this. $2 is:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep parent::element(b)
+ * AxisStep parent::element(a)
+ *
+ * and we want this:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep self::element(b)
+ * TruthPredicate
+ * AxisStep parent::element(a)
+ * AxisStep parent::document()
+ *
+ * So we want to rewrite the predicate deepest down into a
+ * another TruthPredicate containing the AxisStep.
+ *
+ * The simplest case where $2 is only an axis step is special. When $2 is:
+ *
+ * AxisStep self::element(a)
+ *
+ * we want:
+ *
+ * TruthPredicate
+ * AxisStep self::element(a)
+ * AxisStep parent::document()
+ */
+
+ /* First, find the target. */
+ Expression::Ptr target((yyvsp[(2) - (2)].expr));
+
+ while(isPredicate(target->id()))
+ {
+ const Expression::Ptr candidate(target->operands().at(1));
+
+ if(isPredicate(candidate->id()))
+ target = candidate;
+ else
+ break; /* target is now the last predicate. */
+ }
+
+ if(target->is(Expression::IDAxisStep))
+ {
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(2) - (2)].expr), create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo);
+ }
+ else
+ {
+ const Expression::List targetOperands(target->operands());
+ Expression::List newOps;
+ newOps.append(targetOperands.at(0));
+
+ newOps.append(create(GenericPredicate::create(targetOperands.at(1),
+ create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo));
+
+ target->setOperands(newOps);
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ }
+ break;
+
+ case 95:
+/* Line 1269 of yacc.c. */
+#line 2349 "querytransformparser.ypp"
+ {
+ /* //axis::node-test
+ * =>
+ * axis::node-test[parent::node()]
+ *
+ * Spec says: "//para matches any para element that has a parent node."
+ */
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(2) - (2)].expr), create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo),
+ parseInfo->staticContext, fromYYLTYPE((yylsp[(1) - (2)]), parseInfo)), (yylsp[(1) - (2)]), parseInfo);
+ }
+ break;
+
+ case 97:
+/* Line 1269 of yacc.c. */
+#line 2361 "querytransformparser.ypp"
+ {
+ createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 98:
+/* Line 1269 of yacc.c. */
+#line 2365 "querytransformparser.ypp"
+ {
+ createIdPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 99:
+/* Line 1269 of yacc.c. */
+#line 2370 "querytransformparser.ypp"
+ {
+ const Expression::List ands((yyvsp[(1) - (1)].expr)->operands());
+ const FunctionSignature::Ptr signature((yyvsp[(1) - (1)].expr)->as<FunctionCall>()->signature());
+ const QXmlName name(signature->name());
+ const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
+ const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);
+
+ if(name == id)
+ {
+ const Expression::ID id = ands.first()->id();
+ if(!isVariableReference(id) && id != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
+ "the argument must be a variable reference or a string literal.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else if(name == key)
+ {
+ if(ands.first()->id() != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a string literal, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ const Expression::ID id2 = ands.at(1)->id();
+ if(!isVariableReference(id2) &&
+ id2 != Expression::IDStringValue &&
+ id2 != Expression::IDIntegerValue &&
+ id2 != Expression::IDBooleanValue &&
+ id2 != Expression::IDFloat)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a literal or a variable reference, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(ands.count() == 3)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ }
+ else
+ {
+ const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
+ "and %2, not %3, can be used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
+ formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
+ formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ }
+ break;
+
+ case 101:
+/* Line 1269 of yacc.c. */
+#line 2440 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisParent, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 102:
+/* Line 1269 of yacc.c. */
+#line 2444 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createPatternPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), QXmlNodeModelIndex::AxisAncestor, (yylsp[(2) - (3)]), parseInfo);
+ }
+ break;
+
+ case 103:
+/* Line 1269 of yacc.c. */
+#line 2449 "querytransformparser.ypp"
+ {
+ const Expression::Ptr expr(findAxisStep((yyvsp[(1) - (1)].expr)));
+
+ const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
+ AxisStep *const axisStep = expr->as<AxisStep>();
+
+ /* Here we constrain the possible axes, and we rewrite the axes as according
+ * to 5.5.3 The Meaning of a Pattern.
+ *
+ * However, we also rewrite axis child and attribute to axis self. The
+ * reason for this is that if we don't, we will match the children of
+ * the context node, instead of the context node itself. The formal
+ * definition of a pattern, root(.)//EE is insensitive to context,
+ * while the way we implement pattern, "the other way of seeing it",
+ * e.g from right to left, are very much. */
+
+ if(axisStep->nodeTest() == BuiltinTypes::document
+ || axis == QXmlNodeModelIndex::AxisChild)
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ else if(axis == QXmlNodeModelIndex::AxisAttribute)
+ {
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ /* Consider that the user write attribute::node(). This is
+ * semantically equivalent to attribute::attribute(), but since we have changed
+ * the axis to axis self, we also need to change the node test, such that we
+ * have self::attribute(). */
+ if(*axisStep->nodeTest() == *BuiltinTypes::node)
+ axisStep->setNodeTest(BuiltinTypes::attribute);
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
+ "only axis %2 or %3 can.")
+ .arg(formatKeyword(AxisStep::axisName(axis)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
+ ReportContext::XPST0003,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ }
+ break;
+
+ case 105:
+/* Line 1269 of yacc.c. */
+#line 2494 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ExpressionSequence((yyvsp[(1) - (1)].expressionList)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 106:
+/* Line 1269 of yacc.c. */
+#line 2499 "querytransformparser.ypp"
+ {
+ Expression::List l;
+ l.append((yyvsp[(1) - (3)].expr));
+ l.append((yyvsp[(3) - (3)].expr));
+ (yyval.expressionList) = l;
+ }
+ break;
+
+ case 107:
+/* Line 1269 of yacc.c. */
+#line 2506 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (3)].expressionList).append((yyvsp[(3) - (3)].expr));
+ (yyval.expressionList) = (yyvsp[(1) - (3)].expressionList);
+ }
+ break;
+
+ case 113:
+/* Line 1269 of yacc.c. */
+#line 2517 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(3) - (4)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 114:
+/* Line 1269 of yacc.c. */
+#line 2522 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 115:
+/* Line 1269 of yacc.c. */
+#line 2528 "querytransformparser.ypp"
+ {
+ (yyval.qNameVector) = (yyvsp[(2) - (2)].qNameVector);
+ }
+ break;
+
+ case 116:
+/* Line 1269 of yacc.c. */
+#line 2533 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ }
+ break;
+
+ case 117:
+/* Line 1269 of yacc.c. */
+#line 2537 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (2)].qName);
+ }
+ break;
+
+ case 118:
+/* Line 1269 of yacc.c. */
+#line 2542 "querytransformparser.ypp"
+ {
+ QVector<QXmlName> result;
+ result.append((yyvsp[(1) - (1)].qName));
+ (yyval.qNameVector) = result;
+ }
+ break;
+
+ case 119:
+/* Line 1269 of yacc.c. */
+#line 2548 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (3)].qNameVector).append((yyvsp[(3) - (3)].qName));
+ (yyval.qNameVector) = (yyvsp[(1) - (3)].qNameVector);
+ }
+ break;
+
+ case 120:
+/* Line 1269 of yacc.c. */
+#line 2554 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 121:
+/* Line 1269 of yacc.c. */
+#line 2558 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (1)].sval) == QLatin1String("#current"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
+ else if((yyvsp[(1) - (1)].sval) == QLatin1String("#default"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ else if((yyvsp[(1) - (1)].sval) == QLatin1String("#all"))
+ (yyval.qName) = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
+ else
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ if(!QXmlUtils::isNCName((yyvsp[(1) - (1)].sval)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
+ .arg(formatKeyword((yyvsp[(1) - (1)].sval))),
+ ReportContext::XTSE0550,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ }
+ break;
+
+ case 124:
+/* Line 1269 of yacc.c. */
+#line 2587 "querytransformparser.ypp"
+ {
+ /* We're pushing the range variable here, not the positional. */
+ (yyval.expr) = pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 125:
+/* Line 1269 of yacc.c. */
+#line 2591 "querytransformparser.ypp"
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ (yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();
+ }
+ break;
+
+ case 126:
+/* Line 1269 of yacc.c. */
+#line 2598 "querytransformparser.ypp"
+ {
+ Q_ASSERT((yyvsp[(7) - (10)].expr));
+ Q_ASSERT((yyvsp[(10) - (10)].expr));
+
+ /* We want the next last pushed variable, since we push the range variable after the
+ * positional variable. */
+ if((yyvsp[(5) - (10)].enums.slot) != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == (yyvsp[(3) - (10)].qName))
+ {
+ /* Ok, a positional variable is used since its slot is not -1, and its name is equal
+ * to our range variable. This is an error. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
+ "from the positional variable. Hence, the two variables named %1 collide.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (10)].qName))),
+ ReportContext::XQST0089,
+ fromYYLTYPE((yyloc), parseInfo));
+
+ }
+
+ const Expression::Ptr retBody(create(new ForClause((yyvsp[(9) - (10)].enums.slot), (yyvsp[(8) - (10)].expr), (yyvsp[(10) - (10)].expr), (yyvsp[(5) - (10)].enums.slot)), (yyloc), parseInfo));
+ ReturnOrderBy *const rob = locateReturnClause((yyvsp[(10) - (10)].expr));
+
+ if(rob)
+ (yyval.expr) = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), (yyloc), parseInfo);
+ else
+ (yyval.expr) = retBody;
+
+ parseInfo->finalizePushedVariable();
+
+ if((yyvsp[(5) - (10)].enums.slot) != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 127:
+/* Line 1269 of yacc.c. */
+#line 2632 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (7)].qName), quantificationType((yyvsp[(4) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 128:
+/* Line 1269 of yacc.c. */
+#line 2635 "querytransformparser.ypp"
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ (yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();
+ }
+ break;
+
+ case 129:
+/* Line 1269 of yacc.c. */
+#line 2642 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ForClause((yyvsp[(9) - (10)].enums.slot), (yyvsp[(7) - (10)].expr), (yyvsp[(10) - (10)].expr), (yyvsp[(5) - (10)].enums.slot)), (yyloc), parseInfo);
+
+ parseInfo->finalizePushedVariable();
+
+ if((yyvsp[(5) - (10)].enums.slot) != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 133:
+/* Line 1269 of yacc.c. */
+#line 2656 "querytransformparser.ypp"
+ {
+ (yyval.enums.slot) = -1;
+ }
+ break;
+
+ case 134:
+/* Line 1269 of yacc.c. */
+#line 2661 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (3)].qName), CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
+ VariableDeclaration::PositionalVariable, (yyloc), parseInfo);
+ (yyval.enums.slot) = parseInfo->currentPositionSlot();
+ }
+ break;
+
+ case 135:
+/* Line 1269 of yacc.c. */
+#line 2668 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(4) - (7)].qName), quantificationType((yyvsp[(5) - (7)].sequenceType)), (yyvsp[(7) - (7)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 136:
+/* Line 1269 of yacc.c. */
+#line 2672 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (9)].enums.Bool));
+
+ Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(4) - (9)].qName));
+ (yyval.expr) = create(new LetClause((yyvsp[(8) - (9)].expr), (yyvsp[(9) - (9)].expr), parseInfo->variables.top()), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 137:
+/* Line 1269 of yacc.c. */
+#line 2681 "querytransformparser.ypp"
+ { (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr), VariableDeclaration::ExpressionVariable, (yyloc), parseInfo);}
+ break;
+
+ case 138:
+/* Line 1269 of yacc.c. */
+#line 2683 "querytransformparser.ypp"
+ {
+ Q_ASSERT(parseInfo->variables.top()->name == (yyvsp[(3) - (8)].qName));
+ (yyval.expr) = create(new LetClause((yyvsp[(7) - (8)].expr), (yyvsp[(8) - (8)].expr), parseInfo->variables.top()), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 142:
+/* Line 1269 of yacc.c. */
+#line 2694 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (3)].orderSpecs).isEmpty())
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ else
+ (yyval.expr) = createReturnOrderBy((yyvsp[(1) - (3)].orderSpecs), (yyvsp[(3) - (3)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 143:
+/* Line 1269 of yacc.c. */
+#line 2702 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (5)].orderSpecs).isEmpty())
+ (yyval.expr) = create(new IfThenClause((yyvsp[(2) - (5)].expr), (yyvsp[(5) - (5)].expr), create(new EmptySequence, (yyloc), parseInfo)), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new IfThenClause((yyvsp[(2) - (5)].expr), createReturnOrderBy((yyvsp[(3) - (5)].orderSpecs), (yyvsp[(5) - (5)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo),
+ create(new EmptySequence, (yyloc), parseInfo)),
+ (yyloc), parseInfo);
+ }
+ break;
+
+ case 144:
+/* Line 1269 of yacc.c. */
+#line 2712 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = OrderSpecTransfer::List();
+ }
+ break;
+
+ case 146:
+/* Line 1269 of yacc.c. */
+#line 2718 "querytransformparser.ypp"
+ {
+ (yyval.orderSpecs) = (yyvsp[(2) - (2)].orderSpecs);
+ }
+ break;
+
+ case 147:
+/* Line 1269 of yacc.c. */
+#line 2723 "querytransformparser.ypp"
+ {
+ OrderSpecTransfer::List list;
+ list += (yyvsp[(1) - (3)].orderSpecs);
+ list.append((yyvsp[(3) - (3)].orderSpec));
+ (yyval.orderSpecs) = list;
+ }
+ break;
+
+ case 148:
+/* Line 1269 of yacc.c. */
+#line 2730 "querytransformparser.ypp"
+ {
+ OrderSpecTransfer::List list;
+ list.append((yyvsp[(1) - (1)].orderSpec));
+ (yyval.orderSpecs) = list;
+ }
+ break;
+
+ case 149:
+/* Line 1269 of yacc.c. */
+#line 2737 "querytransformparser.ypp"
+ {
+ (yyval.orderSpec) = OrderSpecTransfer((yyvsp[(1) - (4)].expr), OrderBy::OrderSpec((yyvsp[(2) - (4)].enums.sortDirection), (yyvsp[(3) - (4)].enums.orderingEmptySequence)));
+ }
+ break;
+
+ case 150:
+/* Line 1269 of yacc.c. */
+#line 2742 "querytransformparser.ypp"
+ {
+ /* Where does the specification state the default value is ascending?
+ *
+ * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
+ *
+ * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
+ * of values encountered when evaluating their orderspecs from left to right for
+ * which one value is greater-than the other (as defined above), then:
+ *
+ * 1. If V1 is greater-than V2: If the orderspec specifies descending,
+ * then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
+ * 2. If V2 is greater-than V1: If the orderspec specifies descending,
+ * then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
+ *
+ * which means that if you don't specify anything, or you
+ * specify ascending, you get the same result.
+ */
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending;
+ }
+ break;
+
+ case 151:
+/* Line 1269 of yacc.c. */
+#line 2763 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Ascending;
+ }
+ break;
+
+ case 152:
+/* Line 1269 of yacc.c. */
+#line 2768 "querytransformparser.ypp"
+ {
+ (yyval.enums.sortDirection) = OrderBy::OrderSpec::Descending;
+ }
+ break;
+
+ case 153:
+/* Line 1269 of yacc.c. */
+#line 2773 "querytransformparser.ypp"
+ {
+ (yyval.enums.orderingEmptySequence) = parseInfo->staticContext->orderingEmptySequence();
+ }
+ break;
+
+ case 156:
+/* Line 1269 of yacc.c. */
+#line 2780 "querytransformparser.ypp"
+ {
+ if(parseInfo->isXSLT())
+ resolveAndCheckCollation<ReportContext::XTDE1035>((yyvsp[(2) - (2)].sval), parseInfo, (yyloc));
+ else
+ resolveAndCheckCollation<ReportContext::XQST0076>((yyvsp[(2) - (2)].sval), parseInfo, (yyloc));
+ }
+ break;
+
+ case 157:
+/* Line 1269 of yacc.c. */
+#line 2787 "querytransformparser.ypp"
+ {
+ /* We do nothing. We don't use collations, and we have this non-terminal
+ * in order to accept expressions. */
+ }
+ break;
+
+ case 158:
+/* Line 1269 of yacc.c. */
+#line 2793 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::StableOrder);
+ }
+ break;
+
+ case 159:
+/* Line 1269 of yacc.c. */
+#line 2797 "querytransformparser.ypp"
+ {
+ parseInfo->orderStability.push(OrderBy::UnstableOrder);
+ }
+ break;
+
+ case 162:
+/* Line 1269 of yacc.c. */
+#line 2805 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 163:
+/* Line 1269 of yacc.c. */
+#line 2809 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 164:
+/* Line 1269 of yacc.c. */
+#line 2811 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Some, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 165:
+/* Line 1269 of yacc.c. */
+#line 2819 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 166:
+/* Line 1269 of yacc.c. */
+#line 2823 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 167:
+/* Line 1269 of yacc.c. */
+#line 2825 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Some, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 169:
+/* Line 1269 of yacc.c. */
+#line 2834 "querytransformparser.ypp"
+ {
+ pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 170:
+/* Line 1269 of yacc.c. */
+#line 2838 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 171:
+/* Line 1269 of yacc.c. */
+#line 2840 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Every, (yyvsp[(6) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 172:
+/* Line 1269 of yacc.c. */
+#line 2848 "querytransformparser.ypp"
+ {
+ (yyval.expr) = pushVariable((yyvsp[(3) - (6)].qName), quantificationType((yyvsp[(4) - (6)].sequenceType)), (yyvsp[(6) - (6)].expr),
+ VariableDeclaration::RangeVariable, (yyloc), parseInfo);
+ }
+ break;
+
+ case 173:
+/* Line 1269 of yacc.c. */
+#line 2852 "querytransformparser.ypp"
+ {(yyval.enums.slot) = parseInfo->staticContext->currentRangeSlot();}
+ break;
+
+ case 174:
+/* Line 1269 of yacc.c. */
+#line 2854 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new QuantifiedExpression((yyvsp[(8) - (9)].enums.slot),
+ QuantifiedExpression::Every, (yyvsp[(7) - (9)].expr), (yyvsp[(9) - (9)].expr)), (yyloc), parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 176:
+/* Line 1269 of yacc.c. */
+#line 2863 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 177:
+/* Line 1269 of yacc.c. */
+#line 2890 "querytransformparser.ypp"
+ {
+ parseInfo->typeswitchSource.push((yyvsp[(3) - (4)].expr));
+ }
+ break;
+
+ case 178:
+/* Line 1269 of yacc.c. */
+#line 2894 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->typeswitchSource.pop();
+ (yyval.expr) = (yyvsp[(6) - (6)].expr);
+ }
+ break;
+
+ case 179:
+/* Line 1269 of yacc.c. */
+#line 2901 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(2) - (3)].qName).isNull())
+ {
+ pushVariable((yyvsp[(2) - (3)].qName), (yyvsp[(3) - (3)].sequenceType), parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, (yyloc), parseInfo, false);
+ }
+ }
+ break;
+
+ case 180:
+/* Line 1269 of yacc.c. */
+#line 2909 "querytransformparser.ypp"
+ {
+ /* The variable shouldn't be in-scope for other case branches. */
+ if(!(yyvsp[(2) - (6)].qName).isNull())
+ parseInfo->finalizePushedVariable();
+ }
+ break;
+
+ case 181:
+/* Line 1269 of yacc.c. */
+#line 2915 "querytransformparser.ypp"
+ {
+ const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), (yyvsp[(3) - (8)].sequenceType)), (yyloc), parseInfo));
+ (yyval.expr) = create(new IfThenClause(instanceOf, (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 184:
+/* Line 1269 of yacc.c. */
+#line 2924 "querytransformparser.ypp"
+ {
+ (yyval.qName) = QXmlName();
+ }
+ break;
+
+ case 185:
+/* Line 1269 of yacc.c. */
+#line 2929 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(2) - (3)].qName);
+ }
+ break;
+
+ case 186:
+/* Line 1269 of yacc.c. */
+#line 2934 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ }
+ break;
+
+ case 187:
+/* Line 1269 of yacc.c. */
+#line 2938 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (3)].qName).isNull())
+ {
+ pushVariable((yyvsp[(3) - (3)].qName), parseInfo->typeswitchSource.top()->staticType(),
+ parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, (yyloc), parseInfo, false);
+ }
+ }
+ break;
+
+ case 188:
+/* Line 1269 of yacc.c. */
+#line 2947 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(3) - (6)].qName).isNull())
+ parseInfo->finalizePushedVariable();
+ (yyval.expr) = (yyvsp[(6) - (6)].expr);
+ }
+ break;
+
+ case 189:
+/* Line 1269 of yacc.c. */
+#line 2954 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new IfThenClause((yyvsp[(3) - (8)].expr), (yyvsp[(6) - (8)].expr), (yyvsp[(8) - (8)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 191:
+/* Line 1269 of yacc.c. */
+#line 2961 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new OrExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 193:
+/* Line 1269 of yacc.c. */
+#line 2968 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new AndExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 199:
+/* Line 1269 of yacc.c. */
+#line 2980 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new RangeExpression((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 201:
+/* Line 1269 of yacc.c. */
+#line 2987 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 202:
+/* Line 1269 of yacc.c. */
+#line 2992 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Add;}
+ break;
+
+ case 203:
+/* Line 1269 of yacc.c. */
+#line 2993 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Substract;}
+ break;
+
+ case 205:
+/* Line 1269 of yacc.c. */
+#line 2997 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new ArithmeticExpression((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.mathOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 206:
+/* Line 1269 of yacc.c. */
+#line 3002 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Multiply;}
+ break;
+
+ case 207:
+/* Line 1269 of yacc.c. */
+#line 3003 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Div;}
+ break;
+
+ case 208:
+/* Line 1269 of yacc.c. */
+#line 3004 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::IDiv;}
+ break;
+
+ case 209:
+/* Line 1269 of yacc.c. */
+#line 3005 "querytransformparser.ypp"
+ {(yyval.enums.mathOperator) = AtomicMathematician::Mod;}
+ break;
+
+ case 211:
+/* Line 1269 of yacc.c. */
+#line 3009 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10
+ | QXmlQuery::XPath20
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector),
+ parseInfo, (yyloc));
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), CombineNodes::Union, (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 213:
+/* Line 1269 of yacc.c. */
+#line 3020 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CombineNodes((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.combinedNodeOp), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 216:
+/* Line 1269 of yacc.c. */
+#line 3029 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Intersect;
+ }
+ break;
+
+ case 217:
+/* Line 1269 of yacc.c. */
+#line 3033 "querytransformparser.ypp"
+ {
+ (yyval.enums.combinedNodeOp) = CombineNodes::Except;
+ }
+ break;
+
+ case 219:
+/* Line 1269 of yacc.c. */
+#line 3039 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new InstanceOf((yyvsp[(1) - (4)].expr),
+ SequenceType::Ptr((yyvsp[(4) - (4)].sequenceType))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 221:
+/* Line 1269 of yacc.c. */
+#line 3047 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new TreatAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 223:
+/* Line 1269 of yacc.c. */
+#line 3054 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CastableAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 225:
+/* Line 1269 of yacc.c. */
+#line 3061 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new CastAs((yyvsp[(1) - (4)].expr), (yyvsp[(4) - (4)].sequenceType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 227:
+/* Line 1269 of yacc.c. */
+#line 3068 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new UnaryExpression((yyvsp[(1) - (2)].enums.mathOperator), (yyvsp[(2) - (2)].expr), parseInfo->staticContext), (yyloc), parseInfo);
+ }
+ break;
+
+ case 228:
+/* Line 1269 of yacc.c. */
+#line 3074 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Add;
+ }
+ break;
+
+ case 229:
+/* Line 1269 of yacc.c. */
+#line 3078 "querytransformparser.ypp"
+ {
+ (yyval.enums.mathOperator) = AtomicMathematician::Substract;
+ }
+ break;
+
+ case 233:
+/* Line 1269 of yacc.c. */
+#line 3087 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new GeneralComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr), parseInfo->isBackwardsCompat.top()), (yyloc), parseInfo);
+ }
+ break;
+
+ case 234:
+/* Line 1269 of yacc.c. */
+#line 3092 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 235:
+/* Line 1269 of yacc.c. */
+#line 3093 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 236:
+/* Line 1269 of yacc.c. */
+#line 3094 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 237:
+/* Line 1269 of yacc.c. */
+#line 3095 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 238:
+/* Line 1269 of yacc.c. */
+#line 3096 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 239:
+/* Line 1269 of yacc.c. */
+#line 3097 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 240:
+/* Line 1269 of yacc.c. */
+#line 3100 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ValueComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.valueOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 241:
+/* Line 1269 of yacc.c. */
+#line 3104 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorEqual;}
+ break;
+
+ case 242:
+/* Line 1269 of yacc.c. */
+#line 3105 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorNotEqual;}
+ break;
+
+ case 243:
+/* Line 1269 of yacc.c. */
+#line 3106 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterOrEqual;}
+ break;
+
+ case 244:
+/* Line 1269 of yacc.c. */
+#line 3107 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorGreaterThan;}
+ break;
+
+ case 245:
+/* Line 1269 of yacc.c. */
+#line 3108 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessOrEqual;}
+ break;
+
+ case 246:
+/* Line 1269 of yacc.c. */
+#line 3109 "querytransformparser.ypp"
+ {(yyval.enums.valueOperator) = AtomicComparator::OperatorLessThan;}
+ break;
+
+ case 247:
+/* Line 1269 of yacc.c. */
+#line 3112 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NodeComparison((yyvsp[(1) - (3)].expr), (yyvsp[(2) - (3)].enums.nodeOperator), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 248:
+/* Line 1269 of yacc.c. */
+#line 3116 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Is;}
+ break;
+
+ case 249:
+/* Line 1269 of yacc.c. */
+#line 3117 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Precedes;}
+ break;
+
+ case 250:
+/* Line 1269 of yacc.c. */
+#line 3118 "querytransformparser.ypp"
+ {(yyval.enums.nodeOperator) = QXmlNodeModelIndex::Follows;}
+ break;
+
+ case 251:
+/* Line 1269 of yacc.c. */
+#line 3121 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
+ "Hence, %1-expressions may not be used.")
+ .arg(formatKeyword("validate")),
+ ReportContext::XQST0075, fromYYLTYPE((yyloc), parseInfo));
+ /*
+ $$ = Validate::create($2, $1, parseInfo->staticContext);
+ */
+ }
+ break;
+
+ case 252:
+/* Line 1269 of yacc.c. */
+#line 3134 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 253:
+/* Line 1269 of yacc.c. */
+#line 3135 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Strict;}
+ break;
+
+ case 254:
+/* Line 1269 of yacc.c. */
+#line 3136 "querytransformparser.ypp"
+ {(yyval.enums.validationMode) = Validate::Lax;}
+ break;
+
+ case 255:
+/* Line 1269 of yacc.c. */
+#line 3139 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ /* We don't support any pragmas, so we only do the
+ * necessary validation and use the fallback expression. */
+
+ if((yyvsp[(2) - (2)].expr))
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
+ "Therefore, a fallback expression "
+ "must be present"),
+ ReportContext::XQST0079, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 256:
+/* Line 1269 of yacc.c. */
+#line 3156 "querytransformparser.ypp"
+ {
+ (yyval.expr).reset();
+ }
+ break;
+
+ case 257:
+/* Line 1269 of yacc.c. */
+#line 3160 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 260:
+/* Line 1269 of yacc.c. */
+#line 3168 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 263:
+/* Line 1269 of yacc.c. */
+#line 3176 "querytransformparser.ypp"
+ {
+ /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
+ (yyval.expr) = create(new Path(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 264:
+/* Line 1269 of yacc.c. */
+#line 3182 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath(createRootExpression(parseInfo, (yyloc)), (yyvsp[(2) - (2)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 265:
+/* Line 1269 of yacc.c. */
+#line 3186 "querytransformparser.ypp"
+ {
+ /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
+ (yyval.expr) = createRootExpression(parseInfo, (yyloc));
+ }
+ break;
+
+ case 268:
+/* Line 1269 of yacc.c. */
+#line 3196 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Path((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyvsp[(2) - (3)].enums.pathKind)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 269:
+/* Line 1269 of yacc.c. */
+#line 3200 "querytransformparser.ypp"
+ {
+ const Expression::Ptr orderBy(createReturnOrderBy((yyvsp[(4) - (7)].orderSpecs), (yyvsp[(6) - (7)].expr), parseInfo->orderStability.pop(), (yyloc), parseInfo));
+
+ ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
+ const Expression::Ptr path(create(new Path((yyvsp[(1) - (7)].expr), orderBy, (yyvsp[(2) - (7)].enums.pathKind)), (yyloc), parseInfo));
+
+ (yyval.expr) = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), (yyloc), parseInfo);
+ }
+ break;
+
+ case 270:
+/* Line 1269 of yacc.c. */
+#line 3209 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createSlashSlashPath((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr), (yyloc), parseInfo);
+ }
+ break;
+
+ case 271:
+/* Line 1269 of yacc.c. */
+#line 3214 "querytransformparser.ypp"
+ {
+ (yyval.expr) = NodeSortExpression::wrapAround((yyvsp[(1) - (1)].expr), parseInfo->staticContext);
+ }
+ break;
+
+ case 273:
+/* Line 1269 of yacc.c. */
+#line 3219 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CurrentItemStore((yyvsp[(2) - (2)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 274:
+/* Line 1269 of yacc.c. */
+#line 3223 "querytransformparser.ypp"
+ {
+ const xsDouble version = (yyvsp[(1) - (1)].sval).toDouble();
+
+ parseInfo->isBackwardsCompat.push(version != 2);
+
+ (yyval.enums.Double) = version;
+ }
+ break;
+
+ case 275:
+/* Line 1269 of yacc.c. */
+#line 3231 "querytransformparser.ypp"
+ {
+ if((yyvsp[(2) - (3)].enums.Double) < 2)
+ (yyval.expr) = createCompatStore((yyvsp[(3) - (3)].expr), (yyloc), parseInfo);
+ else
+ (yyval.expr) = (yyvsp[(3) - (3)].expr);
+ }
+ break;
+
+ case 276:
+/* Line 1269 of yacc.c. */
+#line 3238 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XSLT20, parseInfo, (yyloc));
+ Q_ASSERT(!(yyvsp[(2) - (5)].sval).isEmpty());
+ (yyval.expr) = create(new StaticBaseURIStore((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].expr)), (yyloc), parseInfo);
+}
+ break;
+
+ case 277:
+/* Line 1269 of yacc.c. */
+#line 3245 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, (yyloc));
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace((yyvsp[(5) - (6)].sval)),
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix((yyvsp[(3) - (6)].sval))));
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ }
+ break;
+
+ case 278:
+/* Line 1269 of yacc.c. */
+#line 3256 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ (yyval.expr) = (yyvsp[(8) - (9)].expr);
+ }
+ break;
+
+ case 279:
+/* Line 1269 of yacc.c. */
+#line 3261 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CallTemplate((yyvsp[(2) - (5)].qName), parseInfo->templateWithParams), (yyloc), parseInfo);
+ parseInfo->templateWithParametersHandled();
+ parseInfo->templateCalls.append((yyval.expr));
+ }
+ break;
+
+ case 280:
+/* Line 1269 of yacc.c. */
+#line 3268 "querytransformparser.ypp"
+ {
+ parseInfo->startParsingWithParam();
+ }
+ break;
+
+ case 281:
+/* Line 1269 of yacc.c. */
+#line 3272 "querytransformparser.ypp"
+ {
+ parseInfo->endParsingWithParam();
+ }
+ break;
+
+ case 282:
+/* Line 1269 of yacc.c. */
+#line 3277 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 283:
+/* Line 1269 of yacc.c. */
+#line 3280 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 284:
+/* Line 1269 of yacc.c. */
+#line 3283 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 285:
+/* Line 1269 of yacc.c. */
+#line 3287 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 286:
+/* Line 1269 of yacc.c. */
+#line 3290 "querytransformparser.ypp"
+ {
+ }
+ break;
+
+ case 287:
+/* Line 1269 of yacc.c. */
+#line 3294 "querytransformparser.ypp"
+ {
+ /* Note, this grammar rule is invoked for @c xsl:param @em and @c
+ * xsl:with-param. */
+ const bool isParsingWithParam = parseInfo->isParsingWithParam();
+
+ /**
+ * @c xsl:param doesn't make life easy:
+ *
+ * If it only has @c name, it's default value is an empty
+ * string(hence has type @c xs:string), but the value that
+ * (maybe) is supplied can be anything, typically a node.
+ *
+ * Therefore, for that very common case we can't rely on
+ * the Expression's type, but have to force it to item()*.
+ *
+ * So if we're supplied the type item()*, we pass a null
+ * SequenceType. TemplateParameterReference recognizes this
+ * and has item()* as its static type, regardless of if the
+ * expression has a more specific type.
+ */
+ SequenceType::Ptr type;
+
+ if(!(yyvsp[(4) - (5)].sequenceType)->is(CommonSequenceTypes::ZeroOrMoreItems))
+ type = (yyvsp[(4) - (5)].sequenceType);
+
+ Expression::Ptr expr;
+
+ /* The default value is an empty sequence. */
+ if(!(yyvsp[(5) - (5)].expr) && ((type && (yyvsp[(4) - (5)].sequenceType)->cardinality().allowsEmpty())
+ || isParsingWithParam))
+ expr = create(new EmptySequence, (yyloc), parseInfo);
+ else
+ expr = (yyvsp[(5) - (5)].expr);
+
+ /* We ensure we have some type, so CallTemplate, Template and friends
+ * are happy. */
+ if(!isParsingWithParam && !type)
+ type = CommonSequenceTypes::ZeroOrMoreItems;
+
+ if((yyvsp[(1) - (5)].enums.Bool))
+ /* TODO, handle tunnel parameters. */;
+ else
+ {
+ if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, (yyvsp[(3) - (5)].qName))) ||
+ (isParsingWithParam && parseInfo->templateWithParams.contains((yyvsp[(3) - (5)].qName))))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (5)].qName))),
+ isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ if(isParsingWithParam)
+ parseInfo->templateWithParams[(yyvsp[(3) - (5)].qName)] = WithParam::Ptr(new WithParam((yyvsp[(3) - (5)].qName), (yyvsp[(4) - (5)].sequenceType), expr));
+ else
+ {
+ Q_ASSERT(type);
+ pushVariable((yyvsp[(3) - (5)].qName), type, expr, VariableDeclaration::TemplateParameter, (yyloc), parseInfo);
+ parseInfo->templateParameters.append(parseInfo->variables.top());
+ }
+ }
+ }
+ }
+ break;
+
+ case 288:
+/* Line 1269 of yacc.c. */
+#line 3359 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 289:
+/* Line 1269 of yacc.c. */
+#line 3363 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 290:
+/* Line 1269 of yacc.c. */
+#line 3368 "querytransformparser.ypp"
+ {
+ (yyval.expr) = Expression::Ptr();
+ }
+ break;
+
+ case 291:
+/* Line 1269 of yacc.c. */
+#line 3372 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 292:
+/* Line 1269 of yacc.c. */
+#line 3381 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::RegularPath;
+ }
+ break;
+
+ case 293:
+/* Line 1269 of yacc.c. */
+#line 3385 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::XSLTForEach;
+ }
+ break;
+
+ case 294:
+/* Line 1269 of yacc.c. */
+#line 3389 "querytransformparser.ypp"
+ {
+ (yyval.enums.pathKind) = Path::ForApplyTemplate;
+ }
+ break;
+
+ case 296:
+/* Line 1269 of yacc.c. */
+#line 3395 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 299:
+/* Line 1269 of yacc.c. */
+#line 3403 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (1)].enums.axis) == QXmlNodeModelIndex::AxisAttribute)
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 300:
+/* Line 1269 of yacc.c. */
+#line 3408 "querytransformparser.ypp"
+ {
+ if((yyvsp[(3) - (3)].itemType))
+ {
+ /* A node test was explicitly specified. The un-abbreviated syntax was used. */
+ (yyval.expr) = create(new AxisStep((yyvsp[(1) - (3)].enums.axis), (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo);
+ }
+ else
+ {
+ /* Quote from 3.2.1.1 Axes
+ *
+ * [Definition: Every axis has a principal node kind. If an axis
+ * can contain elements, then the principal node kind is element;
+ * otherwise, it is the kind of nodes that the axis can contain.] Thus:
+ * - For the attribute axis, the principal node kind is attribute.
+ * - For all other axes, the principal node kind is element. */
+
+ if((yyvsp[(1) - (3)].enums.axis) == QXmlNodeModelIndex::AxisAttribute)
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new AxisStep((yyvsp[(1) - (3)].enums.axis), BuiltinTypes::element), (yyloc), parseInfo);
+ }
+
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 304:
+/* Line 1269 of yacc.c. */
+#line 3438 "querytransformparser.ypp"
+ {
+ if((yyvsp[(1) - (2)].enums.axis) == QXmlNodeModelIndex::AxisNamespace)
+ {
+ /* We don't raise XPST0010 here because the namespace axis isn't an optional
+ * axis. It simply is not part of the XQuery grammar. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
+ .arg(formatKeyword("namespace")),
+ ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ (yyval.enums.axis) = (yyvsp[(1) - (2)].enums.axis);
+
+ switch((yyvsp[(1) - (2)].enums.axis))
+ {
+ case QXmlNodeModelIndex::AxisAttribute:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ break;
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ break;
+ }
+ default:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XSLT20),
+ parseInfo, (yyloc));
+ }
+ }
+ }
+ break;
+
+ case 305:
+/* Line 1269 of yacc.c. */
+#line 3481 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestorOrSelf ;}
+ break;
+
+ case 306:
+/* Line 1269 of yacc.c. */
+#line 3482 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAncestor ;}
+ break;
+
+ case 307:
+/* Line 1269 of yacc.c. */
+#line 3483 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisAttribute ;}
+ break;
+
+ case 308:
+/* Line 1269 of yacc.c. */
+#line 3484 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisChild ;}
+ break;
+
+ case 309:
+/* Line 1269 of yacc.c. */
+#line 3485 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendantOrSelf;}
+ break;
+
+ case 310:
+/* Line 1269 of yacc.c. */
+#line 3486 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisDescendant ;}
+ break;
+
+ case 311:
+/* Line 1269 of yacc.c. */
+#line 3487 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowing ;}
+ break;
+
+ case 312:
+/* Line 1269 of yacc.c. */
+#line 3488 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPreceding ;}
+ break;
+
+ case 313:
+/* Line 1269 of yacc.c. */
+#line 3489 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisFollowingSibling;}
+ break;
+
+ case 314:
+/* Line 1269 of yacc.c. */
+#line 3490 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisPrecedingSibling;}
+ break;
+
+ case 315:
+/* Line 1269 of yacc.c. */
+#line 3491 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisParent ;}
+ break;
+
+ case 316:
+/* Line 1269 of yacc.c. */
+#line 3492 "querytransformparser.ypp"
+ {(yyval.enums.axis) = QXmlNodeModelIndex::AxisSelf ;}
+ break;
+
+ case 317:
+/* Line 1269 of yacc.c. */
+#line 3495 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 318:
+/* Line 1269 of yacc.c. */
+#line 3499 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, (yyloc));
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(3) - (3)].itemType)), (yyloc), parseInfo);
+
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 319:
+/* Line 1269 of yacc.c. */
+#line 3506 "querytransformparser.ypp"
+ {
+ ItemType::Ptr nodeTest;
+
+ if(parseInfo->isParsingPattern && *(yyvsp[(1) - (1)].itemType) == *BuiltinTypes::node)
+ nodeTest = BuiltinTypes::xsltNodeTest;
+ else
+ nodeTest = (yyvsp[(1) - (1)].itemType);
+
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), (yyloc), parseInfo);
+ }
+ break;
+
+ case 320:
+/* Line 1269 of yacc.c. */
+#line 3517 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, (yyvsp[(1) - (1)].itemType)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 322:
+/* Line 1269 of yacc.c. */
+#line 3524 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), (yyloc), parseInfo);
+ }
+ break;
+
+ case 324:
+/* Line 1269 of yacc.c. */
+#line 3530 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 325:
+/* Line 1269 of yacc.c. */
+#line 3535 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(parseInfo->nodeTestSource, (yyvsp[(1) - (1)].qName));
+ }
+ break;
+
+ case 327:
+/* Line 1269 of yacc.c. */
+#line 3541 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = parseInfo->nodeTestSource;
+ }
+ break;
+
+ case 328:
+/* Line 1269 of yacc.c. */
+#line 3545 "querytransformparser.ypp"
+ {
+ const NamePool::Ptr np(parseInfo->staticContext->namePool());
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix((yyvsp[(1) - (1)].sval)), parseInfo->staticContext, &ryy));
+
+ (yyval.itemType) = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
+ }
+ break;
+
+ case 329:
+/* Line 1269 of yacc.c. */
+#line 3554 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(1) - (1)].sval));
+ (yyval.itemType) = LocalNameTest::create(parseInfo->nodeTestSource, c);
+ }
+ break;
+
+ case 331:
+/* Line 1269 of yacc.c. */
+#line 3562 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(GenericPredicate::create((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr), parseInfo->staticContext, fromYYLTYPE((yylsp[(4) - (4)]), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 339:
+/* Line 1269 of yacc.c. */
+#line 3575 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ApplyTemplate(parseInfo->modeFor((yyvsp[(2) - (5)].qName)),
+ parseInfo->templateWithParams,
+ parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::Default))),
+ (yylsp[(1) - (5)]), parseInfo);
+ parseInfo->templateWithParametersHandled();
+ }
+ break;
+
+ case 341:
+/* Line 1269 of yacc.c. */
+#line 3586 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 342:
+/* Line 1269 of yacc.c. */
+#line 3591 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = createNumericLiteral<Double>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 343:
+/* Line 1269 of yacc.c. */
+#line 3596 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = createNumericLiteral<Numeric>((yyvsp[(1) - (1)].sval), (yyloc), parseInfo);
+ }
+ break;
+
+ case 344:
+/* Line 1269 of yacc.c. */
+#line 3602 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = resolveVariable((yyvsp[(2) - (2)].qName), (yyloc), parseInfo, false);
+ }
+ break;
+
+ case 345:
+/* Line 1269 of yacc.c. */
+#line 3608 "querytransformparser.ypp"
+ {
+ /* See: http://www.w3.org/TR/xpath20/#id-variables */
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(QString(), (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 346:
+/* Line 1269 of yacc.c. */
+#line 3613 "querytransformparser.ypp"
+ {
+ (yyval.qName) = (yyvsp[(1) - (1)].qName);
+ }
+ break;
+
+ case 347:
+/* Line 1269 of yacc.c. */
+#line 3618 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = (yyvsp[(2) - (3)].expr);
+ }
+ break;
+
+ case 348:
+/* Line 1269 of yacc.c. */
+#line 3623 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ (yyval.expr) = create(new EmptySequence, (yyloc), parseInfo);
+ }
+ break;
+
+ case 349:
+/* Line 1269 of yacc.c. */
+#line 3629 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ContextItem(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 350:
+/* Line 1269 of yacc.c. */
+#line 3634 "querytransformparser.ypp"
+ {
+ (yyval.expr) = (yyvsp[(2) - (2)].expr);
+ }
+ break;
+
+ case 351:
+/* Line 1269 of yacc.c. */
+#line 3639 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ if(XPathHelper::isReservedNamespace((yyvsp[(1) - (4)].qName).namespaceURI()) || (yyvsp[(1) - (4)].qName).namespaceURI() == StandardNamespaces::InternalXSLT)
+ { /* We got a call to a builtin function. */
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const Expression::Ptr
+ func(parseInfo->staticContext->
+ functionSignatures()->createFunctionCall((yyvsp[(1) - (4)].qName), (yyvsp[(3) - (4)].expressionList), parseInfo->staticContext, &ryy));
+
+ if(func)
+ (yyval.expr) = create(func, (yyloc), parseInfo);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with name %1 is available.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(1) - (4)].qName))),
+ ReportContext::XPST0017, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else /* It's a call to a function created with 'declare function'.*/
+ {
+ (yyval.expr) = create(new UserFunctionCallsite((yyvsp[(1) - (4)].qName), (yyvsp[(3) - (4)].expressionList).count()), (yyloc), parseInfo);
+
+ (yyval.expr)->setOperands((yyvsp[(3) - (4)].expressionList));
+ parseInfo->userFunctionCallsites.append((yyval.expr));
+ }
+ }
+ break;
+
+ case 352:
+/* Line 1269 of yacc.c. */
+#line 3668 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 353:
+/* Line 1269 of yacc.c. */
+#line 3673 "querytransformparser.ypp"
+ {
+ Expression::List list;
+ list.append((yyvsp[(1) - (1)].expr));
+ (yyval.expressionList) = list;
+ }
+ break;
+
+ case 355:
+/* Line 1269 of yacc.c. */
+#line 3682 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc));
+ }
+ break;
+
+ case 360:
+/* Line 1269 of yacc.c. */
+#line 3726 "querytransformparser.ypp"
+ {
+ (yyval.enums.tokenizerPosition) = parseInfo->tokenizer->commenceScanOnly();
+ parseInfo->scanOnlyStack.push(true);
+ }
+ break;
+
+ case 361:
+/* Line 1269 of yacc.c. */
+#line 3735 "querytransformparser.ypp"
+ {
+ ++parseInfo->elementConstructorDepth;
+ Expression::List constructors;
+
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+
+ /* Fix up attributes and namespace declarations. */
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = (yyvsp[(4) - (4)].attributeHolders).size();
+ QSet<QXmlName::PrefixCode> usedDeclarations;
+
+ /* Whether xmlns="" has been encountered. */
+ bool hasDefaultDeclaration = false;
+
+ /* For each attribute & namespace declaration, do: */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName((yyvsp[(4) - (4)].attributeHolders).at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+
+ /* This can seem a bit weird. However, this name is ending up in a QXmlName
+ * which consider its prefix a... prefix. So, a namespace binding name can in some cases
+ * be a local name, but that's just as the initial syntactical construct. */
+ const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);
+
+ /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
+ {
+ if(localName == StandardPrefixes::xmlns)
+ hasDefaultDeclaration = true;
+
+ /* We have a namespace declaration. */
+
+ const Expression::Ptr nsExpr((yyvsp[(4) - (4)].attributeHolders).at(i).second);
+
+ const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
+
+ const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
+
+ if(ns == StandardNamespaces::empty)
+ {
+ if(localName != StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
+ .arg(formatURI(strPrefix)),
+ ReportContext::XQST0085, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ else if(!AnyURI::isValid(strNamespace))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
+ ReportContext::XQST0022, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
+ .arg(formatKeyword("xml")),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
+ ReportContext::XQST0070, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ QXmlName nb;
+
+ if(localName == StandardPrefixes::xmlns)
+ nb = QXmlName(ns, StandardLocalNames::empty);
+ else
+ nb = QXmlName(ns, StandardLocalNames::empty, localName);
+
+ if(usedDeclarations.contains(nb.prefix()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
+ .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
+ ReportContext::XQST0071, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ usedDeclarations.insert(nb.prefix());
+
+ /* If the user has bound the XML namespace correctly, we in either
+ * case don't want to output it.
+ *
+ * We only have to check the namespace parts since the above checks has ensured
+ * consistency in the prefix parts. */
+ if(ns != StandardNamespaces::xml)
+ {
+ /* We don't want default namespace declarations when the
+ * default namespace already is empty. */
+ if(!(ns == StandardNamespaces::empty &&
+ localName == StandardNamespaces::xmlns &&
+ resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
+ {
+ constructors.append(create(new NamespaceConstructor(nb), (yyloc), parseInfo));
+ resolver->addBinding(nb);
+ }
+ }
+ }
+ }
+
+ if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
+ {
+ /* TODO But mostly this isn't needed, since the default element
+ * namespace is empty? How does this at all work? */
+ const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ constructors.append(create(new NamespaceConstructor(def), (yyloc), parseInfo));
+ }
+
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ (yyval.expressionList) = constructors;
+
+ /* Resolve the name of the element, now that the namespace attributes are read. */
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(2) - (4)].sval), parseInfo->staticContext, resolver, &ryy);
+ parseInfo->tagStack.push(ele);
+ }
+
+ parseInfo->tokenizer->resumeTokenizationFrom((yyvsp[(3) - (4)].enums.tokenizerPosition));
+ }
+ break;
+
+ case 362:
+/* Line 1269 of yacc.c. */
+#line 3881 "querytransformparser.ypp"
+ {
+ /* We add the content constructor after the attribute constructors. This might result
+ * in nested ExpressionSequences, but it will be optimized away later on. */
+
+ Expression::List attributes((yyvsp[(5) - (8)].expressionList));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = (yyvsp[(7) - (8)].attributeHolders).size();
+ QSet<QXmlName> declaredAttributes;
+ declaredAttributes.reserve(len);
+
+ /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
+ * turn it into an attribute constructor. */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName((yyvsp[(7) - (8)].attributeHolders).at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+ const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
+ {
+ const Expression::ID id = (yyvsp[(7) - (8)].attributeHolders).at(i).second->id();
+
+ if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
+ {
+ /* It's a namespace declaration, and we've already handled those above. */
+ continue;
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
+ "use enclosed expressions."),
+ ReportContext::XQST0022, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ }
+ else
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+ const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(7) - (8)].attributeHolders).at(i).first, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(),
+ &ryy, true);
+ if(declaredAttributes.contains(att))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute with name %1 has already appeared on this element.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
+ ReportContext::XQST0040, fromYYLTYPE((yyloc), parseInfo));
+
+ }
+ else
+ declaredAttributes.insert(att);
+
+ /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
+ * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
+ * it twice.
+ *
+ * The AttributeConstructor's arguments are just dummies. */
+ const Expression::Ptr ctor(create(new AttributeConstructor((yyvsp[(7) - (8)].attributeHolders).at(i).second, (yyvsp[(7) - (8)].attributeHolders).at(i).second), (yyloc), parseInfo));
+
+ Expression::List ops;
+ ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
+ ops.append((yyvsp[(7) - (8)].attributeHolders).at(i).second);
+ ctor->setOperands(ops);
+
+ attributes.append(ctor);
+ }
+ }
+
+ Expression::Ptr contentOp;
+
+ if(attributes.isEmpty())
+ contentOp = (yyvsp[(8) - (8)].expr);
+ else
+ {
+ attributes.append((yyvsp[(8) - (8)].expr));
+ contentOp = create(new ExpressionSequence(attributes), (yyloc), parseInfo);
+ }
+
+ const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), (yyloc), parseInfo));
+ (yyval.expr) = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), (yyloc), parseInfo);
+
+ /* Restore the old context. We don't want the namespaces
+ * to be in-scope for expressions appearing after the
+ * element they appeared on. */
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ parseInfo->tagStack.pop();
+
+ --parseInfo->elementConstructorDepth;
+ }
+ break;
+
+ case 363:
+/* Line 1269 of yacc.c. */
+#line 3977 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo);
+ }
+ break;
+
+ case 364:
+/* Line 1269 of yacc.c. */
+#line 3981 "querytransformparser.ypp"
+ {
+ if(!(yyvsp[(4) - (5)].qName).isLexicallyEqual(parseInfo->tagStack.top()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
+ "well-formed. %1 is ended with %2.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
+ formatKeyword(parseInfo->staticContext->namePool()->toLexical((yyvsp[(4) - (5)].qName)))),
+ ReportContext::XPST0003, fromYYLTYPE((yyloc), parseInfo));
+ }
+
+ if((yyvsp[(2) - (5)].expressionList).isEmpty())
+ (yyval.expr) = create(new EmptySequence(), (yyloc), parseInfo);
+ else if((yyvsp[(2) - (5)].expressionList).size() == 1)
+ (yyval.expr) = (yyvsp[(2) - (5)].expressionList).first();
+ else
+ (yyval.expr) = create(new ExpressionSequence((yyvsp[(2) - (5)].expressionList)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 365:
+/* Line 1269 of yacc.c. */
+#line 4000 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolders) = AttributeHolderVector();
+ }
+ break;
+
+ case 366:
+/* Line 1269 of yacc.c. */
+#line 4004 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].attributeHolders).append((yyvsp[(2) - (2)].attributeHolder));
+ (yyval.attributeHolders) = (yyvsp[(1) - (2)].attributeHolders);
+ }
+ break;
+
+ case 367:
+/* Line 1269 of yacc.c. */
+#line 4010 "querytransformparser.ypp"
+ {
+ (yyval.attributeHolder) = qMakePair((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr));
+ }
+ break;
+
+ case 368:
+/* Line 1269 of yacc.c. */
+#line 4015 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 369:
+/* Line 1269 of yacc.c. */
+#line 4020 "querytransformparser.ypp"
+ {
+ (yyval.expr) = createDirAttributeValue((yyvsp[(2) - (3)].expressionList), parseInfo, (yyloc));
+ }
+ break;
+
+ case 370:
+/* Line 1269 of yacc.c. */
+#line 4025 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ }
+ break;
+
+ case 371:
+/* Line 1269 of yacc.c. */
+#line 4029 "querytransformparser.ypp"
+ {
+ Expression::Ptr content((yyvsp[(1) - (2)].expr));
+
+ if(parseInfo->isBackwardsCompat.top())
+ content = create(GenericPredicate::createFirstItem(content), (yyloc), parseInfo);
+
+ (yyvsp[(2) - (2)].expressionList).prepend(createSimpleContent(content, (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(2) - (2)].expressionList);
+ }
+ break;
+
+ case 372:
+/* Line 1269 of yacc.c. */
+#line 4039 "querytransformparser.ypp"
+ {
+ (yyvsp[(2) - (2)].expressionList).prepend(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (2)].sval))), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(2) - (2)].expressionList);
+ }
+ break;
+
+ case 373:
+/* Line 1269 of yacc.c. */
+#line 4045 "querytransformparser.ypp"
+ {
+ (yyval.expressionList) = Expression::List();
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 374:
+/* Line 1269 of yacc.c. */
+#line 4050 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].expressionList).append((yyvsp[(2) - (2)].expr));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 375:
+/* Line 1269 of yacc.c. */
+#line 4056 "querytransformparser.ypp"
+ {
+ if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
+ XPathHelper::isWhitespaceOnly((yyvsp[(2) - (2)].sval)))
+ {
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ }
+ else
+ {
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ }
+ break;
+
+ case 376:
+/* Line 1269 of yacc.c. */
+#line 4070 "querytransformparser.ypp"
+ {
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ break;
+
+ case 377:
+/* Line 1269 of yacc.c. */
+#line 4076 "querytransformparser.ypp"
+ {
+ /* We insert a text node constructor that send an empty text node between
+ * the two enclosed expressions, in order to ensure that no space is inserted.
+ *
+ * However, we only do it when we have no node constructors. */
+ if(parseInfo->isPreviousEnclosedExpr &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches((yyvsp[(2) - (2)].expr)->staticType()->itemType()) &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches((yyvsp[(1) - (2)].expressionList).last()->staticType()->itemType()))
+ (yyvsp[(1) - (2)].expressionList).append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), (yyloc), parseInfo)), (yyloc), parseInfo));
+ else
+ parseInfo->isPreviousEnclosedExpr = true;
+
+ (yyvsp[(1) - (2)].expressionList).append(createCopyOf((yyvsp[(2) - (2)].expr), parseInfo, (yyloc)));
+ (yyval.expressionList) = (yyvsp[(1) - (2)].expressionList);
+ }
+ break;
+
+ case 378:
+/* Line 1269 of yacc.c. */
+#line 4093 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new CommentConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(2) - (2)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 379:
+/* Line 1269 of yacc.c. */
+#line 4098 "querytransformparser.ypp"
+ {
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+ NCNameConstructor::validateTargetName<StaticContext::Ptr,
+ ReportContext::XPST0003,
+ ReportContext::XPST0003>((yyvsp[(2) - (3)].sval),
+ parseInfo->staticContext, &ryy);
+
+ (yyval.expr) = create(new ProcessingInstructionConstructor(
+ create(new Literal(AtomicString::fromValue((yyvsp[(2) - (3)].sval))), (yyloc), parseInfo),
+ create(new Literal(AtomicString::fromValue((yyvsp[(3) - (3)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 387:
+/* Line 1269 of yacc.c. */
+#line 4119 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool));
+
+ (yyval.expr) = create(new DocumentConstructor((yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 388:
+/* Line 1269 of yacc.c. */
+#line 4126 "querytransformparser.ypp"
+ {
+ /* This value is incremented before the action below is executed. */
+ ++parseInfo->elementConstructorDepth;
+ }
+ break;
+
+ case 389:
+/* Line 1269 of yacc.c. */
+#line 4131 "querytransformparser.ypp"
+ {
+ Q_ASSERT(5);
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (5)].enums.Bool));
+
+ Expression::Ptr effExpr;
+
+ if((yyvsp[(5) - (5)].expr))
+ effExpr = createCopyOf((yyvsp[(5) - (5)].expr), parseInfo, (yyloc));
+ else
+ effExpr = create(new EmptySequence(), (yyloc), parseInfo);
+
+ const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
+
+ /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
+ * a child of another constructor, it has already been done. */
+ if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
+ {
+ Expression::List exprList;
+
+ /* We append the namespace constructor before the body, in order to
+ * comply with QAbstractXmlPushHandler's contract. */
+ const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ exprList.append(create(new NamespaceConstructor(def), (yyloc), parseInfo));
+
+ exprList.append(effExpr);
+
+ effExpr = create(new ExpressionSequence(exprList), (yyloc), parseInfo);
+ }
+
+ --parseInfo->elementConstructorDepth;
+ (yyval.expr) = create(new ElementConstructor((yyvsp[(3) - (5)].expr), effExpr, parseInfo->isXSLT()), (yyloc), parseInfo);
+ }
+ break;
+
+ case 390:
+/* Line 1269 of yacc.c. */
+#line 4165 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = false;
+ }
+ break;
+
+ case 391:
+/* Line 1269 of yacc.c. */
+#line 4169 "querytransformparser.ypp"
+ {
+ (yyval.enums.Bool) = true;
+ }
+ break;
+
+ case 392:
+/* Line 1269 of yacc.c. */
+#line 4177 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (4)].enums.Bool));
+
+ const Expression::Ptr name(create(new AttributeNameValidator((yyvsp[(3) - (4)].expr)), (yyloc), parseInfo));
+
+ if((yyvsp[(4) - (4)].expr))
+ (yyval.expr) = create(new AttributeConstructor(name, createSimpleContent((yyvsp[(4) - (4)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ else
+ (yyval.expr) = create(new AttributeConstructor(name, create(new EmptySequence(), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 393:
+/* Line 1269 of yacc.c. */
+#line 4189 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new TextNodeConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 394:
+/* Line 1269 of yacc.c. */
+#line 4194 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].enums.Bool));
+
+ (yyval.expr) = create(new CommentConstructor(createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 395:
+/* Line 1269 of yacc.c. */
+#line 4201 "querytransformparser.ypp"
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, (yyloc), (yyvsp[(2) - (3)].expr));
+
+ if((yyvsp[(3) - (3)].expr))
+ {
+ (yyval.expr) = create(new ProcessingInstructionConstructor((yyvsp[(2) - (3)].expr), createSimpleContent((yyvsp[(3) - (3)].expr), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ else
+ (yyval.expr) = create(new ProcessingInstructionConstructor((yyvsp[(2) - (3)].expr), create(new EmptySequence(), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 396:
+/* Line 1269 of yacc.c. */
+#line 4212 "querytransformparser.ypp"
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 397:
+/* Line 1269 of yacc.c. */
+#line 4216 "querytransformparser.ypp"
+ {
+ parseInfo->restoreNodeTestSource();
+ }
+ break;
+
+ case 398:
+/* Line 1269 of yacc.c. */
+#line 4219 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(2) - (3)].qName)))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 400:
+/* Line 1269 of yacc.c. */
+#line 4225 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), (yyvsp[(1) - (1)].qName)))), (yyloc), parseInfo);
+ }
+ break;
+
+ case 402:
+/* Line 1269 of yacc.c. */
+#line 4231 "querytransformparser.ypp"
+ {
+ if(BuiltinTypes::xsQName->xdtTypeMatches((yyvsp[(1) - (1)].expr)->staticType()->itemType()))
+ (yyval.expr) = (yyvsp[(1) - (1)].expr);
+ else
+ {
+ (yyval.expr) = create(new QNameConstructor((yyvsp[(1) - (1)].expr),
+ parseInfo->staticContext->namespaceBindings()),
+ (yyloc), parseInfo);
+ }
+ }
+ break;
+
+ case 403:
+/* Line 1269 of yacc.c. */
+#line 4246 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue((yyvsp[(1) - (1)].sval))), (yyloc), parseInfo)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 404:
+/* Line 1269 of yacc.c. */
+#line 4250 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new NCNameConstructor((yyvsp[(1) - (1)].expr)), (yyloc), parseInfo);
+ }
+ break;
+
+ case 405:
+/* Line 1269 of yacc.c. */
+#line 4259 "querytransformparser.ypp"
+ {
+ (yyval.expr) = create(new ComputedNamespaceConstructor((yyvsp[(2) - (3)].expr), (yyvsp[(3) - (3)].expr)), (yyloc), parseInfo);
+}
+ break;
+
+ case 406:
+/* Line 1269 of yacc.c. */
+#line 4264 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (1)].itemType), Cardinality::exactlyOne());
+ }
+ break;
+
+ case 407:
+/* Line 1269 of yacc.c. */
+#line 4268 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), Cardinality::zeroOrOne());
+ }
+ break;
+
+ case 408:
+/* Line 1269 of yacc.c. */
+#line 4273 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::ZeroOrMoreItems;
+ }
+ break;
+
+ case 409:
+/* Line 1269 of yacc.c. */
+#line 4277 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = (yyvsp[(2) - (2)].sequenceType);
+ }
+ break;
+
+ case 410:
+/* Line 1269 of yacc.c. */
+#line 4282 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = makeGenericSequenceType((yyvsp[(1) - (2)].itemType), (yyvsp[(2) - (2)].cardinality));
+ }
+ break;
+
+ case 411:
+/* Line 1269 of yacc.c. */
+#line 4287 "querytransformparser.ypp"
+ {
+ (yyval.sequenceType) = CommonSequenceTypes::Empty;
+ }
+ break;
+
+ case 412:
+/* Line 1269 of yacc.c. */
+#line 4291 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::exactlyOne();}
+ break;
+
+ case 413:
+/* Line 1269 of yacc.c. */
+#line 4292 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::oneOrMore();}
+ break;
+
+ case 414:
+/* Line 1269 of yacc.c. */
+#line 4293 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrMore();}
+ break;
+
+ case 415:
+/* Line 1269 of yacc.c. */
+#line 4294 "querytransformparser.ypp"
+ {(yyval.cardinality) = Cardinality::zeroOrOne();}
+ break;
+
+ case 419:
+/* Line 1269 of yacc.c. */
+#line 4300 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::item;
+ }
+ break;
+
+ case 420:
+/* Line 1269 of yacc.c. */
+#line 4305 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(1) - (1)].qName)));
+
+ if(!t)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(1) - (1)].qName))), ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
+ (yyval.itemType) = AtomicType::Ptr(t);
+ else
+ {
+ /* Try to give an intelligent message. */
+ if(t->isComplexType())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
+ "types is not possible. However, casting "
+ "to atomic types such as %2 works.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t))
+ .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
+ ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
+ "is only possible to atomic types.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t)),
+ ReportContext::XPST0051, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ }
+ break;
+
+ case 428:
+/* Line 1269 of yacc.c. */
+#line 4349 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::node;
+ }
+ break;
+
+ case 429:
+/* Line 1269 of yacc.c. */
+#line 4354 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 430:
+/* Line 1269 of yacc.c. */
+#line 4359 "querytransformparser.ypp"
+ {
+ // TODO support for document element testing
+ (yyval.itemType) = BuiltinTypes::document;
+ }
+ break;
+
+ case 433:
+/* Line 1269 of yacc.c. */
+#line 4368 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::text;
+ }
+ break;
+
+ case 434:
+/* Line 1269 of yacc.c. */
+#line 4373 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::comment;
+ }
+ break;
+
+ case 435:
+/* Line 1269 of yacc.c. */
+#line 4378 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::pi;
+ }
+ break;
+
+ case 436:
+/* Line 1269 of yacc.c. */
+#line 4383 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(3) - (4)].sval)));
+ }
+ break;
+
+ case 437:
+/* Line 1269 of yacc.c. */
+#line 4388 "querytransformparser.ypp"
+ {
+ if(QXmlUtils::isNCName((yyvsp[(3) - (4)].sval)))
+ {
+ (yyval.itemType) = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName((yyvsp[(3) - (4)].sval)));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
+ "processing-instruction.")
+ .arg(formatKeyword((yyvsp[(3) - (4)].sval))),
+ ReportContext::XPTY0004,
+ fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 440:
+/* Line 1269 of yacc.c. */
+#line 4407 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 441:
+/* Line 1269 of yacc.c. */
+#line 4412 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::attribute;
+ }
+ break;
+
+ case 442:
+/* Line 1269 of yacc.c. */
+#line 4417 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::attribute, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 443:
+/* Line 1269 of yacc.c. */
+#line 4421 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (6)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 444:
+/* Line 1269 of yacc.c. */
+#line 4433 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (6)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (6)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 445:
+/* Line 1269 of yacc.c. */
+#line 4446 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (4)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ (yyval.itemType).reset();
+ }
+ break;
+
+ case 446:
+/* Line 1269 of yacc.c. */
+#line 4456 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 447:
+/* Line 1269 of yacc.c. */
+#line 4461 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = BuiltinTypes::element;
+ }
+ break;
+
+ case 448:
+/* Line 1269 of yacc.c. */
+#line 4466 "querytransformparser.ypp"
+ {
+ (yyval.itemType) = QNameTest::create(BuiltinTypes::element, (yyvsp[(3) - (4)].qName));
+ }
+ break;
+
+ case 449:
+/* Line 1269 of yacc.c. */
+#line 4471 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(unknownType()
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (7)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 450:
+/* Line 1269 of yacc.c. */
+#line 4485 "querytransformparser.ypp"
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType((yyvsp[(5) - (7)].qName)));
+
+ if(t)
+ (yyval.itemType) = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(5) - (7)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ }
+ }
+ break;
+
+ case 453:
+/* Line 1269 of yacc.c. */
+#line 4502 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), (yyvsp[(3) - (4)].qName))),
+ ReportContext::XPST0008, fromYYLTYPE((yyloc), parseInfo));
+ (yyval.itemType).reset();
+ }
+ break;
+
+ case 455:
+/* Line 1269 of yacc.c. */
+#line 4514 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 457:
+/* Line 1269 of yacc.c. */
+#line 4526 "querytransformparser.ypp"
+ {
+ if(parseInfo->nodeTestSource == BuiltinTypes::element)
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), (yyvsp[(1) - (1)].sval));
+ else
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 462:
+/* Line 1269 of yacc.c. */
+#line 4540 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), (yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+ case 463:
+/* Line 1269 of yacc.c. */
+#line 4544 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, (yyvsp[(2) - (2)].sval));
+ }
+ break;
+
+ case 466:
+/* Line 1269 of yacc.c. */
+#line 4552 "querytransformparser.ypp"
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
+ "a namespace."),
+ ReportContext::XPST0081, fromYYLTYPE((yyloc), parseInfo));
+ }
+ break;
+
+ case 469:
+/* Line 1269 of yacc.c. */
+#line 4562 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 470:
+/* Line 1269 of yacc.c. */
+#line 4566 "querytransformparser.ypp"
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, (yyloc));
+ }
+ break;
+
+ case 471:
+/* Line 1269 of yacc.c. */
+#line 4571 "querytransformparser.ypp"
+ {
+
+ const ReflectYYLTYPE ryy((yyloc), parseInfo);
+
+ (yyval.qName) = QNameConstructor::
+ expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>((yyvsp[(1) - (1)].sval), parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(), &ryy);
+
+ }
+ break;
+
+ case 472:
+/* Line 1269 of yacc.c. */
+#line 4583 "querytransformparser.ypp"
+ {
+ (yyval.qName) = parseInfo->staticContext->namePool()->fromClarkName((yyvsp[(1) - (1)].sval));
+ }
+ break;
+
+
+/* Line 1269 of yacc.c. */
+#line 7763 "qquerytransformparser.cpp"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, parseInfo, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (&yylloc, parseInfo, yymsg);
+ }
+ else
+ {
+ yyerror (&yylloc, parseInfo, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[0] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, parseInfo);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[0] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[0] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, parseInfo);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[1] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, parseInfo, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, parseInfo);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, parseInfo);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+/* Line 1486 of yacc.c. */
+#line 4587 "querytransformparser.ypp"
+
+
+QString Tokenizer::tokenToString(const Token &token)
+{
+ switch(token.type)
+ {
+ case NCNAME:
+ /* Fallthrough. */
+ case QNAME:
+ /* Fallthrough. */
+ case NUMBER:
+ /* Fallthrough. */
+ case XPATH2_NUMBER:
+ return token.value;
+ case STRING_LITERAL:
+ return QLatin1Char('"') + token.value + QLatin1Char('"');
+ default:
+ {
+ const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
+
+ /* Remove the quotes. */
+ if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
+ return raw.mid(1, raw.length() - 2);
+ else
+ return raw;
+ }
+ }
+}
+
+} /* namespace Patternist */
+
+QT_END_NAMESPACE
+
+// vim: et:ts=4:sw=4:sts=4:syntax=yacc
+
diff --git a/src/xmlpatterns/parser/qquerytransformparser_p.h b/src/xmlpatterns/parser/qquerytransformparser_p.h
new file mode 100644
index 0000000..a4c1191
--- /dev/null
+++ b/src/xmlpatterns/parser/qquerytransformparser_p.h
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** 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.
+
+/* A Bison parser, made by GNU Bison 2.3a. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* These tokens are defined to nothing on Windows because they're
+ * used in their documentation parser, for use in things like:
+ *
+ * int foo(IN char* name, OUT char* path);
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef IN
+# undef IN
+#endif
+#ifdef INSTANCE
+# undef INSTANCE
+#endif
+#ifdef STRICT
+# undef STRICT
+#endif
+#ifdef SELF
+# undef SELF
+#endif
+/* These tokens are defined in VxWorks kernel mode
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef ERROR
+# undef ERROR
+#endif
+#ifdef IMPORT
+# undef IMPORT
+#endif
+#ifdef MAP
+# undef MAP
+#endif
+
+/* These tokens are defined to nothing on Windows because they're
+ * used in their documentation parser, for use in things like:
+ *
+ * int foo(IN char* name, OUT char* path);
+ *
+ * Hence this un-break fix. Note that this file was auto generated. */
+#ifdef IN
+# undef IN
+#endif
+#ifdef INSTANCE
+# undef INSTANCE
+#endif
+#ifdef STRICT
+# undef STRICT
+#endif
+#ifdef SELF
+# undef SELF
+#endif
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END_OF_FILE = 0,
+ STRING_LITERAL = 258,
+ NON_BOUNDARY_WS = 259,
+ XPATH2_STRING_LITERAL = 260,
+ QNAME = 261,
+ NCNAME = 262,
+ CLARK_NAME = 263,
+ ANY_LOCAL_NAME = 264,
+ ANY_PREFIX = 265,
+ NUMBER = 266,
+ XPATH2_NUMBER = 267,
+ ANCESTOR = 268,
+ ANCESTOR_OR_SELF = 269,
+ AND = 270,
+ APOS = 271,
+ APPLY_TEMPLATE = 272,
+ AS = 273,
+ ASCENDING = 274,
+ ASSIGN = 275,
+ AT = 276,
+ AT_SIGN = 277,
+ ATTRIBUTE = 278,
+ AVT = 279,
+ BAR = 280,
+ BASEURI = 281,
+ BEGIN_END_TAG = 282,
+ BOUNDARY_SPACE = 283,
+ BY = 284,
+ CALL_TEMPLATE = 285,
+ CASE = 286,
+ CASTABLE = 287,
+ CAST = 288,
+ CHILD = 289,
+ COLLATION = 290,
+ COLONCOLON = 291,
+ COMMA = 292,
+ COMMENT = 293,
+ COMMENT_START = 294,
+ CONSTRUCTION = 295,
+ COPY_NAMESPACES = 296,
+ CURLY_LBRACE = 297,
+ CURLY_RBRACE = 298,
+ DECLARE = 299,
+ DEFAULT = 300,
+ DESCENDANT = 301,
+ DESCENDANT_OR_SELF = 302,
+ DESCENDING = 303,
+ DIV = 304,
+ DOCUMENT = 305,
+ DOCUMENT_NODE = 306,
+ DOLLAR = 307,
+ DOT = 308,
+ DOTDOT = 309,
+ ELEMENT = 310,
+ ELSE = 311,
+ EMPTY = 312,
+ EMPTY_SEQUENCE = 313,
+ ENCODING = 314,
+ END_SORT = 315,
+ EQ = 316,
+ ERROR = 317,
+ EVERY = 318,
+ EXCEPT = 319,
+ EXTERNAL = 320,
+ FOLLOWING = 321,
+ FOLLOWING_SIBLING = 322,
+ FOLLOWS = 323,
+ FOR_APPLY_TEMPLATE = 324,
+ FOR = 325,
+ FUNCTION = 326,
+ GE = 327,
+ G_EQ = 328,
+ G_GE = 329,
+ G_GT = 330,
+ G_LE = 331,
+ G_LT = 332,
+ G_NE = 333,
+ GREATEST = 334,
+ GT = 335,
+ IDIV = 336,
+ IF = 337,
+ IMPORT = 338,
+ INHERIT = 339,
+ IN = 340,
+ INSTANCE = 341,
+ INTERSECT = 342,
+ IS = 343,
+ ITEM = 344,
+ LAX = 345,
+ LBRACKET = 346,
+ LEAST = 347,
+ LE = 348,
+ LET = 349,
+ LPAREN = 350,
+ LT = 351,
+ MAP = 352,
+ MATCHES = 353,
+ MINUS = 354,
+ MODE = 355,
+ MOD = 356,
+ MODULE = 357,
+ NAME = 358,
+ NAMESPACE = 359,
+ NE = 360,
+ NODE = 361,
+ NO_INHERIT = 362,
+ NO_PRESERVE = 363,
+ OF = 364,
+ OPTION = 365,
+ ORDERED = 366,
+ ORDERING = 367,
+ ORDER = 368,
+ OR = 369,
+ PARENT = 370,
+ PI_START = 371,
+ PLUS = 372,
+ POSITION_SET = 373,
+ PRAGMA_END = 374,
+ PRAGMA_START = 375,
+ PRECEDES = 376,
+ PRECEDING = 377,
+ PRECEDING_SIBLING = 378,
+ PRESERVE = 379,
+ PRIORITY = 380,
+ PROCESSING_INSTRUCTION = 381,
+ QUESTION = 382,
+ QUICK_TAG_END = 383,
+ QUOTE = 384,
+ RBRACKET = 385,
+ RETURN = 386,
+ RPAREN = 387,
+ SATISFIES = 388,
+ SCHEMA_ATTRIBUTE = 389,
+ SCHEMA_ELEMENT = 390,
+ SCHEMA = 391,
+ SELF = 392,
+ SEMI_COLON = 393,
+ SLASH = 394,
+ SLASHSLASH = 395,
+ SOME = 396,
+ SORT = 397,
+ STABLE = 398,
+ STAR = 399,
+ STRICT = 400,
+ STRIP = 401,
+ SUCCESS = 402,
+ COMMENT_CONTENT = 403,
+ PI_CONTENT = 404,
+ PI_TARGET = 405,
+ XSLT_VERSION = 406,
+ TEMPLATE = 407,
+ TEXT = 408,
+ THEN = 409,
+ TO = 410,
+ TREAT = 411,
+ TUNNEL = 412,
+ TYPESWITCH = 413,
+ UNION = 414,
+ UNORDERED = 415,
+ VALIDATE = 416,
+ VARIABLE = 417,
+ VERSION = 418,
+ WHERE = 419,
+ XQUERY = 420,
+ INTERNAL = 421,
+ INTERNAL_NAME = 422,
+ CURRENT = 423
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/src/xmlpatterns/parser/qtokenizer_p.h b/src/xmlpatterns/parser/qtokenizer_p.h
new file mode 100644
index 0000000..3a50980
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenizer_p.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** 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_Tokenizer_H
+#define Patternist_Tokenizer_H
+
+#include <QPair>
+#include <QSharedData>
+#include <QString>
+#include <QUrl>
+
+#include "qparsercontext_p.h"
+#include "qtokensource_p.h"
+
+/**
+ * @file
+ * @short Contains functions and classes used by the parser and tokenizer.
+ */
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ typedef QPair<QString, Expression::Ptr> AttributeHolder;
+ typedef QVector<AttributeHolder> AttributeHolderVector;
+
+ class OrderSpecTransfer
+ {
+ public:
+ typedef QList<OrderSpecTransfer> List;
+ inline OrderSpecTransfer()
+ {
+ }
+
+ inline OrderSpecTransfer(const Expression::Ptr &aExpr,
+ const OrderBy::OrderSpec aOrderSpec) : expression(aExpr),
+ orderSpec(aOrderSpec)
+ {
+ Q_ASSERT(expression);
+ }
+
+ Expression::Ptr expression;
+ OrderBy::OrderSpec orderSpec;
+ };
+
+ /**
+ * @short The value the parser, but not the tokenizers, uses for tokens and
+ * non-terminals.
+ *
+ * It is inefficient but ensures nothing leaks, by invoking C++
+ * destructors even in the cases the code throws exceptions. This might be
+ * able to be done in a more efficient way -- suggestions are welcome.
+ */
+ class TokenValue
+ {
+ public:
+ QString sval;
+
+ Expression::Ptr expr;
+ Expression::List expressionList;
+
+ Cardinality cardinality;
+ ItemType::Ptr itemType;
+ SequenceType::Ptr sequenceType;
+ FunctionArgument::List functionArguments;
+ FunctionArgument::Ptr functionArgument;
+ QVector<QXmlName> qNameVector;
+ QXmlName qName;
+ /**
+ * Holds enum values.
+ */
+ EnumUnion enums;
+
+ AttributeHolder attributeHolder;
+ AttributeHolderVector attributeHolders;
+ OrderSpecTransfer::List orderSpecs;
+ OrderSpecTransfer orderSpec;
+ };
+}
+
+QT_END_NAMESPACE
+
+/**
+ * Macro for the data type of semantic values; int by default.
+ * See section Data Types of Semantic Values.
+ */
+#define YYSTYPE QPatternist::TokenValue
+
+#include "qquerytransformparser_p.h" /* This inclusion must be after TokenValue. */
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all tokenizers.
+ *
+ * The main entry point is nextToken(), which ones calls to retrieve the stream
+ * of tokens this Tokenizer delivers.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a
+ * Tokenizer for XPath or XQuery</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Tokenizer : public TokenSource
+ {
+ public:
+ inline Tokenizer(const QUrl &queryU) : m_queryURI(queryU)
+ {
+ Q_ASSERT(queryU.isValid());
+ }
+
+ typedef QExplicitlySharedDataPointer<Tokenizer> Ptr;
+
+ /**
+ * Switches the Tokenizer to only do scanning, and returns complete
+ * strings for attribute value templates as opposed to the tokens for
+ * the contained expressions.
+ *
+ * The current position in the stream is returned. It can be used to
+ * later resume regular tokenization.
+ */
+ virtual int commenceScanOnly() = 0;
+
+ /**
+ * Resumes regular parsing from @p position. The tokenizer must be in
+ * the scan-only state, which the commenceScanOnly() call transists to.
+ *
+ * The tokenizer will return the token POSITION_SET once after this
+ * function has been called.
+ */
+ virtual void resumeTokenizationFrom(const int position) = 0;
+
+ /**
+ * @returns the URI of the resource being tokenized.
+ */
+ inline const QUrl &queryURI() const
+ {
+ return m_queryURI;
+ }
+
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo) = 0;
+
+ protected:
+ /**
+ * Returns a string representation of @p token.
+ *
+ * This function is used for debugging purposes. The implementation of
+ * this function is in querytransformparser.ypp.
+ */
+ static QString tokenToString(const Token &token);
+
+ private:
+ Q_DISABLE_COPY(Tokenizer)
+ const QUrl m_queryURI;
+ };
+
+}
+
+#undef Patternist_DEBUG_PARSER // disable it for now
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qtokenlookup.cpp b/src/xmlpatterns/parser/qtokenlookup.cpp
new file mode 100644
index 0000000..a6ea7ed
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenlookup.cpp
@@ -0,0 +1,444 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+/* C++ code produced by gperf version 3.0.3 */
+/* Command-line: gperf TokenLookup.gperf */
+/* Computed positions: -k'1,3,$' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 107 "TokenLookup.gperf"
+
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+#line 101 "TokenLookup.gperf"
+struct TokenMap
+{
+ const char *name;
+ const Tokenizer::TokenType token;
+}
+
+
+/* The strings below are in UTF-16 encoding. Subsequently, each ASCII
+ * character is stored as the ASCII character, followed by a null byte.
+ * Sorted alphabetically. */;
+/* maximum key range = 228, duplicates = 0 */
+
+class TokenLookup
+{
+private:
+ static inline unsigned int hash (const char *str, unsigned int len);
+public:
+ static const struct TokenMap *value (const char *str, unsigned int len);
+};
+
+inline unsigned int
+TokenLookup::hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 25, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 0, 2, 5,
+ 25, 0, 20, 20, 35, 85, 230, 230, 40, 110,
+ 25, 65, 80, 0, 60, 5, 10, 0, 55, 5,
+ 20, 0, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
+ case 2:
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+const struct TokenMap *
+TokenLookup::value (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 99,
+ MIN_WORD_LENGTH = 2,
+ MAX_WORD_LENGTH = 22,
+ MIN_HASH_VALUE = 2,
+ MAX_HASH_VALUE = 229
+ };
+
+ static const struct TokenMap wordlist[] =
+ {
+ {"",ERROR}, {"",ERROR},
+#line 152 "TokenLookup.gperf"
+ {"eq", EQ},
+ {"",ERROR},
+#line 130 "TokenLookup.gperf"
+ {"by", BY},
+#line 153 "TokenLookup.gperf"
+ {"every", EVERY},
+ {"",ERROR},
+#line 123 "TokenLookup.gperf"
+ {"as", AS},
+ {"",ERROR},
+#line 148 "TokenLookup.gperf"
+ {"else", ELSE},
+#line 217 "TokenLookup.gperf"
+ {"where", WHERE},
+#line 204 "TokenLookup.gperf"
+ {"stable", STABLE},
+#line 126 "TokenLookup.gperf"
+ {"at", AT},
+ {"",ERROR},
+#line 131 "TokenLookup.gperf"
+ {"case", CASE},
+ {"",ERROR},
+#line 129 "TokenLookup.gperf"
+ {"boundary-space", BOUNDARY_SPACE},
+#line 147 "TokenLookup.gperf"
+ {"element", ELEMENT},
+#line 132 "TokenLookup.gperf"
+ {"castable", CASTABLE},
+#line 127 "TokenLookup.gperf"
+ {"attribute", ATTRIBUTE},
+ {"",ERROR},
+#line 154 "TokenLookup.gperf"
+ {"except", EXCEPT},
+#line 161 "TokenLookup.gperf"
+ {"ge", GE},
+ {"",ERROR},
+#line 133 "TokenLookup.gperf"
+ {"cast", CAST},
+#line 210 "TokenLookup.gperf"
+ {"treat", TREAT},
+#line 218 "TokenLookup.gperf"
+ {"xquery", XQUERY},
+#line 181 "TokenLookup.gperf"
+ {"ne", NE},
+ {"",ERROR},
+#line 198 "TokenLookup.gperf"
+ {"satisfies", SATISFIES},
+ {"",ERROR}, {"",ERROR},
+#line 163 "TokenLookup.gperf"
+ {"gt", GT},
+#line 151 "TokenLookup.gperf"
+ {"encoding", ENCODING},
+#line 124 "TokenLookup.gperf"
+ {"ascending", ASCENDING},
+ {"",ERROR},
+#line 125 "TokenLookup.gperf"
+ {"assign", ASSIGN},
+#line 139 "TokenLookup.gperf"
+ {"declare", DECLARE},
+#line 162 "TokenLookup.gperf"
+ {"greatest", GREATEST},
+#line 208 "TokenLookup.gperf"
+ {"then", THEN},
+ {"",ERROR},
+#line 121 "TokenLookup.gperf"
+ {"ancestor-or-self", ANCESTOR_OR_SELF},
+#line 175 "TokenLookup.gperf"
+ {"le", LE},
+#line 146 "TokenLookup.gperf"
+ {"document-node", DOCUMENT_NODE},
+#line 207 "TokenLookup.gperf"
+ {"text", TEXT},
+ {"",ERROR},
+#line 201 "TokenLookup.gperf"
+ {"schema", SCHEMA},
+ {"",ERROR},
+#line 145 "TokenLookup.gperf"
+ {"document", DOCUMENT},
+ {"",ERROR},
+#line 141 "TokenLookup.gperf"
+ {"descendant", DESCENDANT},
+ {"",ERROR},
+#line 177 "TokenLookup.gperf"
+ {"lt", LT},
+#line 122 "TokenLookup.gperf"
+ {"and", AND},
+#line 182 "TokenLookup.gperf"
+ {"node", NODE},
+#line 174 "TokenLookup.gperf"
+ {"least", LEAST},
+#line 199 "TokenLookup.gperf"
+ {"schema-attribute", SCHEMA_ATTRIBUTE},
+ {"",ERROR},
+#line 155 "TokenLookup.gperf"
+ {"external", EXTERNAL},
+ {"",ERROR},
+#line 143 "TokenLookup.gperf"
+ {"descending", DESCENDING},
+#line 184 "TokenLookup.gperf"
+ {"no-preserve", NO_PRESERVE},
+#line 140 "TokenLookup.gperf"
+ {"default", DEFAULT},
+#line 176 "TokenLookup.gperf"
+ {"let", LET},
+#line 200 "TokenLookup.gperf"
+ {"schema-element", SCHEMA_ELEMENT},
+ {"",ERROR}, {"",ERROR},
+#line 137 "TokenLookup.gperf"
+ {"construction", CONSTRUCTION},
+#line 142 "TokenLookup.gperf"
+ {"descendant-or-self", DESCENDANT_OR_SELF},
+#line 202 "TokenLookup.gperf"
+ {"self", SELF},
+#line 183 "TokenLookup.gperf"
+ {"no-inherit", NO_INHERIT},
+ {"",ERROR},
+#line 158 "TokenLookup.gperf"
+ {"follows", FOLLOWS},
+#line 120 "TokenLookup.gperf"
+ {"ancestor", ANCESTOR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 209 "TokenLookup.gperf"
+ {"to", TO},
+#line 160 "TokenLookup.gperf"
+ {"function", FUNCTION},
+#line 135 "TokenLookup.gperf"
+ {"collation", COLLATION},
+ {"",ERROR},
+#line 205 "TokenLookup.gperf"
+ {"strict", STRICT},
+ {"",ERROR},
+#line 173 "TokenLookup.gperf"
+ {"lax", LAX},
+ {"",ERROR},
+#line 149 "TokenLookup.gperf"
+ {"empty", EMPTY},
+ {"",ERROR},
+#line 185 "TokenLookup.gperf"
+ {"of", OF},
+#line 195 "TokenLookup.gperf"
+ {"preserve", PRESERVE},
+#line 156 "TokenLookup.gperf"
+ {"following", FOLLOWING},
+ {"",ERROR}, {"",ERROR},
+#line 171 "TokenLookup.gperf"
+ {"is", IS},
+#line 192 "TokenLookup.gperf"
+ {"precedes", PRECEDES},
+#line 150 "TokenLookup.gperf"
+ {"empty-sequence", EMPTY_SEQUENCE},
+ {"",ERROR}, {"",ERROR},
+#line 157 "TokenLookup.gperf"
+ {"following-sibling", FOLLOWING_SIBLING},
+#line 169 "TokenLookup.gperf"
+ {"instance", INSTANCE},
+#line 213 "TokenLookup.gperf"
+ {"unordered", UNORDERED},
+#line 128 "TokenLookup.gperf"
+ {"base-uri", BASEURI},
+#line 197 "TokenLookup.gperf"
+ {"return", RETURN},
+ {"",ERROR},
+#line 214 "TokenLookup.gperf"
+ {"validate", VALIDATE},
+ {"",ERROR},
+#line 138 "TokenLookup.gperf"
+ {"copy-namespaces", COPY_NAMESPACES},
+#line 186 "TokenLookup.gperf"
+ {"option", OPTION},
+#line 165 "TokenLookup.gperf"
+ {"if", IF},
+ {"",ERROR},
+#line 193 "TokenLookup.gperf"
+ {"preceding", PRECEDING},
+ {"",ERROR}, {"",ERROR},
+#line 168 "TokenLookup.gperf"
+ {"in", IN},
+ {"",ERROR},
+#line 170 "TokenLookup.gperf"
+ {"intersect", INTERSECT},
+#line 212 "TokenLookup.gperf"
+ {"union", UNION},
+ {"",ERROR},
+#line 194 "TokenLookup.gperf"
+ {"preceding-sibling", PRECEDING_SIBLING},
+#line 188 "TokenLookup.gperf"
+ {"ordering", ORDERING},
+#line 203 "TokenLookup.gperf"
+ {"some", SOME},
+#line 134 "TokenLookup.gperf"
+ {"child", CHILD},
+ {"",ERROR},
+#line 187 "TokenLookup.gperf"
+ {"ordered", ORDERED},
+#line 215 "TokenLookup.gperf"
+ {"variable", VARIABLE},
+ {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 190 "TokenLookup.gperf"
+ {"or", OR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 136 "TokenLookup.gperf"
+ {"comment", COMMENT},
+ {"",ERROR}, {"",ERROR},
+#line 211 "TokenLookup.gperf"
+ {"typeswitch", TYPESWITCH},
+ {"",ERROR},
+#line 167 "TokenLookup.gperf"
+ {"inherit", INHERIT},
+#line 144 "TokenLookup.gperf"
+ {"div", DIV},
+ {"",ERROR}, {"",ERROR},
+#line 179 "TokenLookup.gperf"
+ {"module", MODULE},
+ {"",ERROR},
+#line 159 "TokenLookup.gperf"
+ {"for", FOR},
+#line 180 "TokenLookup.gperf"
+ {"namespace", NAMESPACE},
+ {"",ERROR}, {"",ERROR},
+#line 216 "TokenLookup.gperf"
+ {"version", VERSION},
+ {"",ERROR}, {"",ERROR},
+#line 206 "TokenLookup.gperf"
+ {"strip", STRIP},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+#line 189 "TokenLookup.gperf"
+ {"order", ORDER},
+#line 191 "TokenLookup.gperf"
+ {"parent", PARENT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 178 "TokenLookup.gperf"
+ {"mod", MOD},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR},
+#line 166 "TokenLookup.gperf"
+ {"import", IMPORT},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 196 "TokenLookup.gperf"
+ {"processing-instruction", PROCESSING_INSTRUCTION},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR},
+#line 172 "TokenLookup.gperf"
+ {"item", ITEM},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR}, {"",ERROR}, {"",ERROR}, {"",ERROR},
+ {"",ERROR},
+#line 164 "TokenLookup.gperf"
+ {"idiv", IDIV}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register const char *s = wordlist[key].name;
+
+ if (*str == *s && !strcmp (str + 1, s + 1))
+ return &wordlist[key];
+ }
+ }
+ return 0;
+}
+#line 219 "TokenLookup.gperf"
+
+
+} /* Close the QPatternist namespace. */
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qtokenrevealer.cpp b/src/xmlpatterns/parser/qtokenrevealer.cpp
new file mode 100644
index 0000000..8e10204
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qtokenrevealer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TokenRevealer::TokenRevealer(const QUrl &uri,
+ const Tokenizer::Ptr &other) : Tokenizer(uri)
+ , m_tokenizer(other)
+{
+ Q_ASSERT(other);
+}
+
+TokenRevealer::~TokenRevealer()
+{
+ qDebug() << "Tokens Revealed:" << m_result;
+}
+
+void TokenRevealer::setParserContext(const ParserContext::Ptr &parseInfo)
+{
+ m_tokenizer->setParserContext(parseInfo);
+}
+
+Tokenizer::Token TokenRevealer::nextToken(YYLTYPE *const sourceLocator)
+{
+ const Token token(m_tokenizer->nextToken(sourceLocator));
+ const QString asString(tokenToString(token));
+ const TokenType type = token.type;
+
+ /* Indent. */
+ switch(type)
+ {
+ case CURLY_LBRACE:
+ {
+ m_result += QLatin1Char('\n') + m_indentationString + asString + QLatin1Char('\n');
+ m_indentationString.append(QLatin1String(" "));
+ m_result += m_indentationString;
+ break;
+ }
+ case CURLY_RBRACE:
+ {
+ m_indentationString.chop(4);
+ m_result += QLatin1Char('\n') + m_indentationString + asString;
+ break;
+ }
+ case SEMI_COLON:
+ /* Fallthrough. */
+ case COMMA:
+ {
+ m_result += asString + QLatin1Char('\n') + m_indentationString;
+ break;
+ }
+ default:
+ m_result += asString + QLatin1Char(' ');
+ }
+
+ return token;
+}
+
+int TokenRevealer::commenceScanOnly()
+{
+ return m_tokenizer->commenceScanOnly();
+}
+
+void TokenRevealer::resumeTokenizationFrom(const int position)
+{
+ m_tokenizer->resumeTokenizationFrom(position);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qtokenrevealer_p.h b/src/xmlpatterns/parser/qtokenrevealer_p.h
new file mode 100644
index 0000000..8b6ef96
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokenrevealer_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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_TokenRevealer_h
+#define Patternist_TokenRevealer_h
+
+#include <QSet>
+
+#include "qtokenizer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Delegates another Tokenizer, and while doing so
+ * prints the tokens it delivers to @c stderr.
+ *
+ * Hence, this class is used solely for debugging.
+ *
+ * @since 4.5
+ */
+ class TokenRevealer : public Tokenizer
+ {
+ public:
+ TokenRevealer(const QUrl &uri,
+ const Tokenizer::Ptr &other);
+
+ virtual ~TokenRevealer();
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+ virtual int commenceScanOnly();
+ virtual void resumeTokenizationFrom(const int position);
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ private:
+ const Tokenizer::Ptr m_tokenizer;
+ QString m_result;
+ QString m_indentationString;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/parser/qtokensource.cpp b/src/xmlpatterns/parser/qtokensource.cpp
new file mode 100644
index 0000000..99ad910
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include "qtokensource_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TokenSource::~TokenSource()
+{
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qtokensource_p.h b/src/xmlpatterns/parser/qtokensource_p.h
new file mode 100644
index 0000000..0ffb916
--- /dev/null
+++ b/src/xmlpatterns/parser/qtokensource_p.h
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** 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_TokenSource_H
+#define Patternist_TokenSource_H
+
+#include "qatomiccomparator_p.h"
+#include "qatomicmathematician_p.h"
+#include "qcombinenodes_p.h"
+#include "qfunctionargument_p.h"
+#include "qitem_p.h"
+#include "qitemtype_p.h"
+#include "qorderby_p.h"
+#include "qpath_p.h"
+#include "qquerytransformparser_p.h"
+#include "qvalidate_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QQueue;
+
+namespace QPatternist
+{
+ /**
+ * @short A union of all the enums the parser uses.
+ */
+ union EnumUnion
+ {
+ AtomicComparator::Operator valueOperator;
+ AtomicMathematician::Operator mathOperator;
+ CombineNodes::Operator combinedNodeOp;
+ QXmlNodeModelIndex::Axis axis;
+ QXmlNodeModelIndex::DocumentOrder nodeOperator;
+ StaticContext::BoundarySpacePolicy boundarySpacePolicy;
+ StaticContext::ConstructionMode constructionMode;
+ StaticContext::OrderingEmptySequence orderingEmptySequence;
+ StaticContext::OrderingMode orderingMode;
+ OrderBy::OrderSpec::Direction sortDirection;
+ Validate::Mode validationMode;
+ VariableSlotID slot;
+ int tokenizerPosition;
+ qint16 zeroer;
+ bool Bool;
+ xsDouble Double;
+ Path::Kind pathKind;
+ };
+
+ /**
+ * @short Base class for components that needs to return tokens.
+ *
+ * TokenSource represents a stream of Token instances. The end
+ * is reached when readNext() returns a Token constructed with
+ * END_OF_FILE.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a
+ * Tokenizer for XPath or XQuery</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class TokenSource : public QSharedData
+ {
+ public:
+ /**
+ * typedef for the enum Bison generates that contains
+ * the token symbols.
+ */
+ typedef yytokentype TokenType;
+
+ /**
+ * Represents a token by carrying its name and value.
+ */
+ class Token
+ {
+ public:
+ /**
+ * Constructs an invalid Token. This default constructor
+ * is need in Qt's container classes.
+ */
+ inline Token() {}
+ inline Token(const TokenType t) : type(t) {}
+ inline Token(const TokenType t, const QString &val) : type(t), value(val) {}
+
+ bool hasError() const
+ {
+ return type == ERROR;
+ }
+
+ TokenType type;
+ QString value;
+ };
+
+ typedef QExplicitlySharedDataPointer<TokenSource> Ptr;
+ typedef QQueue<Ptr> Queue;
+
+ /**
+ * The C++ compiler cannot synthesize it when we use the
+ * Q_DISABLE_COPY() macro.
+ */
+ inline TokenSource()
+ {
+ }
+
+ virtual ~TokenSource();
+
+ /**
+ * @returns the next token.
+ */
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator) = 0;
+
+ private:
+ Q_DISABLE_COPY(TokenSource)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/querytransformparser.ypp b/src/xmlpatterns/parser/querytransformparser.ypp
new file mode 100644
index 0000000..186538c
--- /dev/null
+++ b/src/xmlpatterns/parser/querytransformparser.ypp
@@ -0,0 +1,4680 @@
+/****************************************************************************
+**
+** 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.
+
+%{
+/****************************************************************************
+**
+** 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.
+
+#include <limits>
+
+#include <QUrl>
+
+#include "qabstractfloat_p.h"
+#include "qandexpression_p.h"
+#include "qanyuri_p.h"
+#include "qapplytemplate_p.h"
+#include "qargumentreference_p.h"
+#include "qarithmeticexpression_p.h"
+#include "qatomicstring_p.h"
+#include "qattributeconstructor_p.h"
+#include "qattributenamevalidator_p.h"
+#include "qaxisstep_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcalltemplate_p.h"
+#include "qcastableas_p.h"
+#include "qcastas_p.h"
+#include "qcombinenodes_p.h"
+#include "qcommentconstructor_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qcomputednamespaceconstructor_p.h"
+#include "qcontextitem_p.h"
+#include "qcopyof_p.h"
+#include "qcurrentitemstore_p.h"
+#include "qdebug_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qdocumentconstructor_p.h"
+#include "qelementconstructor_p.h"
+#include "qemptysequence_p.h"
+#include "qemptysequencetype_p.h"
+#include "qevaluationcache_p.h"
+#include "qexpressionfactory_p.h"
+#include "qexpressionsequence_p.h"
+#include "qexpressionvariablereference_p.h"
+#include "qexternalvariablereference_p.h"
+#include "qforclause_p.h"
+#include "qfunctioncall_p.h"
+#include "qfunctionfactory_p.h"
+#include "qfunctionsignature_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qgenericpredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qifthenclause_p.h"
+#include "qinstanceof_p.h"
+#include "qletclause_p.h"
+#include "qliteral_p.h"
+#include "qlocalnametest_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnamespacenametest_p.h"
+#include "qncnameconstructor_p.h"
+#include "qnodecomparison_p.h"
+#include "qnodesort_p.h"
+#include "qorderby_p.h"
+#include "qorexpression_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qpatternistlocale_p.h"
+#include "qpositionalvariablereference_p.h"
+#include "qprocessinginstructionconstructor_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnametest_p.h"
+#include "qqnamevalue_p.h"
+#include "qquantifiedexpression_p.h"
+#include "qrangeexpression_p.h"
+#include "qrangevariablereference_p.h"
+#include "qreturnorderby_p.h"
+#include "qschemanumeric_p.h"
+#include "qschematypefactory_p.h"
+#include "qsimplecontentconstructor_p.h"
+#include "qstaticbaseuristore_p.h"
+#include "qstaticcompatibilitystore_p.h"
+#include "qtemplateparameterreference_p.h"
+#include "qtemplate_p.h"
+#include "qtextnodeconstructor_p.h"
+#include "qtokenizer_p.h"
+#include "qtreatas_p.h"
+#include "qtypechecker_p.h"
+#include "qunaryexpression_p.h"
+#include "qunresolvedvariablereference_p.h"
+#include "quserfunctioncallsite_p.h"
+#include "qvaluecomparison_p.h"
+#include "qxpathhelper_p.h"
+#include "qxsltsimplecontentconstructor_p.h"
+
+/*
+ * The cpp generated with bison 2.1 wants to
+ * redeclare the C-like prototypes of 'malloc' and 'free', so we avoid that.
+ */
+#define YYMALLOC malloc
+#define YYFREE free
+
+QT_BEGIN_NAMESPACE
+
+/* Due to Qt's QT_BEGIN_NAMESPACE magic, we can't use `using namespace', for some
+ * undocumented reason. */
+namespace QPatternist
+{
+
+/**
+ * "Macro that you define with #define in the Bison declarations
+ * section to request verbose, specific error message strings when
+ * yyerror is called."
+ */
+#define YYERROR_VERBOSE 1
+
+#undef YYLTYPE_IS_TRIVIAL
+#define YYLTYPE_IS_TRIVIAL 0
+
+/* Suppresses `warning: "YYENABLE_NLS" is not defined`
+ * @c YYENABLE_NLS enables Bison internationalization, and we don't
+ * use that, so disable it. See the Bison Manual, section 4.5 Parser Internationalization.
+ */
+#define YYENABLE_NLS 0
+
+static inline QSourceLocation fromYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return QSourceLocation(parseInfo->tokenizer->queryURI(),
+ sourceLocator.first_line,
+ sourceLocator.first_column);
+}
+
+/**
+ * @internal
+ * @relates QXmlQuery
+ */
+typedef QFlags<QXmlQuery::QueryLanguage> QueryLanguages;
+
+/**
+ * @short Flags invalid expressions and declarations in the currently
+ * parsed language.
+ *
+ * Since this grammar is used for several languages: XQuery 1.0, XSL-T 2.0, and
+ * XPath 2.0 inside XSL-T, and field and selector patterns in W3C XML Schema's
+ * identity constraints, it is the union of all the constructs in these
+ * languages. However, when dealing with each language individually, we
+ * regularly need to disallow some expressions, such as direct element
+ * constructors when parsing XSL-T, or the typeswitch when parsing XPath.
+ *
+ * This is further complicated by that XSLTTokenizer sometimes generates code
+ * which is allowed in XQuery but not in XPath. For that reason the token
+ * INTERNAL is sometimes generated, which signals that an expression, for
+ * instance the @c let clause, should not be flagged as an error, because it's
+ * used for internal purposes.
+ *
+ * Hence, this function is called from each expression and declaration with @p
+ * allowedLanguages stating what languages it is allowed in.
+ *
+ * If @p isInternal is @c true, no error is raised. Otherwise, if the current
+ * language is not in @p allowedLanguages, an error is raised.
+ */
+static void allowedIn(const QueryLanguages allowedLanguages,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const bool isInternal = false)
+{
+ /* We treat XPath 2.0 as a subset of XSL-T 2.0, so if XPath 2.0 is allowed
+ * and XSL-T is the language, it's ok. */
+ if(!isInternal &&
+ (!allowedLanguages.testFlag(parseInfo->languageAccent) && !(allowedLanguages.testFlag(QXmlQuery::XPath20) && parseInfo->languageAccent == QXmlQuery::XSLT20)))
+ {
+
+ QString langName;
+
+ switch(parseInfo->languageAccent)
+ {
+ case QXmlQuery::XPath20:
+ langName = QLatin1String("XPath 2.0");
+ break;
+ case QXmlQuery::XSLT20:
+ langName = QLatin1String("XSL-T 2.0");
+ break;
+ case QXmlQuery::XQuery10:
+ langName = QLatin1String("XQuery 1.0");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintSelector:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint selector");
+ break;
+ case QXmlQuery::XmlSchema11IdentityConstraintField:
+ langName = QtXmlPatterns::tr("W3C XML Schema identity constraint field");
+ break;
+ }
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A construct was encountered "
+ "which is disallowed in the current language(%1).").arg(langName),
+ ReportContext::XPST0003,
+ fromYYLTYPE(sourceLocator, parseInfo));
+
+ }
+}
+
+static inline bool isVariableReference(const Expression::ID id)
+{
+ return id == Expression::IDExpressionVariableReference
+ || id == Expression::IDRangeVariableReference
+ || id == Expression::IDArgumentReference;
+}
+
+class ReflectYYLTYPE : public SourceLocationReflection
+{
+public:
+ inline ReflectYYLTYPE(const YYLTYPE &sourceLocator,
+ const ParserContext *const pi) : m_sl(sourceLocator)
+ , m_parseInfo(pi)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return this;
+ }
+
+ virtual QSourceLocation sourceLocation() const
+ {
+ return fromYYLTYPE(m_sl, m_parseInfo);
+ }
+
+ virtual QString description() const
+ {
+ Q_ASSERT(false);
+ return QString();
+ }
+
+private:
+ const YYLTYPE &m_sl;
+ const ParserContext *const m_parseInfo;
+};
+
+/**
+ * @short Centralizes a translation string for the purpose of increasing consistency.
+ */
+static inline QString unknownType()
+{
+ return QtXmlPatterns::tr("%1 is an unknown schema type.");
+}
+
+static inline Expression::Ptr create(Expression *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Expression::Ptr(expr);
+}
+
+static inline Template::Ptr create(Template *const expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr, fromYYLTYPE(sourceLocator, parseInfo));
+ return Template::Ptr(expr);
+}
+
+static inline Expression::Ptr create(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ parseInfo->staticContext->addLocation(expr.data(), fromYYLTYPE(sourceLocator, parseInfo));
+ return expr;
+}
+
+static Expression::Ptr createSimpleContent(const Expression::Ptr &source,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(parseInfo->isXSLT() ? new XSLTSimpleContentConstructor(source) : new SimpleContentConstructor(source),
+ sourceLocator,
+ parseInfo);
+}
+
+static void loadPattern(const Expression::Ptr &matchPattern,
+ TemplatePattern::Vector &ourPatterns,
+ const TemplatePattern::ID id,
+ const PatternPriority priority,
+ const Template::Ptr &temp)
+{
+ Q_ASSERT(temp);
+
+ const PatternPriority effectivePriority = qIsNaN(priority) ? matchPattern->patternPriority() : priority;
+
+ ourPatterns.append(TemplatePattern::Ptr(new TemplatePattern(matchPattern, effectivePriority, id, temp)));
+}
+
+static Expression::Ptr typeCheckTemplateBody(const Expression::Ptr &body,
+ const SequenceType::Ptr &reqType,
+ const ParserContext *const parseInfo)
+{
+ return TypeChecker::applyFunctionConversion(body, reqType,
+ parseInfo->staticContext,
+ ReportContext::XTTE0505,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert | TypeChecker::GeneratePromotion));
+}
+
+static void registerNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &body,
+ ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator,
+ const Template::Ptr &temp)
+{
+ Template::Ptr &e = parseInfo->namedTemplates[name];
+
+ if(e)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A template by name %1 "
+ "has already been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(),
+ name)),
+ ReportContext::XTSE0660,
+ fromYYLTYPE(sourceLocator, parseInfo));
+ }
+ else
+ {
+ e = temp;
+ e->body = body;
+ }
+}
+
+/**
+ * @short Centralizes code for creating numeric literals.
+ */
+template<typename TNumberClass>
+Expression::Ptr createNumericLiteral(const QString &in,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Item num(TNumberClass::fromLexical(in));
+
+ if(num.template as<AtomicValue>()->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid numeric literal.")
+ .arg(formatData(in)),
+ ReportContext::XPST0003, fromYYLTYPE(sl, parseInfo));
+ return Expression::Ptr(); /* Avoid compiler warning. */
+ }
+ else
+ return create(new Literal(num), sl, parseInfo);
+}
+
+/**
+ * @short The generated Bison parser calls this function when there is a parse error.
+ *
+ * It is not called, nor should be, for logical errors(which the Bison not know about). For those,
+ * ReportContext::error() is called.
+ */
+static int XPatherror(YYLTYPE *sourceLocator, const ParserContext *const parseInfo, const char *const msg)
+{
+ Q_UNUSED(sourceLocator);
+ Q_ASSERT(parseInfo);
+
+ parseInfo->staticContext->error(escape(QLatin1String(msg)), ReportContext::XPST0003, fromYYLTYPE(*sourceLocator, parseInfo));
+ return 1;
+}
+
+/**
+ * When we want to connect the OrderBy and ReturnOrderBy, it might be that we have other expressions, such
+ * as @c where and @c let inbetween. We need to continue through them. This function does that.
+ */
+static ReturnOrderBy *locateReturnClause(const Expression::Ptr &expr)
+{
+ Q_ASSERT(expr);
+
+ const Expression::ID id = expr->id();
+ if(id == Expression::IDLetClause || id == Expression::IDIfThenClause || id == Expression::IDForClause)
+ return locateReturnClause(expr->operands()[1]);
+ else if(id == Expression::IDReturnOrderBy)
+ return expr->as<ReturnOrderBy>();
+ else
+ return 0;
+}
+
+static inline bool isPredicate(const Expression::ID id)
+{
+ return id == Expression::IDGenericPredicate ||
+ id == Expression::IDFirstItemPredicate;
+}
+
+/**
+ * Assumes expr is an AxisStep wrapped in some kind of predicates or paths. Filters
+ * through the predicates and returns the AxisStep.
+ */
+static Expression::Ptr findAxisStep(const Expression::Ptr &expr,
+ const bool throughStructures = true)
+{
+ Q_ASSERT(expr);
+
+ if(!throughStructures)
+ return expr;
+
+ Expression *candidate = expr.data();
+ Expression::ID id = candidate->id();
+
+ while(isPredicate(id) || id == Expression::IDPath)
+ {
+ const Expression::List &children = candidate->operands();
+ if(children.isEmpty())
+ return Expression::Ptr();
+ else
+ {
+ candidate = children.first().data();
+ id = candidate->id();
+ }
+ }
+
+ if(id == Expression::IDEmptySequence)
+ return Expression::Ptr();
+ else
+ {
+ Q_ASSERT(candidate->is(Expression::IDAxisStep));
+ return Expression::Ptr(candidate);
+ }
+}
+
+static void changeToTopAxis(const Expression::Ptr &op)
+{
+ /* This axis must have been written away by now. */
+ Q_ASSERT(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisChild);
+
+ if(op->as<AxisStep>()->axis() != QXmlNodeModelIndex::AxisSelf)
+ op->as<AxisStep>()->setAxis(QXmlNodeModelIndex::AxisAttributeOrTop);
+}
+
+/**
+ * @short Writes @p operand1 and @p operand2, two operands in an XSL-T pattern,
+ * into an equivalent XPath expression.
+ *
+ * Essentially, the following rewrite is done:
+ *
+ * <tt>
+ * axis1::test1(a)/axis2::test2(b)
+ * =>
+ * child-or-top::test2(b)[parent::test1(a)]
+ * </tt>
+ *
+ * Section 5.5.3 The Meaning of a Pattern talks about rewrites that are applied to
+ * only the first step in a pattern, but since we're doing rewrites more radically,
+ * its line of reasoning cannot be followed.
+ *
+ * Keep in mind the rewrites that non-terminal PatternStep do.
+ *
+ * @see createIdPatternPath()
+ */
+static inline Expression::Ptr createPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandL(findAxisStep(operand1, false));
+
+ if(operandL->is(Expression::IDAxisStep))
+ operandL->as<AxisStep>()->setAxis(axis);
+ else
+ findAxisStep(operand1)->as<AxisStep>()->setAxis(axis);
+
+ return create(GenericPredicate::create(operand2, operandL,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Performs the same role as createPatternPath(), but is tailored
+ * for @c fn:key() and @c fn:id().
+ *
+ * @c fn:key() and @c fn:id() can be part of path patterns(only as the first step,
+ * to be precise) and that poses a challenge to rewriting because what
+ * createPatternPath() is not possible to express, since the functions cannot be
+ * node tests. E.g, this rewrite is not possible:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::id-or-key]
+ * </tt>
+ *
+ * Our approach is to rewrite like this:
+ *
+ * <tt>
+ * id-or-key/abc
+ * =>
+ * child-or-top::abc[parent::node is id-or-key]
+ * </tt>
+ *
+ * @p operand1 is the call to @c fn:key() or @c fn:id(), @p operand2
+ * the right operand, and @p axis the target axis to rewrite to.
+ *
+ * @see createPatternPath()
+ */
+static inline Expression::Ptr createIdPatternPath(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const QXmlNodeModelIndex::Axis axis,
+ const YYLTYPE &sl,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr operandR(findAxisStep(operand2));
+ Q_ASSERT(operandR);
+ changeToTopAxis(operandR);
+
+ const Expression::Ptr parentStep(create(new AxisStep(axis, BuiltinTypes::node),
+ sl,
+ parseInfo));
+ const Expression::Ptr isComp(create(new NodeComparison(parentStep,
+ QXmlNodeModelIndex::Is,
+ operand1),
+ sl,
+ parseInfo));
+
+ return create(GenericPredicate::create(operandR, isComp,
+ parseInfo->staticContext, fromYYLTYPE(sl, parseInfo)), sl, parseInfo);
+}
+
+/**
+ * @short Centralizes a translation message, for the
+ * purpose of consistency and modularization.
+ */
+static inline QString prologMessage(const char *const msg)
+{
+ Q_ASSERT(msg);
+ return QtXmlPatterns::tr("Only one %1 declaration can occur in the query prolog.").arg(formatKeyword(msg));
+}
+
+/**
+ * @short Resolves against the static base URI and checks that @p collation
+ * is a supported Unicode Collation.
+ *
+ * "If a default collation declaration specifies a collation by a
+ * relative URI, that relative URI is resolved to an absolute
+ * URI using the base URI in the static context."
+ *
+ * @returns the Unicode Collation properly resolved, if @p collation is a valid collation
+ */
+template<const ReportContext::ErrorCode errorCode>
+static QUrl resolveAndCheckCollation(const QString &collation,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ QUrl uri(AnyURI::toQUrl<ReportContext::XQST0046>(collation, parseInfo->staticContext, &ryy));
+
+ if(uri.isRelative())
+ uri = parseInfo->staticContext->baseURI().resolved(uri);
+
+ XPathHelper::checkCollationSupport<errorCode>(uri.toString(), parseInfo->staticContext, &ryy);
+
+ return uri;
+}
+
+/* The Bison generated parser declares macros that aren't used
+ * so suppress the warnings by fake usage of them.
+ *
+ * We do the same for some more defines in the first action. */
+#if defined(YYLSP_NEEDED) \
+ || defined(YYBISON) \
+ || defined(YYBISON_VERSION) \
+ || defined(YYPURE) \
+ || defined(yydebug) \
+ || defined(YYSKELETON_NAME)
+#endif
+
+/**
+ * Wraps @p operand with a CopyOf in case it makes any difference.
+ *
+ * There is no need to wrap the return value in a call to create(), it's
+ * already done.
+ */
+static Expression::Ptr createCopyOf(const Expression::Ptr &operand,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ return create(new CopyOf(operand, parseInfo->inheritNamespacesMode,
+ parseInfo->preserveNamespacesMode), sl, parseInfo);
+}
+
+static Expression::Ptr createCompatStore(const Expression::Ptr &expr,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ return create(new StaticCompatibilityStore(expr), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates an Expression that corresponds to <tt>/</tt>. This is literally
+ * <tt>fn:root(self::node()) treat as document-node()</tt>.
+ */
+static Expression::Ptr createRootExpression(const ParserContext *const parseInfo,
+ const YYLTYPE &sl)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::root);
+
+ Expression::List args;
+ args.append(create(new ContextItem(), sl, parseInfo));
+
+ const ReflectYYLTYPE ryy(sl, parseInfo);
+
+ const Expression::Ptr fnRoot(parseInfo->staticContext->functionSignatures()
+ ->createFunctionCall(name, args, parseInfo->staticContext, &ryy));
+ Q_ASSERT(fnRoot);
+
+ return create(new TreatAs(create(fnRoot, sl, parseInfo), CommonSequenceTypes::ExactlyOneDocumentNode), sl, parseInfo);
+}
+
+static int XPathlex(YYSTYPE *lexVal, YYLTYPE *sourceLocator, const ParserContext *const parseInfo)
+{
+#ifdef Patternist_DEBUG_PARSER
+ /**
+ * "External integer variable set to zero by default. If yydebug
+ * is given a nonzero value, the parser will output information on
+ * input symbols and parser action. See section Debugging Your Parser."
+ */
+# define YYDEBUG 1
+
+ extern int XPathdebug;
+ XPathdebug = 1;
+#endif
+
+ Q_ASSERT(parseInfo);
+
+ const Tokenizer::Token tok(parseInfo->tokenizer->nextToken(sourceLocator));
+
+ (*lexVal).sval = tok.value;
+
+ return static_cast<int>(tok.type);
+}
+
+/**
+ * @short Creates a path expression which contains the step <tt>//</tt> between
+ * @p begin and and @p end.
+ *
+ * <tt>begin//end</tt> is a short form for: <tt>begin/descendant-or-self::node()/end</tt>
+ *
+ * This will be compiled as two-path expression: <tt>(/)/(//.)/step/</tt>
+ */
+static Expression::Ptr createSlashSlashPath(const Expression::Ptr &begin,
+ const Expression::Ptr &end,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ const Expression::Ptr twoSlash(create(new AxisStep(QXmlNodeModelIndex::AxisDescendantOrSelf, BuiltinTypes::node), sourceLocator, parseInfo));
+ const Expression::Ptr p1(create(new Path(begin, twoSlash), sourceLocator, parseInfo));
+
+ return create(new Path(p1, end), sourceLocator, parseInfo);
+}
+
+/**
+ * @short Creates a call to <tt>fn:concat()</tt> with @p args as the arguments.
+ */
+static inline Expression::Ptr createConcatFN(const ParserContext *const parseInfo,
+ const Expression::List &args,
+ const YYLTYPE &sourceLocator)
+{
+ Q_ASSERT(parseInfo);
+ const QXmlName name(StandardNamespaces::fn, StandardLocalNames::concat);
+ const ReflectYYLTYPE ryy(sourceLocator, parseInfo);
+
+ return create(parseInfo->staticContext->functionSignatures()->createFunctionCall(name, args, parseInfo->staticContext, &ryy),
+ sourceLocator, parseInfo);
+}
+
+static inline Expression::Ptr createDirAttributeValue(const Expression::List &content,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &sourceLocator)
+{
+ if(content.isEmpty())
+ return create(new EmptySequence(), sourceLocator, parseInfo);
+ else if(content.size() == 1)
+ return content.first();
+ else
+ return createConcatFN(parseInfo, content, sourceLocator);
+}
+
+/**
+ * @short Checks for variable initialization circularity.
+ *
+ * "A recursive function that checks for recursion is full of ironies."
+ *
+ * -- The Salsa Master
+ *
+ * Issues an error via @p parseInfo's StaticContext if the initialization
+ * expression @p checkee for the global variable @p var, contains a variable
+ * reference to @p var. That is, if there's a circularity.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#ERRXQST0054">XQuery 1.0: An XML
+ * Query Language, err:XQST0054</a>
+ */
+static void checkVariableCircularity(const VariableDeclaration::Ptr &var,
+ const Expression::Ptr &checkee,
+ const VariableDeclaration::Type type,
+ FunctionSignature::List &signList,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(var);
+ Q_ASSERT(checkee);
+ Q_ASSERT(parseInfo);
+
+ const Expression::ID id = checkee->id();
+
+ if(id == Expression::IDExpressionVariableReference)
+ {
+ const ExpressionVariableReference *const ref =
+ static_cast<const ExpressionVariableReference *>(checkee.data());
+
+ if(var->slot == ref->slot() && type == ref->variableDeclaration()->type)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The initialization of variable %1 "
+ "depends on itself").arg(formatKeyword(var, parseInfo->staticContext->namePool())),
+ parseInfo->isXSLT() ? ReportContext::XTDE0640 : ReportContext::XQST0054, ref);
+ return;
+ }
+ else
+ {
+ /* If the variable we're checking is below another variable, it can be a recursive
+ * dependency through functions, so we need to check variable references too. */
+ checkVariableCircularity(var, ref->sourceExpression(), type, signList, parseInfo);
+ return;
+ }
+ }
+ else if(id == Expression::IDUserFunctionCallsite)
+ {
+ const UserFunctionCallsite::Ptr callsite(checkee);
+ const FunctionSignature::Ptr sign(callsite->callTargetDescription());
+ const FunctionSignature::List::const_iterator end(signList.constEnd());
+ FunctionSignature::List::const_iterator it(signList.constBegin());
+ bool noMatch = true;
+
+ for(; it != end; ++it)
+ {
+ if(*it == sign)
+ {
+ /* The variable we're checking is depending on a function that's recursive. The
+ * user has written a weird query, in other words. Since it's the second time
+ * we've encountered a callsite, we now skip it. */
+ noMatch = false;
+ break;
+ }
+ }
+
+ if(noMatch)
+ {
+ signList.append(sign);
+ /* Check the body of the function being called. */
+ checkVariableCircularity(var, callsite->body(), type, signList, parseInfo);
+ }
+ /* Continue with the operands, such that we also check the arguments of the callsite. */
+ }
+ else if(id == Expression::IDUnresolvedVariableReference)
+ {
+ /* We're called before it has rewritten itself. */
+ checkVariableCircularity(var, checkee->as<UnresolvedVariableReference>()->replacement(), type, signList, parseInfo);
+ }
+
+ /* Check the operands. */
+ const Expression::List ops(checkee->operands());
+ if(ops.isEmpty())
+ return;
+
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkVariableCircularity(var, *it, type, signList, parseInfo);
+}
+
+static void variableUnavailable(const QXmlName &variableName,
+ const ParserContext *const parseInfo,
+ const YYLTYPE &location)
+{
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No variable with name %1 exists")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), variableName)),
+ ReportContext::XPST0008, fromYYLTYPE(location, parseInfo));
+}
+
+/**
+ * The Cardinality in a TypeDeclaration for a variable in a quantification has no effect,
+ * and this function ensures this by changing @p type to Cardinality Cardinality::zeroOrMore().
+ *
+ * @see <a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=3305">Bugzilla Bug 3305
+ * Cardinality + on range variables</a>
+ * @see ParserContext::finalizePushedVariable()
+ */
+static inline SequenceType::Ptr quantificationType(const SequenceType::Ptr &type)
+{
+ Q_ASSERT(type);
+ return makeGenericSequenceType(type->itemType(), Cardinality::zeroOrMore());
+}
+
+/**
+ * @p seqType and @p expr may be @c null.
+ */
+static Expression::Ptr pushVariable(const QXmlName name,
+ const SequenceType::Ptr &seqType,
+ const Expression::Ptr &expr,
+ const VariableDeclaration::Type type,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool checkSource = true)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* -2 will cause Q_ASSERTs to trigger if it isn't changed. */
+ VariableSlotID slot = -2;
+
+ switch(type)
+ {
+ case VariableDeclaration::FunctionArgument:
+ /* Fallthrough. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ slot = parseInfo->allocateExpressionSlot();
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ {
+ slot = parseInfo->allocateGlobalVariableSlot();
+ break;
+ }
+ case VariableDeclaration::RangeVariable:
+ {
+ slot = parseInfo->staticContext->allocateRangeSlot();
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ slot = parseInfo->allocatePositionalSlot();
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ /* Fallthrough. We do nothing, template parameters
+ * doesn't use context slots at all, they're hashed
+ * on the name. */
+ case VariableDeclaration::ExternalVariable:
+ /* We do nothing, external variables doesn't use
+ *context slots/stack frames at all. */
+ ;
+ }
+
+ const VariableDeclaration::Ptr var(new VariableDeclaration(name, slot, type, seqType));
+
+ Expression::Ptr checked;
+
+ if(checkSource && seqType)
+ {
+ if(expr)
+ {
+ /* We only want to add conversion for function arguments, and variables
+ * if we're XSL-T.
+ *
+ * We unconditionally skip TypeChecker::CheckFocus because the StaticContext we
+ * pass hasn't set up the focus yet, since that's the parent's responsibility. */
+ const TypeChecker::Options options(( type == VariableDeclaration::FunctionArgument
+ || type == VariableDeclaration::TemplateParameter
+ || parseInfo->isXSLT())
+ ? TypeChecker::AutomaticallyConvert : TypeChecker::Options());
+
+ checked = TypeChecker::applyFunctionConversion(expr, seqType, parseInfo->staticContext,
+ parseInfo->isXSLT() ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ options);
+ }
+ }
+ else
+ checked = expr;
+
+ /* Add an evaluation cache for all expression variables. No EvaluationCache is needed for
+ * positional variables because in the end they are calls to Iterator::position(). Similarly,
+ * no need to cache range variables either because they are calls to DynamicContext::rangeVariable().
+ *
+ * We don't do it for function arguments because the Expression being cached depends -- it depends
+ * on the callsite. UserFunctionCallsite is responsible for the evaluation caches in that case.
+ *
+ * In some cases the EvaluationCache instance isn't necessary, but in those cases EvaluationCache
+ * optimizes itself away. */
+ if(type == VariableDeclaration::ExpressionVariable)
+ checked = create(new EvaluationCache<false>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+ else if(type == VariableDeclaration::GlobalVariable)
+ checked = create(new EvaluationCache<true>(checked, var, parseInfo->allocateCacheSlot()), sourceLocator, parseInfo);
+
+ var->setExpression(checked);
+
+ parseInfo->variables.push(var);
+ return checked;
+}
+
+static inline VariableDeclaration::Ptr variableByName(const QXmlName name,
+ const ParserContext *const parseInfo)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(parseInfo);
+
+ /* We walk the list backwards. */
+ const VariableDeclaration::Stack::const_iterator start(parseInfo->variables.constBegin());
+ VariableDeclaration::Stack::const_iterator it(parseInfo->variables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ Q_ASSERT(*it);
+ if((*it)->name == name)
+ return *it;
+ }
+
+ return VariableDeclaration::Ptr();
+}
+
+static Expression::Ptr resolveVariable(const QXmlName &name,
+ const YYLTYPE &sourceLocator,
+ ParserContext *const parseInfo,
+ const bool raiseErrorOnUnavailability)
+{
+ const VariableDeclaration::Ptr var(variableByName(name, parseInfo));
+ Expression::Ptr retval;
+
+ if(var && var->type != VariableDeclaration::ExternalVariable)
+ {
+ switch(var->type)
+ {
+ case VariableDeclaration::RangeVariable:
+ {
+ retval = create(new RangeVariableReference(var->expression(), var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::GlobalVariable:
+ /* Fallthrough. From the perspective of an ExpressionVariableReference, it can't tell
+ * a difference between a global and a local expression variable. However, the cache
+ * mechanism must. */
+ case VariableDeclaration::ExpressionVariable:
+ {
+ retval = create(new ExpressionVariableReference(var->slot, var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::FunctionArgument:
+ {
+ retval = create(new ArgumentReference(var->sequenceType, var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::PositionalVariable:
+ {
+ retval = create(new PositionalVariableReference(var->slot), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::TemplateParameter:
+ {
+ retval = create(new TemplateParameterReference(var), sourceLocator, parseInfo);
+ break;
+ }
+ case VariableDeclaration::ExternalVariable:
+ /* This code path will never be hit, but the case
+ * label silences a warning. See above. */
+ ;
+ }
+ Q_ASSERT(retval);
+ var->references.append(retval);
+ }
+ else
+ {
+ /* Let's see if your external variable loader can provide us with one. */
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable(name, CommonSequenceTypes::ZeroOrMoreItems));
+
+ if(varType)
+ {
+ const Expression::Ptr extRef(create(new ExternalVariableReference(name, varType), sourceLocator, parseInfo));
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion(extRef, varType, parseInfo->staticContext));
+ retval = checked;
+ }
+ else if(!raiseErrorOnUnavailability && parseInfo->isXSLT())
+ {
+ /* In XSL-T, global variables are in scope for the whole
+ * stylesheet, so we must resolve this first at the end. */
+ retval = create(new UnresolvedVariableReference(name), sourceLocator, parseInfo);
+ parseInfo->unresolvedVariableReferences.insert(name, retval);
+ }
+ else
+ variableUnavailable(name, parseInfo, sourceLocator);
+ }
+
+ return retval;
+}
+
+static Expression::Ptr createReturnOrderBy(const OrderSpecTransfer::List &orderSpecTransfer,
+ const Expression::Ptr &returnExpr,
+ const OrderBy::Stability stability,
+ const YYLTYPE &sourceLocator,
+ const ParserContext *const parseInfo)
+{
+ // TODO do resize(orderSpec.size() + 1)
+ Expression::List exprs;
+ OrderBy::OrderSpec::Vector orderSpecs;
+
+ exprs.append(returnExpr);
+
+ const int len = orderSpecTransfer.size();
+
+ for(int i = 0; i < len; ++i)
+ {
+ exprs.append(orderSpecTransfer.at(i).expression);
+ orderSpecs.append(orderSpecTransfer.at(i).orderSpec);
+ }
+
+ return create(new ReturnOrderBy(stability, orderSpecs, exprs), sourceLocator, parseInfo);
+}
+
+%}
+
+/* This grammar shouldn't be compiled with anything older than the Bison version
+ * specified below. This '%require' directive was introduced in Bison 2.2. */
+%require "2.3a"
+
+%name-prefix="XPath"
+
+/* Specifies the name of the generated parser. */
+%output="qquerytransformparser.cpp"
+
+/* Output the .output file. */
+%verbose
+
+/* Yes, we want descriptive error messages. */
+%error-verbose
+
+/* We'd like to be reentrant/thread-safe */
+%pure-parser
+
+/* We want code for line/columns to be generated. */
+%locations
+
+/* Create a header file and put declarations there. */
+%defines
+
+%parse-param {ParserContext *const parseInfo}
+%lex-param {ParserContext *const parseInfo}
+
+%expect 4
+/* Silences the following:
+
+state 327
+
+ 293 SequenceType: ItemType . OccurrenceIndicator
+
+ "+" shift, and go to state 379
+ "*" shift, and go to state 380
+ "?" shift, and go to state 381
+
+ "+" [reduce using rule 295 (OccurrenceIndicator)]
+ "*" [reduce using rule 295 (OccurrenceIndicator)]
+ $default reduce using rule 295 (OccurrenceIndicator)
+
+ OccurrenceIndicator go to state 382
+
+state 45
+
+ 200 PathExpr: "/" . RelativePathExpr
+ 203 | "/" .
+
+ [...]
+
+ "<" [reduce using rule 203 (PathExpr)]
+ "*" [reduce using rule 203 (PathExpr)]
+ $default reduce using rule 203 (PathExpr)
+*/
+
+%token <sval> STRING_LITERAL "<string literal>"
+
+/**
+ * This token is only used in element content and signals content that
+ * is not Boundary whitespace. Nevertheless, the token value can be all whitespace,
+ * but it was specified using character references or CDATA sections by the user. */
+%token <sval> NON_BOUNDARY_WS "<non-boundary text node>"
+
+/* XPath 2.0 allows quotes and apostrophes to be escaped with "" and ''; this token is
+ is used for XPath 2.0 literals such that we can flag syntax errors if running in
+ 1.0 mode. */
+%token <sval> XPATH2_STRING_LITERAL "<string literal(XPath 2.0)>"
+%token <sval> QNAME "QName"
+%token <sval> NCNAME "NCName"
+
+/* A QName as a clark name. See QXmlName::toClarkName(). */
+%token <sval> CLARK_NAME "ClarkName"
+
+/**
+ * Is "ncname:*". The token value does not include the colon and the star.
+ */
+%token <sval> ANY_LOCAL_NAME
+
+/**
+ * Is "*:ncname". The token value does not include the colon and the star.
+ */
+%token <sval> ANY_PREFIX
+
+/**
+ * An XPath 1.0 number literal. It is a string value because
+ * Numeric::fromLexical() does the tokenization.
+ */
+%token <sval> NUMBER "<number literal>"
+
+/**
+ * XPath 2.0 number literal. It includes the use of 'e'/'E'
+ */
+%token <sval> XPATH2_NUMBER "<number literal(XPath 2.0)>"
+
+%token ANCESTOR "ancestor"
+%token ANCESTOR_OR_SELF "ancestor-or-self"
+%token AND "and"
+%token APOS "'"
+%token APPLY_TEMPLATE "apply-template"
+%token AS "as"
+%token ASCENDING "ascending"
+%token ASSIGN ":="
+%token AT "at"
+%token AT_SIGN "@"
+%token ATTRIBUTE "attribute"
+%token AVT /* Synthetic token. Signals an attribute value template. */
+%token BAR "|"
+%token BASEURI "base-uri"
+%token BEGIN_END_TAG "</"
+%token BOUNDARY_SPACE "boundary-space"
+%token BY "by"
+%token CALL_TEMPLATE "call-template"
+%token CASE "case"
+%token CASTABLE "castable"
+%token CAST "cast"
+%token CHILD "child"
+%token COLLATION "collation"
+%token COLONCOLON "::"
+%token COMMA ","
+%token COMMENT "comment"
+%token COMMENT_START "<!--"
+%token CONSTRUCTION "construction"
+%token COPY_NAMESPACES "copy-namespaces"
+%token CURLY_LBRACE "{"
+%token CURLY_RBRACE "}"
+%token DECLARE "declare"
+%token DEFAULT "default"
+%token DESCENDANT "descendant"
+%token DESCENDANT_OR_SELF "descendant-or-self"
+%token DESCENDING "descending"
+%token DIV "div"
+%token DOCUMENT "document"
+%token DOCUMENT_NODE "document-node"
+%token DOLLAR "$"
+%token DOT "."
+%token DOTDOT ".."
+%token ELEMENT "element"
+%token ELSE "else"
+%token EMPTY "empty"
+%token EMPTY_SEQUENCE "empty-sequence"
+%token ENCODING "encoding"
+%token END_OF_FILE 0 "end of file"
+%token END_SORT "end_sort"
+%token EQ "eq"
+%token ERROR "unknown keyword" /* Used by the Tokenizer. We use the phrase "keyword" instead of "token" to be less pointy. */
+%token EVERY "every"
+%token EXCEPT "except"
+%token EXTERNAL "external"
+%token FOLLOWING "following"
+%token FOLLOWING_SIBLING "following-sibling"
+%token FOLLOWS ">>"
+%token FOR_APPLY_TEMPLATE "for-apply-template" /* Synthetic token, used in XSL-T. */
+%token FOR "for"
+%token FUNCTION "function"
+%token GE "ge"
+%token G_EQ "="
+%token G_GE ">="
+%token G_GT ">"
+%token G_LE "<="
+%token G_LT "<"
+%token G_NE "!="
+%token GREATEST "greatest"
+%token GT "gt"
+%token IDIV "idiv"
+%token IF "if"
+%token IMPORT "import"
+%token INHERIT "inherit"
+%token IN "in"
+%token INSTANCE "instance"
+%token INTERSECT "intersect"
+%token IS "is"
+%token ITEM "item"
+%token LAX "lax"
+%token LBRACKET "["
+%token LEAST "least"
+%token LE "le"
+%token LET "let"
+%token LPAREN "("
+%token LT "lt"
+%token MAP "map" /* Synthetic token, used in XSL-T. */
+%token MATCHES "matches"
+%token MINUS "-"
+%token MODE "mode" /* Synthetic token, used in XSL-T. */
+%token MOD "mod"
+%token MODULE "module"
+%token NAME "name"
+%token NAMESPACE "namespace"
+%token NE "ne"
+%token NODE "node"
+%token NO_INHERIT "no-inherit"
+%token NO_PRESERVE "no-preserve"
+%token OF "of"
+%token OPTION "option"
+%token ORDERED "ordered"
+%token ORDERING "ordering"
+%token ORDER "order"
+%token OR "or"
+%token PARENT "parent"
+%token PI_START "<?"
+%token PLUS "+"
+%token POSITION_SET /* Synthetic token. */
+%token PRAGMA_END "#)"
+%token PRAGMA_START "(#"
+%token PRECEDES "<<"
+%token PRECEDING "preceding"
+%token PRECEDING_SIBLING "preceding-sibling"
+%token PRESERVE "preserve"
+%token PRIORITY "priority"
+%token PROCESSING_INSTRUCTION "processing-instruction"
+%token QUESTION "?"
+%token QUICK_TAG_END "/>"
+%token QUOTE "\""
+%token RBRACKET "]"
+%token RETURN "return"
+%token RPAREN ")"
+%token SATISFIES "satisfies"
+%token SCHEMA_ATTRIBUTE "schema-attribute"
+%token SCHEMA_ELEMENT "schema-element"
+%token SCHEMA "schema"
+%token SELF "self"
+%token SEMI_COLON ";"
+%token SLASH "/"
+%token SLASHSLASH "//"
+%token SOME "some"
+%token SORT "sort" /* Synthetic token, used in XSL-T. */
+%token STABLE "stable"
+%token STAR "*"
+%token STRICT "strict"
+%token STRIP "strip"
+%token SUCCESS /* Synthetic token, used by the Tokenizer. */
+%token <sval> COMMENT_CONTENT
+%token <sval> PI_CONTENT
+%token <sval> PI_TARGET
+%token <sval> XSLT_VERSION /* Synthetic token, used in XSL-T. */
+%token TEMPLATE "template"
+%token TEXT "text"
+%token THEN "then"
+%token TO "to"
+%token TREAT "treat"
+%token TUNNEL "tunnel" /* Synthetic token, used in XSL-T. */
+%token TYPESWITCH "typeswitch"
+%token UNION "union"
+%token UNORDERED "unordered"
+%token VALIDATE "validate"
+%token VARIABLE "variable"
+%token VERSION "version"
+%token WHERE "where"
+%token XQUERY "xquery"
+%token INTERNAL "internal" /* Synthetic token, used in XSL-T. */
+%token INTERNAL_NAME "internal-name" /* Synthetic token, used in XSL-T. */
+%token CURRENT "current" /* Synthetic token, used in XSL-T. */
+
+/* Alphabetically. */
+%type <attributeHolder> Attribute
+%type <attributeHolders> DirAttributeList
+%type <cardinality> OccurrenceIndicator
+%type <enums.axis> Axis AxisToken
+%type <enums.boundarySpacePolicy> BoundarySpacePolicy
+%type <enums.combinedNodeOp> IntersectOperator
+%type <enums.constructionMode> ConstructionMode
+%type <enums.mathOperator> MultiplyOperator AdditiveOperator UnaryOperator
+%type <enums.nodeOperator> NodeOperator
+%type <enums.orderingEmptySequence> OrderingEmptySequence EmptynessModifier
+%type <enums.sortDirection> DirectionModifier
+
+%type <enums.orderingMode> OrderingMode
+%type <enums.slot> PositionalVar
+%type <enums.validationMode> ValidationMode
+%type <enums.valueOperator> ValueComparisonOperator GeneralComparisonOperator
+%type <expr> OrExpr AndExpr ComparisonExpr UnionExpr Literal
+ AdditiveExpr MultiplicativeExpr PrimaryExpr FilterExpr
+ StepExpr PathExpr RelativePathExpr Expr ExprSingle
+ VarRef ContextItemExpr IfExpr CastExpr CastableExpr
+ TreatExpr InstanceOfExpr ValueExpr UnaryExpr NodeComp
+ IntersectExceptExpr RangeExpr ParenthesizedExpr
+ ValueComp FunctionCallExpr GeneralComp ForClause
+ WhereClause FLWORExpr ForTail QuantifiedExpr QueryBody
+ SomeQuantificationExpr SomeQuantificationTail
+ EveryQuantificationExpr EveryQuantificationTail
+ ExtensionExpr EnclosedOptionalExpr VariableValue
+ EnclosedExpr FunctionBody ValidateExpr NumericLiteral
+ OrderingExpr TypeswitchExpr LetClause LetTail
+ Constructor DirectConstructor DirElemConstructor
+ ComputedConstructor CompDocConstructor CompElemConstructor
+ CompTextConstructor CompCommentConstructor CompPIConstructor
+ DirPIConstructor CompAttrConstructor DirElemConstructorTail
+ AxisStep ForwardStep ReverseStep AbbrevForwardStep
+ CaseDefault CaseClause CaseTail CompAttributeName
+ FilteredAxisStep DirCommentConstructor CompPIName
+ DirAttributeValue AbbrevReverseStep CompNamespaceConstructor
+ CompElementName CompNameExpr SatisfiesClause Pattern PathPattern
+ PatternStep RelativePathPattern IdKeyPattern OptionalAssign
+ OptionalDefaultValue
+
+%type <orderSpec> OrderSpec
+%type <expressionList> ExpressionSequence FunctionArguments
+ DirElemContent AttrValueContent
+%type <orderSpecs> OrderSpecList OrderByClause MandatoryOrderByClause
+%type <functionArgument> Param
+%type <functionArguments> ParamList
+%type <itemType> KindTest ItemType AtomicType NodeTest NameTest WildCard NodeTestInAxisStep
+ ElementTest AttributeTest SchemaElementTest SchemaAttributeTest
+ TextTest CommentTest PITest DocumentTest AnyKindTest AnyAttributeTest
+%type <qName> ElementName QName VarName FunctionName PragmaName TypeName NCName
+ CaseVariable AttributeName OptionalTemplateName
+ TemplateName Mode OptionalMode
+%type <qNameVector> Modes OptionalModes
+%type <sequenceType> SequenceType SingleType TypeDeclaration
+%type <sval> URILiteral StringLiteral LexicalName
+%type <enums.Bool> IsInternal IsTunnel
+%type <enums.Double> OptionalPriority
+%type <enums.pathKind> MapOrSlash
+
+/* Operator Precendence
+ * See: http://www.w3.org/TR/xpath20/#parse-note-occurrence-indicators */
+%left STAR DIV
+%left PLUS MINUS
+
+%%
+
+/* Here, the grammar starts. In the brackets on the right you
+ * find the number of corresponding EBNF rule in the XQuery 1.0 specification. If it
+ * contains an X, it means the non-terminal has no counter part in the grammar, but
+ * exists for implementation purposes. */
+Module: VersionDecl LibraryModule /* [1] */
+| VersionDecl MainModule
+
+VersionDecl: /* empty */ /* [2] */
+| XQUERY VERSION StringLiteral Encoding Separator
+ {
+
+/* Suppress more compiler warnings about unused defines. */
+#if defined(YYNNTS) \
+ || defined(yyerrok) \
+ || defined(YYNSTATES) \
+ || defined(YYRHSLOC) \
+ || defined(YYRECOVERING) \
+ || defined(YYFAIL) \
+ || defined(YYERROR) \
+ || defined(YYNRULES) \
+ || defined(YYBACKUP) \
+ || defined(YYMAXDEPTH) \
+ || defined(yyclearin) \
+ || defined(YYERRCODE) \
+ || defined(YY_LOCATION_PRINT) \
+ || defined(YYLLOC_DEFAULT)
+#endif
+
+ if($3 != QLatin1String("1.0"))
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Version %1 is not supported. The supported "
+ "XQuery version is 1.0.")
+ .arg(formatData($3)),
+ ReportContext::XQST0031, &ryy);
+ }
+ }
+
+Encoding: /* empty */ /* [X] */
+| ENCODING StringLiteral
+ {
+ const QRegExp encNameRegExp(QLatin1String("[A-Za-z][A-Za-z0-9._\\-]*"));
+
+ if(!encNameRegExp.exactMatch($2))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The encoding %1 is invalid. "
+ "It must contain Latin characters only, "
+ "must not contain whitespace, and must match "
+ "the regular expression %2.")
+ .arg(formatKeyword((yyvsp[(2) - (2)].sval)),
+ formatExpression(encNameRegExp.pattern())),
+ ReportContext::XQST0087, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+MainModule: Prolog QueryBody /* [3] */
+ {
+ /* In XSL-T, we can have dangling variable references, so resolve them
+ * before we proceed with other steps, such as checking circularity. */
+ if(parseInfo->isXSLT())
+ {
+ typedef QHash<QXmlName, Expression::Ptr> Hash;
+ const Hash::const_iterator end(parseInfo->unresolvedVariableReferences.constEnd());
+
+ for(Hash::const_iterator it(parseInfo->unresolvedVariableReferences.constBegin()); it != end; ++it)
+ {
+ const Expression::Ptr body(resolveVariable(it.key(), @$, parseInfo, true)); // TODO source locations vaise
+ Q_ASSERT(body);
+ it.value()->as<UnresolvedVariableReference>()->bindTo(body);
+ }
+ }
+
+ /* The UserFunction callsites aren't bound yet, so bind them(if possible!). */
+ {
+ const UserFunctionCallsite::List::const_iterator cend(parseInfo->userFunctionCallsites.constEnd());
+ UserFunctionCallsite::List::const_iterator cit(parseInfo->userFunctionCallsites.constBegin());
+ for(; cit != cend; ++cit) /* For each callsite. */
+ {
+ const UserFunctionCallsite::Ptr callsite(*cit);
+ Q_ASSERT(callsite);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it) /* For each UserFunction. */
+ {
+ const FunctionSignature::Ptr sign((*it)->signature());
+ Q_ASSERT(sign);
+
+ if(callsite->isSignatureValid(sign))
+ {
+ callsite->setSource((*it),
+ parseInfo->allocateCacheSlots((*it)->argumentDeclarations().count()));
+ break;
+ }
+ }
+ if(it == end)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function with signature %1 is available")
+ .arg(formatFunction(callsite)),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+
+ /* Mark callsites in UserFunction bodies as recursive, if they are. */
+ {
+ const UserFunction::List::const_iterator fend(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator fit(parseInfo->userFunctions.constBegin());
+ for(; fit != fend; ++fit)
+ {
+ CallTargetDescription::List signList;
+ signList.append((*fit)->signature());
+ CallTargetDescription::checkCallsiteCircularity(signList, (*fit)->body());
+ }
+ }
+
+ /* Now, check all global variables for circularity. This is done
+ * backwards because global variables are only in scope below them,
+ * in XQuery. */
+ {
+ const VariableDeclaration::List::const_iterator start(parseInfo->declaredVariables.constBegin());
+ VariableDeclaration::List::const_iterator it(parseInfo->declaredVariables.constEnd());
+
+ while(it != start)
+ {
+ --it;
+ if((*it)->type != VariableDeclaration::ExpressionVariable && (*it)->type != VariableDeclaration::GlobalVariable)
+ continue; /* We want to ignore 'external' variables. */
+
+ FunctionSignature::List signList;
+ checkVariableCircularity(*it, (*it)->expression(), (*it)->type, signList, parseInfo);
+ ExpressionFactory::registerLastPath((*it)->expression());
+ parseInfo->finalizePushedVariable(1, false); /* Warn if it's unused. */
+ }
+ }
+
+ /* Generate code for doing initial template name calling. One problem
+ * is that we compilation in the initial template name, since we throw away the
+ * code if we don't have the requested template. */
+ if(parseInfo->languageAccent == QXmlQuery::XSLT20
+ && !parseInfo->initialTemplateName.isNull()
+ && parseInfo->namedTemplates.contains(parseInfo->initialTemplateName))
+ {
+ parseInfo->queryBody = create(new CallTemplate(parseInfo->initialTemplateName,
+ WithParam::Hash()),
+ @$, parseInfo);
+ parseInfo->templateCalls.append(parseInfo->queryBody);
+ /* We just discard the template body that XSLTTokenizer generated. */
+ }
+ else
+ parseInfo->queryBody = $2;
+ }
+
+LibraryModule: ModuleDecl Prolog /* [4] */
+
+ModuleDecl: MODULE NAMESPACE NCNAME G_EQ URILiteral Separator /* [5] */
+ {
+ // TODO add to namespace context
+ parseInfo->moduleNamespace = parseInfo->staticContext->namePool()->allocateNamespace($3);
+ }
+
+Prolog: /* Empty. */ /* [6] */
+/* First part. */
+| Prolog DefaultNamespaceDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog Setter
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A default namespace declaration must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog NamespaceDecl
+ {
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace declarations must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog Import
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasSecondPrologPart)
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Module imports must occur before function, "
+ "variable, and option declarations."), ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+| Prolog TemplateDecl
+
+/* Second part. */
+| Prolog VarDecl
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+| Prolog FunctionDecl
+ {
+ parseInfo->hasSecondPrologPart = true;
+ }
+| Prolog OptionDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->hasSecondPrologPart = true;
+ }
+
+/*
+ * declare template name theName
+ * {
+ * "expression"
+ * };
+ *
+ * or
+ *
+ * declare template name theName matches (pattern) mode modeName priority 123
+ * {
+ * "expression"
+ * };
+ *
+ */
+TemplateDecl: DECLARE TEMPLATE TemplateName
+ OptionalTemplateParameters
+ TypeDeclaration
+ EnclosedOptionalExpr Separator /* [X] */
+ {
+ Template::Ptr temp(create(new Template(parseInfo->currentImportPrecedence, $5), @$, parseInfo));
+
+ registerNamedTemplate($3, typeCheckTemplateBody($6, $5, parseInfo),
+ parseInfo, @1, temp);
+ temp->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+ }
+| DECLARE TEMPLATE OptionalTemplateName
+ MATCHES LPAREN
+ {
+ parseInfo->isParsingPattern = true;
+ }
+ Pattern
+ {
+ parseInfo->isParsingPattern = false;
+ }
+ RPAREN
+ OptionalModes
+ OptionalPriority
+ OptionalTemplateParameters
+ TypeDeclaration
+ EnclosedOptionalExpr Separator /* [X] */
+ {
+ /* In this grammar branch, we're guaranteed to be a template rule, but
+ * may also be a named template. */
+
+ const ImportPrecedence ip = parseInfo->isFirstTemplate() ? 0 : parseInfo->currentImportPrecedence;
+ Expression::Ptr pattern($7);
+ const TemplatePattern::ID templateID = parseInfo->allocateTemplateID();
+
+ Template::Ptr templ(create(new Template(ip, $13), @$, parseInfo));
+ templ->body = typeCheckTemplateBody($14, $13, parseInfo);
+ templ->templateParameters = parseInfo->templateParameters;
+ parseInfo->templateParametersHandled();
+
+ TemplatePattern::Vector ourPatterns;
+ /* We do it as per 6.4 Conflict Resolution for Template Rules:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives." */
+ while(pattern->is(Expression::IDCombineNodes))
+ {
+ const Expression::List operands(pattern->operands());
+ pattern = operands.first();
+
+ loadPattern(operands.at(1), ourPatterns, templateID, $11, templ);
+ }
+
+ loadPattern(pattern, ourPatterns, templateID, $11, templ);
+
+ if(!$3.isNull())
+ registerNamedTemplate($3, $14, parseInfo, @1, templ);
+
+ /* Now, let's add it to all the relevant templates. */
+ for(int i = 0; i < $10.count(); ++i) /* For each mode. */
+ {
+ const QXmlName &modeName = $10.at(i);
+
+ if(modeName == QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all) && $10.count() > 1)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The keyword %1 cannot occur with any other mode name.")
+ .arg(formatKeyword(QLatin1String("#all"))),
+ ReportContext::XTSE0530,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ /* For each pattern the template use. */
+ const TemplateMode::Ptr mode(parseInfo->modeFor(modeName));
+ for(int t = 0; t < ourPatterns.count(); ++t)
+ mode->templatePatterns.append(ourPatterns.at(t));
+ }
+ }
+
+OptionalPriority: /* Empty. */ /* [X] */
+ {
+ $$ = std::numeric_limits<xsDouble>::quiet_NaN();
+ }
+
+| PRIORITY StringLiteral
+ {
+ const AtomicValue::Ptr val(Decimal::fromLexical($2));
+ if(val->hasError())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The value of attribute %1 must be of type %2, which %3 isn't.")
+ .arg(formatKeyword(QLatin1String("priority")),
+ formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsDecimal),
+ formatData($2)),
+ ReportContext::XTSE0530,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ $$ = val->as<Numeric>()->toDouble();
+ }
+
+OptionalTemplateName: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName();
+ }
+| TemplateName
+
+TemplateName: NAME ElementName
+ {
+ $$ = $2;
+ }
+
+Setter: BoundarySpaceDecl /* [7] */
+| DefaultCollationDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| BaseURIDecl
+| ConstructionDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| OrderingModeDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| EmptyOrderDecl
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| CopyNamespacesDecl
+
+Import: SchemaImport /* [8] */
+| ModuleImport
+
+Separator: SEMI_COLON /* [9] */
+
+NamespaceDecl: DECLARE NAMESPACE NCNAME G_EQ URILiteral IsInternal Separator /* [10] */
+ {
+ if(!$6)
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+
+ if($3 == QLatin1String("xmlns"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to redeclare prefix %1.")
+ .arg(formatKeyword(QLatin1String("xmlns"))),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+ else if ($5 == CommonNamespaces::XML || $3 == QLatin1String("xml"))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The prefix %1 can not be bound. By default, it is already bound "
+ "to the namespace %2.")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(CommonNamespaces::XML)),
+ ReportContext::XQST0070,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else if(parseInfo->declaredPrefixes.contains($3))
+ {
+ /* This includes the case where the user has bound a default prefix(such
+ * as 'local') and now tries to do it again. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 is already declared in the prolog.")
+ .arg(formatKeyword($3)),
+ ReportContext::XQST0033, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->declaredPrefixes.append($3);
+
+ if($5.isEmpty())
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(StandardNamespaces::UndeclarePrefix,
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix($3)));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(parseInfo->staticContext->namePool()->allocateBinding($3, $5));
+ }
+ }
+ }
+
+BoundarySpaceDecl: DECLARE BOUNDARY_SPACE BoundarySpacePolicy Separator /* [11] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::BoundarySpaceDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare boundary-space"),
+ ReportContext::XQST0068, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setBoundarySpacePolicy($3);
+ parseInfo->registerDeclaration(ParserContext::BoundarySpaceDecl);
+ }
+ }
+
+BoundarySpacePolicy: STRIP /* [X] */
+ {
+ $$ = StaticContext::BSPStrip;
+ }
+
+| PRESERVE
+ {
+ $$ = StaticContext::BSPPreserve;
+ }
+
+DefaultNamespaceDecl: DeclareDefaultElementNamespace /* [12] */
+| DeclareDefaultFunctionNamespace
+
+DeclareDefaultElementNamespace: DECLARE DEFAULT ELEMENT NAMESPACE
+ URILiteral Separator /* [X] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultElementNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default element namespace"),
+ ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->namespaceBindings()->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5), StandardLocalNames::empty));
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultElementNamespace);
+ }
+ }
+
+DeclareDefaultFunctionNamespace: DECLARE DEFAULT FUNCTION NAMESPACE
+ URILiteral Separator /* [X] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DeclareDefaultFunctionNamespace))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default function namespace"),
+ ReportContext::XQST0066, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->setDefaultFunctionNamespace($5);
+ parseInfo->registerDeclaration(ParserContext::DeclareDefaultFunctionNamespace);
+ }
+ }
+
+OptionDecl: DECLARE OPTION ElementName StringLiteral Separator /* [13] */
+ {
+ if($3.prefix() == StandardPrefixes::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an option must have a prefix. "
+ "There is no default namespace for options."),
+ ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+OrderingModeDecl: DECLARE ORDERING OrderingMode Separator /* [14] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ if(parseInfo->hasDeclaration(ParserContext::OrderingModeDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0065, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::OrderingModeDecl);
+ parseInfo->staticContext->setOrderingMode($3);
+ }
+ }
+
+OrderingMode: ORDERED
+ {
+ $$ = StaticContext::Ordered;
+ }
+| UNORDERED
+ {
+ $$ = StaticContext::Unordered;
+ }
+
+EmptyOrderDecl: DECLARE DEFAULT ORDER OrderingEmptySequence Separator /* [15] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::EmptyOrderDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default order"),
+ ReportContext::XQST0069, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::EmptyOrderDecl);
+ parseInfo->staticContext->setOrderingEmptySequence($4);
+ }
+ }
+
+OrderingEmptySequence: EMPTY LEAST /* [X] */
+ {
+ $$ = StaticContext::Least;
+ }
+| EMPTY GREATEST
+ {
+ $$ = StaticContext::Greatest;
+ }
+
+CopyNamespacesDecl: DECLARE COPY_NAMESPACES PreserveMode COMMA
+ InheritMode Separator /* [16] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::CopyNamespacesDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare copy-namespaces"),
+ ReportContext::XQST0055, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::CopyNamespacesDecl);
+ }
+ }
+
+PreserveMode: PRESERVE /* [17] */
+ {
+ parseInfo->preserveNamespacesMode = true;
+ }
+
+| NO_PRESERVE
+ {
+ parseInfo->preserveNamespacesMode = false;
+ }
+
+InheritMode: INHERIT /* [18] */
+ {
+ parseInfo->inheritNamespacesMode = true;
+ }
+
+| NO_INHERIT
+ {
+ parseInfo->inheritNamespacesMode = false;
+ }
+
+DefaultCollationDecl: DECLARE DEFAULT COLLATION StringLiteral Separator /* [19] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::DefaultCollationDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare default collation"),
+ ReportContext::XQST0038, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ const QUrl coll(resolveAndCheckCollation<ReportContext::XQST0038>($4, parseInfo, @$));
+
+ parseInfo->registerDeclaration(ParserContext::DefaultCollationDecl);
+ parseInfo->staticContext->setDefaultCollation(coll);
+ }
+ }
+
+BaseURIDecl: DECLARE BASEURI IsInternal URILiteral Separator /* [20] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$, $3);
+ if(parseInfo->hasDeclaration(ParserContext::BaseURIDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare base-uri"),
+ ReportContext::XQST0032, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::BaseURIDecl);
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ QUrl toBeBase(AnyURI::toQUrl<ReportContext::XQST0046>($4, parseInfo->staticContext, &ryy));
+ /* Now we're guaranteed that base is a valid lexical representation, but it can still be relative. */
+
+ if(toBeBase.isRelative())
+ toBeBase = parseInfo->staticContext->baseURI().resolved(toBeBase);
+
+ parseInfo->staticContext->setBaseURI(toBeBase);
+ }
+ }
+
+SchemaImport: IMPORT SCHEMA SchemaPrefix URILiteral FileLocations Separator /* [21] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Import feature is not supported, "
+ "and therefore %1 declarations cannot occur.")
+ .arg(formatKeyword("import schema")),
+ ReportContext::XQST0009, fromYYLTYPE(@$, parseInfo));
+ }
+
+SchemaPrefix: /* empty */ /* [22] */
+| DEFAULT ELEMENT NAMESPACE
+| NAMESPACE NCNAME G_EQ
+
+ModuleImport: IMPORT MODULE ModuleNamespaceDecl URILiteral FileLocations Separator /* [23] */
+ {
+ if($4.isEmpty())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The target namespace of a %1 cannot be empty.")
+ .arg(formatKeyword("module import")),
+ ReportContext::XQST0088, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ {
+ /* This is temporary until we have implemented it. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The module import feature is not supported"),
+ ReportContext::XQST0016, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ModuleNamespaceDecl: /* empty */ /* [X] */
+| NAMESPACE NCNAME G_EQ
+
+FileLocations: /* empty */ /* [X] */
+| AT FileLocation
+
+FileLocation: URILiteral /* [X] */
+| FileLocation COMMA URILiteral
+
+VarDecl: DECLARE VARIABLE IsInternal DOLLAR VarName TypeDeclaration
+ VariableValue OptionalDefaultValue Separator /* [24] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
+ if(variableByName($5, parseInfo))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A variable by name %1 has already "
+ "been declared.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical($5))),
+ parseInfo->isXSLT() ? ReportContext::XTSE0630 : ReportContext::XQST0049,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ if($7) /* We got a value assigned. */
+ {
+ const Expression::Ptr checked
+ (TypeChecker::applyFunctionConversion($7, $6, parseInfo->staticContext,
+ $3 ? ReportContext::XTTE0570 : ReportContext::XPTY0004,
+ $3 ? TypeChecker::Options(TypeChecker::CheckFocus | TypeChecker::AutomaticallyConvert) : TypeChecker::CheckFocus));
+
+ pushVariable($5, $6, checked, VariableDeclaration::GlobalVariable, @$, parseInfo);
+ parseInfo->declaredVariables.append(parseInfo->variables.last());
+ }
+ else /* We got an 'external' declaration. */
+ {
+ const SequenceType::Ptr varType(parseInfo->staticContext->
+ externalVariableLoader()->announceExternalVariable($5, $6));
+
+ if(varType)
+ {
+ /* We push the declaration such that we can see name clashes and so on, but we don't use it for tying
+ * any references to it. */
+ pushVariable($5, varType, Expression::Ptr(), VariableDeclaration::ExternalVariable, @$, parseInfo);
+ }
+ else if($8)
+ {
+ /* Ok, the xsl:param got a default value, we make it
+ * available as a regular variable declaration. */
+ // TODO turn into checked
+ pushVariable($5, $6, $8, VariableDeclaration::GlobalVariable, @$, parseInfo);
+ // TODO ensure that duplicates are trapped.
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No value is available for the external "
+ "variable by name %1.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ parseInfo->isXSLT() ? ReportContext::XTDE0050 : ReportContext::XPDY0002,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+ }
+
+VariableValue: EXTERNAL /* [X] */
+ {
+ $$.reset();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+OptionalDefaultValue: /* Empty. */ /* [X] */
+ {
+ $$.reset();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+ConstructionDecl: DECLARE CONSTRUCTION ConstructionMode Separator /* [25] */
+ {
+ if(parseInfo->hasDeclaration(ParserContext::ConstructionDecl))
+ {
+ parseInfo->staticContext->error(prologMessage("declare ordering"),
+ ReportContext::XQST0067, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->registerDeclaration(ParserContext::ConstructionDecl);
+ parseInfo->staticContext->setConstructionMode($3);
+ }
+ }
+
+ConstructionMode: STRIP /* [X] */
+ {
+ $$ = StaticContext::CMStrip;
+ }
+| PRESERVE
+ {
+ $$ = StaticContext::CMPreserve;
+ }
+
+FunctionDecl: DECLARE FUNCTION IsInternal FunctionName LPAREN ParamList RPAREN
+ {
+ $<enums.slot>$ = parseInfo->currentExpressionSlot() - $6.count();
+ }
+ TypeDeclaration FunctionBody Separator /* [26] */
+ {
+ if(!$3)
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $3);
+
+ /* If FunctionBody is null, it is 'external', otherwise the value is the body. */
+ const QXmlName::NamespaceCode ns($4.namespaceURI());
+
+ if(parseInfo->isXSLT() && !$4.hasPrefix())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A stylesheet function must have a prefixed name."),
+ ReportContext::XTSE0740,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ if($10) /* We got a function body. */
+ {
+ if(ns == StandardNamespaces::empty)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace for a user defined function "
+ "cannot be empty (try the predefined "
+ "prefix %1 which exists for cases "
+ "like this)")
+ .arg(formatKeyword("local")),
+ ReportContext::XQST0060, fromYYLTYPE(@$, parseInfo));
+ }
+ else if(XPathHelper::isReservedNamespace(ns))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace %1 is reserved; therefore "
+ "user defined functions may not use it. "
+ "Try the predefined prefix %2, which "
+ "exists for these cases.")
+ .arg(formatURI(parseInfo->staticContext->namePool(), ns), formatKeyword("local")),
+ parseInfo->isXSLT() ? ReportContext::XTSE0080 : ReportContext::XQST0045,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ else if(parseInfo->moduleNamespace != StandardNamespaces::empty &&
+ ns != parseInfo->moduleNamespace)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr(
+ "The namespace of a user defined "
+ "function in a library module must be "
+ "equivalent to the module namespace. "
+ "In other words, it should be %1 instead "
+ "of %2")
+ .arg(formatURI(parseInfo->staticContext->namePool(), parseInfo->moduleNamespace),
+ formatURI(parseInfo->staticContext->namePool(), ns)),
+ ReportContext::XQST0048, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ /* Apply function conversion such that the body matches the declared
+ * return type. */
+ const Expression::Ptr checked(TypeChecker::applyFunctionConversion($10, $9,
+ parseInfo->staticContext,
+ ReportContext::XPTY0004,
+ TypeChecker::Options(TypeChecker::AutomaticallyConvert |
+ TypeChecker::CheckFocus |
+ TypeChecker::GeneratePromotion)));
+
+ const int argCount = $6.count();
+ const FunctionSignature::Ptr sign(new FunctionSignature($4 /* name */,
+ argCount /* minArgs */,
+ argCount /* maxArgs */,
+ $9 /* returnType */));
+ sign->setArguments($6);
+ const UserFunction::List::const_iterator end(parseInfo->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(parseInfo->userFunctions.constBegin());
+
+ for(; it != end; ++it)
+ {
+ if(*(*it)->signature() == *sign)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A function already exists with "
+ "the signature %1.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), sign)),
+ parseInfo->isXSLT() ? ReportContext::XTSE0770 : ReportContext::XQST0034, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ VariableDeclaration::List argDecls;
+
+ for(int i = 0; i < argCount; ++i)
+ argDecls.append(parseInfo->variables.at(i));
+
+ if($<enums.slot>8 > -1)
+ {
+ /* We have allocated slots, so now push them out of scope. */
+ parseInfo->finalizePushedVariable(argCount);
+ }
+
+ parseInfo->userFunctions.append(UserFunction::Ptr(new UserFunction(sign, checked, $<enums.slot>8, argDecls)));
+ }
+ }
+ else /* We got an 'external' declaration. */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No external functions are supported. "
+ "All supported functions can be used directly, "
+ "without first declaring them as external"),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ParamList: /* empty */ /* [27] */
+ {
+ $$ = FunctionArgument::List();
+ }
+| Param
+ {
+ FunctionArgument::List l;
+ l.append($1);
+ $$ = l;
+ }
+| ParamList COMMA Param
+ {
+ FunctionArgument::List::const_iterator it($1.constBegin());
+ const FunctionArgument::List::const_iterator end($1.constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name() == $3->name())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An argument by name %1 has already "
+ "been declared. Every argument name "
+ "must be unique.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3->name())),
+ ReportContext::XQST0039, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+ $1.append($3);
+ $$ = $1;
+ }
+
+Param: DOLLAR VarName TypeDeclaration /* [28] */
+ {
+ pushVariable($2, $3, Expression::Ptr(), VariableDeclaration::FunctionArgument, @$, parseInfo);
+ $$ = FunctionArgument::Ptr(new FunctionArgument($2, $3));
+ }
+
+FunctionBody: EXTERNAL /* [X] */
+ {
+ $$.reset();
+ }
+| EnclosedExpr
+
+EnclosedExpr: CURLY_LBRACE Expr CURLY_RBRACE /* [29] */
+ {
+ $$ = $2;
+ }
+
+QueryBody: Expr /* [30] */
+
+/**
+ * A pattern as found in for instance xsl:template/@match.
+ *
+ * @note When using this pattern, remember to set ParserContext::isParsingPattern.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#dt-pattern">XSL Transformations
+ * (XSLT) Version 2.0, 5.5.2 Syntax of Patterns</a>
+ */
+Pattern: PathPattern /* [XSLT20-1] */
+| Pattern BAR PathPattern
+ {
+ $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
+ }
+
+PathPattern: RelativePathPattern /* [XSLT20-2] */
+| SLASH
+ {
+ /* We write this into a node test. The spec says, 5.5.3 The Meaning of a Pattern:
+ * "Similarly, / matches a document node, and only a document node,
+ * because the result of the expression root(.)//(/) returns the root
+ * node of the tree containing the context node if and only if it is a
+ * document node." */
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisSelf, BuiltinTypes::document), @$, parseInfo);
+ }
+| SLASH RelativePathPattern
+ {
+ /* /axis::node-test
+ * =>
+ * axis::node-test[parent::document-node()]
+ *
+ * In practice it looks like this. $2 is:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep parent::element(b)
+ * AxisStep parent::element(a)
+ *
+ * and we want this:
+ *
+ * TruthPredicate
+ * AxisStep self::element(c)
+ * TruthPredicate
+ * AxisStep self::element(b)
+ * TruthPredicate
+ * AxisStep parent::element(a)
+ * AxisStep parent::document()
+ *
+ * So we want to rewrite the predicate deepest down into a
+ * another TruthPredicate containing the AxisStep.
+ *
+ * The simplest case where $2 is only an axis step is special. When $2 is:
+ *
+ * AxisStep self::element(a)
+ *
+ * we want:
+ *
+ * TruthPredicate
+ * AxisStep self::element(a)
+ * AxisStep parent::document()
+ */
+
+ /* First, find the target. */
+ Expression::Ptr target($2);
+
+ while(isPredicate(target->id()))
+ {
+ const Expression::Ptr candidate(target->operands().at(1));
+
+ if(isPredicate(candidate->id()))
+ target = candidate;
+ else
+ break; /* target is now the last predicate. */
+ }
+
+ if(target->is(Expression::IDAxisStep))
+ {
+ $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
+ }
+ else
+ {
+ const Expression::List targetOperands(target->operands());
+ Expression::List newOps;
+ newOps.append(targetOperands.at(0));
+
+ newOps.append(create(GenericPredicate::create(targetOperands.at(1),
+ create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::document), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo));
+
+ target->setOperands(newOps);
+ $$ = $2;
+ }
+ }
+| SLASHSLASH RelativePathPattern
+ {
+ /* //axis::node-test
+ * =>
+ * axis::node-test[parent::node()]
+ *
+ * Spec says: "//para matches any para element that has a parent node."
+ */
+ $$ = create(GenericPredicate::create($2, create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo),
+ parseInfo->staticContext, fromYYLTYPE(@1, parseInfo)), @1, parseInfo);
+ }
+| IdKeyPattern
+| IdKeyPattern SLASH RelativePathPattern
+ {
+ createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
+ }
+| IdKeyPattern SLASHSLASH RelativePathPattern
+ {
+ createIdPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
+ }
+
+IdKeyPattern: FunctionCallExpr
+ {
+ const Expression::List ands($1->operands());
+ const FunctionSignature::Ptr signature($1->as<FunctionCall>()->signature());
+ const QXmlName name(signature->name());
+ const QXmlName key(StandardNamespaces::fn, StandardLocalNames::key);
+ const QXmlName id(StandardNamespaces::fn, StandardLocalNames::id);
+
+ if(name == id)
+ {
+ const Expression::ID id = ands.first()->id();
+ if(!isVariableReference(id) && id != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("When function %1 is used for matching inside a pattern, "
+ "the argument must be a variable reference or a string literal.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else if(name == key)
+ {
+ if(ands.first()->id() != Expression::IDStringValue)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a string literal, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ const Expression::ID id2 = ands.at(1)->id();
+ if(!isVariableReference(id2) &&
+ id2 != Expression::IDStringValue &&
+ id2 != Expression::IDIntegerValue &&
+ id2 != Expression::IDBooleanValue &&
+ id2 != Expression::IDFloat)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, the first argument to function %1 "
+ "must be a literal or a variable reference, when used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(ands.count() == 3)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, function %1 cannot have a third argument.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ }
+ else
+ {
+ const FunctionSignature::Hash signs(parseInfo->staticContext->functionSignatures()->functionSignatures());
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, only function %1 "
+ "and %2, not %3, can be used for matching.")
+ .arg(formatFunction(parseInfo->staticContext->namePool(), signs.value(id)),
+ formatFunction(parseInfo->staticContext->namePool(), signs.value(key)),
+ formatFunction(parseInfo->staticContext->namePool(), signature)),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = $1;
+ }
+
+RelativePathPattern: PatternStep /* [XSLT20-3] */
+| RelativePathPattern SLASH PatternStep
+ {
+ $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisParent, @2, parseInfo);
+ }
+| RelativePathPattern SLASHSLASH PatternStep
+ {
+ $$ = createPatternPath($1, $3, QXmlNodeModelIndex::AxisAncestor, @2, parseInfo);
+ }
+
+PatternStep: FilteredAxisStep
+ {
+ const Expression::Ptr expr(findAxisStep($1));
+
+ const QXmlNodeModelIndex::Axis axis = expr->as<AxisStep>()->axis();
+ AxisStep *const axisStep = expr->as<AxisStep>();
+
+ /* Here we constrain the possible axes, and we rewrite the axes as according
+ * to 5.5.3 The Meaning of a Pattern.
+ *
+ * However, we also rewrite axis child and attribute to axis self. The
+ * reason for this is that if we don't, we will match the children of
+ * the context node, instead of the context node itself. The formal
+ * definition of a pattern, root(.)//EE is insensitive to context,
+ * while the way we implement pattern, "the other way of seeing it",
+ * e.g from right to left, are very much. */
+
+ if(axisStep->nodeTest() == BuiltinTypes::document
+ || axis == QXmlNodeModelIndex::AxisChild)
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ else if(axis == QXmlNodeModelIndex::AxisAttribute)
+ {
+ axisStep->setAxis(QXmlNodeModelIndex::AxisSelf);
+ /* Consider that the user write attribute::node(). This is
+ * semantically equivalent to attribute::attribute(), but since we have changed
+ * the axis to axis self, we also need to change the node test, such that we
+ * have self::attribute(). */
+ if(*axisStep->nodeTest() == *BuiltinTypes::node)
+ axisStep->setNodeTest(BuiltinTypes::attribute);
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("In an XSL-T pattern, axis %1 cannot be used, "
+ "only axis %2 or %3 can.")
+ .arg(formatKeyword(AxisStep::axisName(axis)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisChild)),
+ formatKeyword(AxisStep::axisName(QXmlNodeModelIndex::AxisAttribute))),
+ ReportContext::XPST0003,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = $1;
+ }
+
+Expr: ExprSingle /* [31] */
+| ExpressionSequence
+ {
+ $$ = create(new ExpressionSequence($1), @$, parseInfo);
+ }
+
+ExpressionSequence: ExprSingle COMMA ExprSingle /* [X] */
+ {
+ Expression::List l;
+ l.append($1);
+ l.append($3);
+ $$ = l;
+ }
+| ExpressionSequence COMMA ExprSingle
+ {
+ $1.append($3);
+ $$ = $1;
+ }
+
+ExprSingle: OrExpr /* [32] */
+| FLWORExpr
+| QuantifiedExpr
+| TypeswitchExpr
+| IfExpr
+| AVT LPAREN AttrValueContent RPAREN
+ {
+ $$ = createDirAttributeValue($3, parseInfo, @$);
+ }
+
+OptionalModes: /* Empty. */ /* [X] */
+ {
+ QVector<QXmlName> result;
+ result.append(QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default));
+ $$ = result;
+ }
+| MODE Modes
+ {
+ $$ = $2;
+ }
+
+OptionalMode: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ }
+| MODE Mode
+ {
+ $$ = $2;
+ }
+
+Modes: Mode
+ {
+ QVector<QXmlName> result;
+ result.append($1);
+ $$ = result;
+ }
+| Modes COMMA Mode
+ {
+ $1.append($3);
+ $$ = $1;
+ }
+
+Mode: QName /* [X] */
+ {
+ $$ = $1;
+ }
+| NCNAME
+ {
+ if($1 == QLatin1String("#current"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::current);
+ else if($1 == QLatin1String("#default"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::Default);
+ else if($1 == QLatin1String("#all"))
+ $$ = QXmlName(StandardNamespaces::InternalXSLT, StandardLocalNames::all);
+ else
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ if(!QXmlUtils::isNCName($1))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid template mode name.")
+ .arg(formatKeyword($1)),
+ ReportContext::XTSE0550,
+ fromYYLTYPE(@$, parseInfo));
+ }
+
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+ }
+
+
+FLWORExpr: ForClause /* [33] */
+| LetClause
+
+ForClause: FOR DOLLAR VarName TypeDeclaration
+ PositionalVar IN ExprSingle
+ {
+ /* We're pushing the range variable here, not the positional. */
+ $<expr>$ = pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
+ }
+ ForTail /* [34] */
+ {
+ Q_ASSERT($7);
+ Q_ASSERT($10);
+
+ /* We want the next last pushed variable, since we push the range variable after the
+ * positional variable. */
+ if($5 != -1 && parseInfo->variables.at(parseInfo->variables.count() -2)->name == $3)
+ {
+ /* Ok, a positional variable is used since its slot is not -1, and its name is equal
+ * to our range variable. This is an error. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of a variable bound in a for-expression must be different "
+ "from the positional variable. Hence, the two variables named %1 collide.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XQST0089,
+ fromYYLTYPE(@$, parseInfo));
+
+ }
+
+ const Expression::Ptr retBody(create(new ForClause($<enums.slot>9, $<expr>8, $10, $5), @$, parseInfo));
+ ReturnOrderBy *const rob = locateReturnClause($10);
+
+ if(rob)
+ $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), retBody, rob), @$, parseInfo);
+ else
+ $$ = retBody;
+
+ parseInfo->finalizePushedVariable();
+
+ if($5 != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+
+ForTail: COMMA DOLLAR VarName TypeDeclaration
+ PositionalVar IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $7, VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {
+ /* It is ok this appears after PositionalVar, because currentRangeSlot()
+ * uses a different "channel" than currentPositionSlot(), so they can't trash
+ * each other. */
+ $<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();
+ }
+ ForTail /* [X] */
+ {
+ $$ = create(new ForClause($<enums.slot>9, $<expr>7, $10, $5), @$, parseInfo);
+
+ parseInfo->finalizePushedVariable();
+
+ if($5 != -1) /* We also have a positional variable to remove from the scope. */
+ parseInfo->finalizePushedVariable();
+ }
+
+| WhereClause
+| ForClause
+| LetClause
+
+PositionalVar: /* empty */ /* [35] */
+ {
+ $$ = -1;
+ }
+
+| AT DOLLAR VarName
+ {
+ pushVariable($3, CommonSequenceTypes::ExactlyOneInteger, Expression::Ptr(),
+ VariableDeclaration::PositionalVariable, @$, parseInfo);
+ $$ = parseInfo->currentPositionSlot();
+ }
+
+LetClause: LET IsInternal DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
+ {
+ $<expr>$ = pushVariable($4, quantificationType($5), $7, VariableDeclaration::ExpressionVariable, @$, parseInfo);
+ }
+ LetTail /* [36] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ Q_ASSERT(parseInfo->variables.top()->name == $4);
+ $$ = create(new LetClause($<expr>8, $9, parseInfo->variables.top()), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+LetTail: COMMA DOLLAR VarName TypeDeclaration ASSIGN ExprSingle
+ { $<expr>$ = pushVariable($3, quantificationType($4), $6, VariableDeclaration::ExpressionVariable, @$, parseInfo);}
+ LetTail /* [X] */
+ {
+ Q_ASSERT(parseInfo->variables.top()->name == $3);
+ $$ = create(new LetClause($<expr>7, $8, parseInfo->variables.top()), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| WhereClause
+| ForClause
+| LetClause
+
+WhereClause: OrderByClause RETURN ExprSingle /* [37] */
+ {
+ if($1.isEmpty())
+ $$ = $3;
+ else
+ $$ = createReturnOrderBy($1, $3, parseInfo->orderStability.pop(), @$, parseInfo);
+ }
+
+| WHERE ExprSingle OrderByClause RETURN ExprSingle
+ {
+ if($3.isEmpty())
+ $$ = create(new IfThenClause($2, $5, create(new EmptySequence, @$, parseInfo)), @$, parseInfo);
+ else
+ $$ = create(new IfThenClause($2, createReturnOrderBy($3, $5, parseInfo->orderStability.pop(), @$, parseInfo),
+ create(new EmptySequence, @$, parseInfo)),
+ @$, parseInfo);
+ }
+
+OrderByClause: /* Empty. */ /* [38] */
+ {
+ $$ = OrderSpecTransfer::List();
+ }
+| MandatoryOrderByClause
+
+MandatoryOrderByClause: OrderByInputOrder OrderSpecList
+ {
+ $$ = $2;
+ }
+
+OrderSpecList: OrderSpecList COMMA OrderSpec /* [39] */
+ {
+ OrderSpecTransfer::List list;
+ list += $1;
+ list.append($3);
+ $$ = list;
+ }
+| OrderSpec
+ {
+ OrderSpecTransfer::List list;
+ list.append($1);
+ $$ = list;
+ }
+
+OrderSpec: ExprSingle DirectionModifier EmptynessModifier CollationModifier /* [40] */
+ {
+ $$ = OrderSpecTransfer($1, OrderBy::OrderSpec($2, $3));
+ }
+
+DirectionModifier: /* Empty. */ /* [X] */
+ {
+ /* Where does the specification state the default value is ascending?
+ *
+ * It is implicit, in the first enumerated list in 3.8.3 Order By and Return Clauses:
+ *
+ * "If T1 and T2 are two tuples in the tuple stream, and V1 and V2 are the first pair
+ * of values encountered when evaluating their orderspecs from left to right for
+ * which one value is greater-than the other (as defined above), then:
+ *
+ * 1. If V1 is greater-than V2: If the orderspec specifies descending,
+ * then T1 precedes T2 in the tuple stream; otherwise, T2 precedes T1 in the tuple stream.
+ * 2. If V2 is greater-than V1: If the orderspec specifies descending,
+ * then T2 precedes T1 in the tuple stream; otherwise, T1 precedes T2 in the tuple stream."
+ *
+ * which means that if you don't specify anything, or you
+ * specify ascending, you get the same result.
+ */
+ $$ = OrderBy::OrderSpec::Ascending;
+ }
+
+| ASCENDING
+ {
+ $$ = OrderBy::OrderSpec::Ascending;
+ }
+
+| DESCENDING
+ {
+ $$ = OrderBy::OrderSpec::Descending;
+ }
+
+EmptynessModifier: /* Empty. */ /* [X] */
+ {
+ $$ = parseInfo->staticContext->orderingEmptySequence();
+ }
+| OrderingEmptySequence
+
+CollationModifier: /* Empty. */ /* [X] */
+| COLLATION URILiteral
+ {
+ if(parseInfo->isXSLT())
+ resolveAndCheckCollation<ReportContext::XTDE1035>($2, parseInfo, @$);
+ else
+ resolveAndCheckCollation<ReportContext::XQST0076>($2, parseInfo, @$);
+ }
+| INTERNAL COLLATION ExprSingle
+ {
+ /* We do nothing. We don't use collations, and we have this non-terminal
+ * in order to accept expressions. */
+ }
+
+OrderByInputOrder: STABLE ORDER BY /* [X] */
+ {
+ parseInfo->orderStability.push(OrderBy::StableOrder);
+ }
+| ORDER BY
+ {
+ parseInfo->orderStability.push(OrderBy::UnstableOrder);
+ }
+
+QuantifiedExpr: SomeQuantificationExpr /* [42] */
+| EveryQuantificationExpr
+
+SomeQuantificationExpr: SOME DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ SomeQuantificationTail /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Some, $<expr>6, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+SomeQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ $<expr>$ = pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ SomeQuantificationTail /* [X] */
+ {
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Some, $<expr>7, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| SatisfiesClause
+
+EveryQuantificationExpr: EVERY DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ EveryQuantificationTail /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Every, $<expr>6, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+EveryQuantificationTail: COMMA DOLLAR VarName TypeDeclaration IN ExprSingle
+ {
+ $<expr>$ = pushVariable($3, quantificationType($4), $6,
+ VariableDeclaration::RangeVariable, @$, parseInfo);
+ }
+ {$<enums.slot>$ = parseInfo->staticContext->currentRangeSlot();}
+ EveryQuantificationTail /* [X] */
+ {
+ $$ = create(new QuantifiedExpression($<enums.slot>8,
+ QuantifiedExpression::Every, $<expr>7, $9), @$, parseInfo);
+ parseInfo->finalizePushedVariable();
+ }
+
+| SatisfiesClause
+
+SatisfiesClause: SATISFIES ExprSingle /* [X] */
+ {
+ $$ = $2;
+ }
+
+/*
+ * Typeswitches are re-written to a combination between @c if clauses, <tt>instance of</tt>, and
+ * @c let bindings. For example, the query:
+ *
+ * @code
+ * typeswitch(input)
+ * case element() return <!-- a comment -->
+ * case $i as attribute(name) return name($i)
+ * default return "Didn't match"
+ * @endcode
+ *
+ * becomes:
+ *
+ * @code
+ * if(input instance of element())
+ * then <!-- a comment -->
+ * else if(input instance of attribute(name))
+ * then let $i as attribute(name) := input return name($i)
+ * else "Didn't match"
+ * @endcode
+ */
+
+TypeswitchExpr: TYPESWITCH LPAREN Expr RPAREN
+ {
+ parseInfo->typeswitchSource.push($3);
+ }
+ CaseClause /* [43] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->typeswitchSource.pop();
+ $$ = $6;
+ }
+
+CaseClause: CASE CaseVariable SequenceType /* [44] */
+ {
+ if(!$2.isNull())
+ {
+ pushVariable($2, $3, parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
+ }
+ }
+ RETURN ExprSingle
+ {
+ /* The variable shouldn't be in-scope for other case branches. */
+ if(!$2.isNull())
+ parseInfo->finalizePushedVariable();
+ }
+ CaseTail
+ {
+ const Expression::Ptr instanceOf(create(new InstanceOf(parseInfo->typeswitchSource.top(), $3), @$, parseInfo));
+ $$ = create(new IfThenClause(instanceOf, $6, $8), @$, parseInfo);
+ }
+
+CaseTail: CaseClause /* [X] */
+| CaseDefault
+
+CaseVariable: /* Empty. */ /* [X] */
+ {
+ $$ = QXmlName();
+ }
+
+| DOLLAR ElementName AS
+ {
+ $$ = $2;
+ }
+
+CaseDefault: DEFAULT RETURN ExprSingle /* [X] */
+ {
+ $$ = $3;
+ }
+| DEFAULT DOLLAR ElementName
+ {
+ if(!$3.isNull())
+ {
+ pushVariable($3, parseInfo->typeswitchSource.top()->staticType(),
+ parseInfo->typeswitchSource.top(),
+ VariableDeclaration::ExpressionVariable, @$, parseInfo, false);
+ }
+ }
+ RETURN ExprSingle
+ {
+ if(!$3.isNull())
+ parseInfo->finalizePushedVariable();
+ $$ = $6;
+ }
+
+IfExpr: IF LPAREN Expr RPAREN THEN ExprSingle ELSE ExprSingle /* [45] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new IfThenClause($3, $6, $8), @$, parseInfo);
+ }
+
+OrExpr: AndExpr /* [46] */
+| OrExpr OR AndExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new OrExpression($1, $3), @$, parseInfo);
+ }
+
+AndExpr: ComparisonExpr /* [47] */
+| AndExpr AND ComparisonExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new AndExpression($1, $3), @$, parseInfo);
+ }
+
+ComparisonExpr: RangeExpr /* [48] */
+| ValueComp
+| GeneralComp
+| NodeComp
+
+RangeExpr: AdditiveExpr /* [49] */
+| AdditiveExpr TO AdditiveExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new RangeExpression($1, $3), @$, parseInfo);
+ }
+
+AdditiveExpr: MultiplicativeExpr /* [50] */
+| AdditiveExpr AdditiveOperator MultiplicativeExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
+ }
+
+AdditiveOperator: PLUS {$$ = AtomicMathematician::Add;} /* [X] */
+| MINUS {$$ = AtomicMathematician::Substract;}
+
+MultiplicativeExpr: UnionExpr /* [51] */
+| MultiplicativeExpr MultiplyOperator UnionExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new ArithmeticExpression($1, $2, $3), @$, parseInfo);
+ }
+
+MultiplyOperator: STAR {$$ = AtomicMathematician::Multiply;} /* [X] */
+| DIV {$$ = AtomicMathematician::Div;}
+| IDIV {$$ = AtomicMathematician::IDiv;}
+| MOD {$$ = AtomicMathematician::Mod;}
+
+UnionExpr: IntersectExceptExpr /* [52] */
+| UnionExpr UnionOperator IntersectExceptExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10
+ | QXmlQuery::XPath20
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector),
+ parseInfo, @$);
+ $$ = create(new CombineNodes($1, CombineNodes::Union, $3), @$, parseInfo);
+ }
+
+IntersectExceptExpr: InstanceOfExpr /* [53] */
+| IntersectExceptExpr IntersectOperator InstanceOfExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CombineNodes($1, $2, $3), @$, parseInfo);
+ }
+
+UnionOperator: UNION /* [X] */
+| BAR
+
+IntersectOperator: INTERSECT /* [X] */
+ {
+ $$ = CombineNodes::Intersect;
+ }
+| EXCEPT
+ {
+ $$ = CombineNodes::Except;
+ }
+
+InstanceOfExpr: TreatExpr /* [54] */
+| TreatExpr INSTANCE OF SequenceType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new InstanceOf($1,
+ SequenceType::Ptr($4)), @$, parseInfo);
+ }
+
+TreatExpr: CastableExpr /* [55] */
+| CastableExpr TREAT AS SequenceType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new TreatAs($1, $4), @$, parseInfo);
+ }
+
+CastableExpr: CastExpr /* [56] */
+| CastExpr CASTABLE AS SingleType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CastableAs($1, $4), @$, parseInfo);
+ }
+
+CastExpr: UnaryExpr /* [57] */
+| UnaryExpr CAST AS SingleType
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new CastAs($1, $4), @$, parseInfo);
+ }
+
+UnaryExpr: ValueExpr /* [58] */
+| UnaryOperator UnaryExpr
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new UnaryExpression($1, $2, parseInfo->staticContext), @$, parseInfo);
+ }
+
+UnaryOperator: PLUS /* [X] */
+ {
+ $$ = AtomicMathematician::Add;
+ }
+| MINUS
+ {
+ $$ = AtomicMathematician::Substract;
+ }
+
+ValueExpr: ValidateExpr /* [59] */
+| PathExpr
+| ExtensionExpr
+
+GeneralComp: RangeExpr GeneralComparisonOperator RangeExpr /* [60] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new GeneralComparison($1, $2, $3, parseInfo->isBackwardsCompat.top()), @$, parseInfo);
+ }
+
+GeneralComparisonOperator: G_EQ {$$ = AtomicComparator::OperatorEqual;} /* [X] */
+| G_NE {$$ = AtomicComparator::OperatorNotEqual;}
+| G_GE {$$ = AtomicComparator::OperatorGreaterOrEqual;}
+| G_GT {$$ = AtomicComparator::OperatorGreaterThan;}
+| G_LE {$$ = AtomicComparator::OperatorLessOrEqual;}
+| G_LT {$$ = AtomicComparator::OperatorLessThan;}
+
+ValueComp: RangeExpr ValueComparisonOperator RangeExpr /* [61] */
+ {
+ $$ = create(new ValueComparison($1, $2, $3), @$, parseInfo);
+ }
+
+ValueComparisonOperator: EQ {$$ = AtomicComparator::OperatorEqual;}
+| NE {$$ = AtomicComparator::OperatorNotEqual;}
+| GE {$$ = AtomicComparator::OperatorGreaterOrEqual;}
+| GT {$$ = AtomicComparator::OperatorGreaterThan;}
+| LE {$$ = AtomicComparator::OperatorLessOrEqual;}
+| LT {$$ = AtomicComparator::OperatorLessThan;}
+
+NodeComp: RangeExpr NodeOperator RangeExpr /* [62] */
+ {
+ $$ = create(new NodeComparison($1, $2, $3), @$, parseInfo);
+ }
+
+NodeOperator: IS {$$ = QXmlNodeModelIndex::Is;} /* [X] */
+| PRECEDES {$$ = QXmlNodeModelIndex::Precedes;}
+| FOLLOWS {$$ = QXmlNodeModelIndex::Follows;}
+
+ValidateExpr: ValidationMode EnclosedExpr /* [63] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The Schema Validation Feature is not supported. "
+ "Hence, %1-expressions may not be used.")
+ .arg(formatKeyword("validate")),
+ ReportContext::XQST0075, fromYYLTYPE(@$, parseInfo));
+ /*
+ $$ = Validate::create($2, $1, parseInfo->staticContext);
+ */
+ }
+
+/* "A validate expression may optionally specify a validation mode. The
+ default validation mode is strict." */
+ValidationMode: VALIDATE {$$ = Validate::Strict;} /* [64] */
+| VALIDATE STRICT {$$ = Validate::Strict;}
+| VALIDATE LAX {$$ = Validate::Lax;}
+
+ExtensionExpr: Pragmas EnclosedOptionalExpr /* [65] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ /* We don't support any pragmas, so we only do the
+ * necessary validation and use the fallback expression. */
+
+ if($2)
+ $$ = $2;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("None of the pragma expressions are supported. "
+ "Therefore, a fallback expression "
+ "must be present"),
+ ReportContext::XQST0079, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+EnclosedOptionalExpr: CURLY_LBRACE /* empty */ CURLY_RBRACE /* [X] */
+ {
+ $$.reset();
+ }
+| CURLY_LBRACE Expr CURLY_RBRACE
+ {
+ $$ = $2;
+ }
+
+Pragmas: Pragmas Pragma /* [X] */
+| Pragma
+
+Pragma: PRAGMA_START PragmaName PragmaContents PRAGMA_END /* [66] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+
+PragmaContents: /* empty */ /* [67] */
+| StringLiteral
+
+PathExpr: SLASH RelativePathExpr /* [68] */
+ {
+ /* This is "/step". That is, fn:root(self::node()) treat as document-node()/RelativePathExpr. */
+ $$ = create(new Path(createRootExpression(parseInfo, @$), $2), @$, parseInfo);
+ }
+
+| SLASHSLASH RelativePathExpr
+ {
+ $$ = createSlashSlashPath(createRootExpression(parseInfo, @$), $2, @$, parseInfo);
+ }
+| SLASH
+ {
+ /* This is "/". That is, fn:root(self::node()) treat as document-node(). */
+ $$ = createRootExpression(parseInfo, @$);
+ }
+
+| RelativePathExpr
+ /* This is "step", simply. We let bison generate "$$ = $1". */
+
+RelativePathExpr: StepExpr /* [69] */
+| RelativePathExpr MapOrSlash StepExpr
+ {
+ $$ = create(new Path($1, $3, $2), @$, parseInfo);
+ }
+| RelativePathExpr MapOrSlash SORT MandatoryOrderByClause RETURN StepExpr END_SORT
+ {
+ const Expression::Ptr orderBy(createReturnOrderBy($4, $6, parseInfo->orderStability.pop(), @$, parseInfo));
+
+ ReturnOrderBy *const rob = orderBy->as<ReturnOrderBy>();
+ const Expression::Ptr path(create(new Path($1, orderBy, $2), @$, parseInfo));
+
+ $$ = create(new OrderBy(rob->stability(), rob->orderSpecs(), path, rob), @$, parseInfo);
+ }
+| RelativePathExpr SLASHSLASH StepExpr
+ {
+ $$ = createSlashSlashPath($1, $3, @$, parseInfo);
+ }
+
+StepExpr: FilteredAxisStep /* [70] */
+ {
+ $$ = NodeSortExpression::wrapAround($1, parseInfo->staticContext);
+ }
+| FilterExpr
+| CURRENT EnclosedExpr
+ {
+ $$ = create(new CurrentItemStore($2), @$, parseInfo);
+ }
+| XSLT_VERSION
+ {
+ const xsDouble version = $1.toDouble();
+
+ parseInfo->isBackwardsCompat.push(version != 2);
+
+ $<enums.Double>$ = version;
+ }
+ EnclosedExpr
+ {
+ if($<enums.Double>2 < 2)
+ $$ = createCompatStore($3, @$, parseInfo);
+ else
+ $$ = $3;
+ }
+| BASEURI StringLiteral CURLY_LBRACE Expr CURLY_RBRACE /* [X] */
+{
+ allowedIn(QXmlQuery::XSLT20, parseInfo, @$);
+ Q_ASSERT(!$2.isEmpty());
+ $$ = create(new StaticBaseURIStore($2, $4), @$, parseInfo);
+}
+
+| DECLARE NAMESPACE NCNAME G_EQ STRING_LITERAL CURLY_LBRACE /* [X] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20), parseInfo, @$);
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ resolver->addBinding(QXmlName(parseInfo->staticContext->namePool()->allocateNamespace($5),
+ StandardLocalNames::empty,
+ parseInfo->staticContext->namePool()->allocatePrefix($3)));
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ }
+ Expr
+ CURLY_RBRACE
+ {
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ $$ = $8;
+ }
+| CALL_TEMPLATE ElementName LPAREN TemplateWithParameters RPAREN
+ {
+ $$ = create(new CallTemplate($2, parseInfo->templateWithParams), @$, parseInfo);
+ parseInfo->templateWithParametersHandled();
+ parseInfo->templateCalls.append($$);
+ }
+
+TemplateWithParameters:
+ {
+ parseInfo->startParsingWithParam();
+ }
+ TemplateParameters
+ {
+ parseInfo->endParsingWithParam();
+ }
+
+TemplateParameters: /* Empty. */ /* [X] */
+ {
+ }
+| TemplateParameter
+ {
+ }
+| TemplateParameters COMMA TemplateParameter
+ {
+ }
+
+OptionalTemplateParameters: /* Empty. */ /* [X] */
+ {
+ }
+| LPAREN TemplateParameters RPAREN
+ {
+ }
+
+TemplateParameter: IsTunnel DOLLAR VarName TypeDeclaration OptionalAssign
+ {
+ /* Note, this grammar rule is invoked for @c xsl:param @em and @c
+ * xsl:with-param. */
+ const bool isParsingWithParam = parseInfo->isParsingWithParam();
+
+ /**
+ * @c xsl:param doesn't make life easy:
+ *
+ * If it only has @c name, it's default value is an empty
+ * string(hence has type @c xs:string), but the value that
+ * (maybe) is supplied can be anything, typically a node.
+ *
+ * Therefore, for that very common case we can't rely on
+ * the Expression's type, but have to force it to item()*.
+ *
+ * So if we're supplied the type item()*, we pass a null
+ * SequenceType. TemplateParameterReference recognizes this
+ * and has item()* as its static type, regardless of if the
+ * expression has a more specific type.
+ */
+ SequenceType::Ptr type;
+
+ if(!$4->is(CommonSequenceTypes::ZeroOrMoreItems))
+ type = $4;
+
+ Expression::Ptr expr;
+
+ /* The default value is an empty sequence. */
+ if(!$5 && ((type && $4->cardinality().allowsEmpty())
+ || isParsingWithParam))
+ expr = create(new EmptySequence, @$, parseInfo);
+ else
+ expr = $5;
+
+ /* We ensure we have some type, so CallTemplate, Template and friends
+ * are happy. */
+ if(!isParsingWithParam && !type)
+ type = CommonSequenceTypes::ZeroOrMoreItems;
+
+ if($1)
+ /* TODO, handle tunnel parameters. */;
+ else
+ {
+ if((!isParsingWithParam && VariableDeclaration::contains(parseInfo->templateParameters, $3)) ||
+ (isParsingWithParam && parseInfo->templateWithParams.contains($3)))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Each name of a template parameter must be unique; %1 is duplicated.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ isParsingWithParam ? ReportContext::XTSE0670 : ReportContext::XTSE0580, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ if(isParsingWithParam)
+ parseInfo->templateWithParams[$3] = WithParam::Ptr(new WithParam($3, $4, expr));
+ else
+ {
+ Q_ASSERT(type);
+ pushVariable($3, type, expr, VariableDeclaration::TemplateParameter, @$, parseInfo);
+ parseInfo->templateParameters.append(parseInfo->variables.top());
+ }
+ }
+ }
+ }
+
+IsTunnel: /* Empty. */
+ {
+ $$ = false;
+ }
+| TUNNEL
+ {
+ $$ = true;
+ }
+
+OptionalAssign: /* Empty. */ /* [X] */
+ {
+ $$ = Expression::Ptr();
+ }
+| ASSIGN ExprSingle
+ {
+ $$ = $2;
+ }
+
+/**
+ * Controls whethers a path expression should sort its result. Used for
+ * implementing XSL-T's for-each.
+ */
+MapOrSlash: SLASH /* [X] */
+ {
+ $$ = Path::RegularPath;
+ }
+| MAP
+ {
+ $$ = Path::XSLTForEach;
+ }
+| FOR_APPLY_TEMPLATE
+ {
+ $$ = Path::ForApplyTemplate;
+ }
+
+FilteredAxisStep: AxisStep /* [X] */
+| FilteredAxisStep LBRACKET Expr RBRACKET
+ {
+ $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@$, parseInfo)), @$, parseInfo);
+ }
+
+AxisStep: ForwardStep /* [71] */
+| ReverseStep
+
+ForwardStep: Axis
+ {
+ if($1 == QXmlNodeModelIndex::AxisAttribute)
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ NodeTestInAxisStep /* [72] */
+ {
+ if($3)
+ {
+ /* A node test was explicitly specified. The un-abbreviated syntax was used. */
+ $$ = create(new AxisStep($1, $3), @$, parseInfo);
+ }
+ else
+ {
+ /* Quote from 3.2.1.1 Axes
+ *
+ * [Definition: Every axis has a principal node kind. If an axis
+ * can contain elements, then the principal node kind is element;
+ * otherwise, it is the kind of nodes that the axis can contain.] Thus:
+ * - For the attribute axis, the principal node kind is attribute.
+ * - For all other axes, the principal node kind is element. */
+
+ if($1 == QXmlNodeModelIndex::AxisAttribute)
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, BuiltinTypes::attribute), @$, parseInfo);
+ else
+ $$ = create(new AxisStep($1, BuiltinTypes::element), @$, parseInfo);
+ }
+
+ parseInfo->restoreNodeTestSource();
+ }
+| AbbrevForwardStep
+
+NodeTestInAxisStep: NodeTest
+| AnyAttributeTest
+
+Axis: AxisToken COLONCOLON /* [73] */
+ {
+ if($1 == QXmlNodeModelIndex::AxisNamespace)
+ {
+ /* We don't raise XPST0010 here because the namespace axis isn't an optional
+ * axis. It simply is not part of the XQuery grammar. */
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The %1-axis is unsupported in XQuery")
+ .arg(formatKeyword("namespace")),
+ ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ $$ = $1;
+
+ switch($1)
+ {
+ case QXmlNodeModelIndex::AxisAttribute:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ break;
+ }
+ case QXmlNodeModelIndex::AxisChild:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XmlSchema11IdentityConstraintField
+ | QXmlQuery::XmlSchema11IdentityConstraintSelector
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ break;
+ }
+ default:
+ {
+ allowedIn(QueryLanguages( QXmlQuery::XPath20
+ | QXmlQuery::XQuery10
+ | QXmlQuery::XSLT20),
+ parseInfo, @$);
+ }
+ }
+ }
+
+AxisToken: ANCESTOR_OR_SELF {$$ = QXmlNodeModelIndex::AxisAncestorOrSelf ;}
+| ANCESTOR {$$ = QXmlNodeModelIndex::AxisAncestor ;}
+| ATTRIBUTE {$$ = QXmlNodeModelIndex::AxisAttribute ;}
+| CHILD {$$ = QXmlNodeModelIndex::AxisChild ;}
+| DESCENDANT_OR_SELF {$$ = QXmlNodeModelIndex::AxisDescendantOrSelf;}
+| DESCENDANT {$$ = QXmlNodeModelIndex::AxisDescendant ;}
+| FOLLOWING {$$ = QXmlNodeModelIndex::AxisFollowing ;}
+| PRECEDING {$$ = QXmlNodeModelIndex::AxisPreceding ;}
+| FOLLOWING_SIBLING {$$ = QXmlNodeModelIndex::AxisFollowingSibling;}
+| PRECEDING_SIBLING {$$ = QXmlNodeModelIndex::AxisPrecedingSibling;}
+| PARENT {$$ = QXmlNodeModelIndex::AxisParent ;}
+| SELF {$$ = QXmlNodeModelIndex::AxisSelf ;}
+
+AbbrevForwardStep: AT_SIGN
+ {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ NodeTest /* [72] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XSLT20 | QXmlQuery::XmlSchema11IdentityConstraintField), parseInfo, @$);
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $3), @$, parseInfo);
+
+ parseInfo->restoreNodeTestSource();
+ }
+| NodeTest
+ {
+ ItemType::Ptr nodeTest;
+
+ if(parseInfo->isParsingPattern && *$1 == *BuiltinTypes::node)
+ nodeTest = BuiltinTypes::xsltNodeTest;
+ else
+ nodeTest = $1;
+
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisChild, nodeTest), @$, parseInfo);
+ }
+| AnyAttributeTest
+ {
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisAttribute, $1), @$, parseInfo);
+ }
+
+ReverseStep: AbbrevReverseStep /* [75] */
+
+AbbrevReverseStep: DOTDOT /* [77] */
+ {
+ $$ = create(new AxisStep(QXmlNodeModelIndex::AxisParent, BuiltinTypes::node), @$, parseInfo);
+ }
+
+NodeTest: NameTest /* [78] */
+| KindTest
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+
+NameTest: ElementName /* [79] */
+ {
+ $$ = QNameTest::create(parseInfo->nodeTestSource, $1);
+ }
+| WildCard
+
+WildCard: STAR /* [80] */
+ {
+ $$ = parseInfo->nodeTestSource;
+ }
+| ANY_LOCAL_NAME
+ {
+ const NamePool::Ptr np(parseInfo->staticContext->namePool());
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const QXmlName::NamespaceCode ns(QNameConstructor::namespaceForPrefix(np->allocatePrefix($1), parseInfo->staticContext, &ryy));
+
+ $$ = NamespaceNameTest::create(parseInfo->nodeTestSource, ns);
+ }
+| ANY_PREFIX
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ const QXmlName::LocalNameCode c = parseInfo->staticContext->namePool()->allocateLocalName($1);
+ $$ = LocalNameTest::create(parseInfo->nodeTestSource, c);
+ }
+
+FilterExpr: PrimaryExpr /* [81] */
+| FilterExpr LBRACKET Expr RBRACKET
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(GenericPredicate::create($1, $3, parseInfo->staticContext, fromYYLTYPE(@4, parseInfo)), @$, parseInfo);
+ }
+
+PrimaryExpr: Literal /* [84] */
+| VarRef
+| ParenthesizedExpr
+| ContextItemExpr
+| FunctionCallExpr
+| OrderingExpr
+| Constructor
+| APPLY_TEMPLATE OptionalMode LPAREN TemplateWithParameters RPAREN
+ {
+ $$ = create(new ApplyTemplate(parseInfo->modeFor($2),
+ parseInfo->templateWithParams,
+ parseInfo->modeFor(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::Default))),
+ @1, parseInfo);
+ parseInfo->templateWithParametersHandled();
+ }
+
+Literal: NumericLiteral /* [85] */
+| StringLiteral
+ {
+ $$ = create(new Literal(AtomicString::fromValue($1)), @$, parseInfo);
+ }
+
+NumericLiteral: XPATH2_NUMBER /* [86] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = createNumericLiteral<Double>($1, @$, parseInfo);
+ }
+| NUMBER
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = createNumericLiteral<Numeric>($1, @$, parseInfo);
+ }
+
+VarRef: DOLLAR VarName /* [87] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = resolveVariable($2, @$, parseInfo, false);
+ }
+
+VarName: NCNAME /* [88] */
+ {
+ /* See: http://www.w3.org/TR/xpath20/#id-variables */
+ $$ = parseInfo->staticContext->namePool()->allocateQName(QString(), $1);
+ }
+| QName
+ {
+ $$ = $1;
+ }
+
+ParenthesizedExpr: LPAREN Expr RPAREN /* [89] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = $2;
+ }
+| LPAREN RPAREN
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ $$ = create(new EmptySequence, @$, parseInfo);
+ }
+
+ContextItemExpr: DOT /* [90] */
+ {
+ $$ = create(new ContextItem(), @$, parseInfo);
+ }
+
+OrderingExpr: OrderingMode EnclosedExpr /* [X] */
+ {
+ $$ = $2;
+ }
+
+FunctionCallExpr: FunctionName LPAREN FunctionArguments RPAREN /* [93] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ if(XPathHelper::isReservedNamespace($1.namespaceURI()) || $1.namespaceURI() == StandardNamespaces::InternalXSLT)
+ { /* We got a call to a builtin function. */
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const Expression::Ptr
+ func(parseInfo->staticContext->
+ functionSignatures()->createFunctionCall($1, $3, parseInfo->staticContext, &ryy));
+
+ if(func)
+ $$ = create(func, @$, parseInfo);
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("No function by name %1 is available.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)),
+ ReportContext::XPST0017, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else /* It's a call to a function created with 'declare function'.*/
+ {
+ $$ = create(new UserFunctionCallsite($1, $3.count()), @$, parseInfo);
+
+ $$->setOperands($3);
+ parseInfo->userFunctionCallsites.append($$);
+ }
+ }
+
+FunctionArguments: /* empty */ /* [X] */
+ {
+ $$ = Expression::List();
+ }
+
+| ExprSingle
+ {
+ Expression::List list;
+ list.append($1);
+ $$ = list;
+ }
+
+| ExpressionSequence
+
+Constructor: DirectConstructor /* [94] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$);
+ }
+| ComputedConstructor
+/* The reason we cannot call alloweIn() as the action for ComputedConstructor,
+ * is that we use the computed constructors for XSL-T, and therefore generate
+ * INTERNAL tokens. */
+
+DirectConstructor: DirElemConstructor /* [95] */
+| DirCommentConstructor
+| DirPIConstructor
+
+/*
+ * Direct attribute constructors can contain embedded expressions, and for those namespace bindings
+ * on the same element needs to be in scope. For example:
+ *
+ * @code
+ * <element attribute="{prefix:nameTest}" xmlns:prefix="http://example.com/"/>
+ * @endcode
+ *
+ * Patternist is designed to do all name resolution at parse time so the subsequent code only has to
+ * deal with expanded QNames(which the QName class represents), and this presents a problem since
+ * the parser haven't even encountered the @c xmlns:prefix when resolving @c prefix in the name test.
+ *
+ * This is solved as follows:
+ *
+ * <ol>
+ * <li>Just before starting parsing the attributes, we call Tokenizer::commenceScanOnly().
+ * This switches the tokenizer to not tokenize embedded expressions in attributes,
+ * but to return them as strings, token type STRING_LITERAL.</li>
+ * <li>We parse all the attributes, and iterates over them, only caring about
+ * namespace bindings, and validates and adds them to the context.</li>
+ * <li>We call Tokenizer::resumeTokenizationFrom() from the previous position
+ * returned from Tokenizer::commenceScanOnly() and parses the attributes once more,
+ * but this time with tokenization of embedded expressions. Since we this time
+ * have the namespace bindings in place, everything resolves.</li>
+ * </ol>
+ *
+ * Saxon does this in a similar way. Study net.sf.saxon.expr.QueryParser::parseDirectElementConstructor().
+ *
+ * @see XQueryTokenizer::attributeAsRaw()
+ */
+DirElemConstructor: G_LT
+ LexicalName
+ {
+ $<enums.tokenizerPosition>$ = parseInfo->tokenizer->commenceScanOnly();
+ parseInfo->scanOnlyStack.push(true);
+ }
+
+ /* This list contains name/string pairs. No embedded
+ * expressions has been parsed. */
+ DirAttributeList
+
+ {
+ ++parseInfo->elementConstructorDepth;
+ Expression::List constructors;
+
+ parseInfo->resolvers.push(parseInfo->staticContext->namespaceBindings());
+
+ /* Fix up attributes and namespace declarations. */
+ const NamespaceResolver::Ptr resolver(new DelegatingNamespaceResolver(parseInfo->staticContext->namespaceBindings()));
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = $4.size();
+ QSet<QXmlName::PrefixCode> usedDeclarations;
+
+ /* Whether xmlns="" has been encountered. */
+ bool hasDefaultDeclaration = false;
+
+ /* For each attribute & namespace declaration, do: */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName($4.at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+
+ /* This can seem a bit weird. However, this name is ending up in a QXmlName
+ * which consider its prefix a... prefix. So, a namespace binding name can in some cases
+ * be a local name, but that's just as the initial syntactical construct. */
+ const QXmlName::LocalNameCode localName = namePool->allocatePrefix(strLocalName);
+
+ /* Not that localName is "foo" in "xmlns:foo" and that prefix is "xmlns". */
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardPrefixes::xmlns))
+ {
+ if(localName == StandardPrefixes::xmlns)
+ hasDefaultDeclaration = true;
+
+ /* We have a namespace declaration. */
+
+ const Expression::Ptr nsExpr($4.at(i).second);
+
+ const QString strNamespace(nsExpr->is(Expression::IDEmptySequence) ? QString() : nsExpr->as<Literal>()->item().stringValue());
+
+ const QXmlName::NamespaceCode ns = namePool->allocateNamespace(strNamespace);
+
+ if(ns == StandardNamespaces::empty)
+ {
+ if(localName != StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI cannot be the empty string when binding to a prefix, %1.")
+ .arg(formatURI(strPrefix)),
+ ReportContext::XQST0085, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ else if(!AnyURI::isValid(strNamespace))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an invalid namespace URI.").arg(formatURI(strNamespace)),
+ ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(prefix == StandardPrefixes::xmlns && localName == StandardPrefixes::xmlns)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("It is not possible to bind to the prefix %1")
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(ns == StandardNamespaces::xml && localName != StandardPrefixes::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Namespace %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml)))
+ .arg(formatKeyword("xml")),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if(localName == StandardPrefixes::xml && ns != StandardNamespaces::xml)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Prefix %1 can only be bound to %2 (and it is, in either case, pre-declared).")
+ .arg(formatKeyword("xml"))
+ .arg(formatURI(namePool->stringForNamespace(StandardNamespaces::xml))),
+ ReportContext::XQST0070, fromYYLTYPE(@$, parseInfo));
+ }
+
+ QXmlName nb;
+
+ if(localName == StandardPrefixes::xmlns)
+ nb = QXmlName(ns, StandardLocalNames::empty);
+ else
+ nb = QXmlName(ns, StandardLocalNames::empty, localName);
+
+ if(usedDeclarations.contains(nb.prefix()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("Two namespace declaration attributes have the same name: %1.")
+ .arg(formatKeyword(namePool->stringForPrefix(nb.prefix()))),
+ ReportContext::XQST0071, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ usedDeclarations.insert(nb.prefix());
+
+ /* If the user has bound the XML namespace correctly, we in either
+ * case don't want to output it.
+ *
+ * We only have to check the namespace parts since the above checks has ensured
+ * consistency in the prefix parts. */
+ if(ns != StandardNamespaces::xml)
+ {
+ /* We don't want default namespace declarations when the
+ * default namespace already is empty. */
+ if(!(ns == StandardNamespaces::empty &&
+ localName == StandardNamespaces::xmlns &&
+ resolver->lookupNamespaceURI(StandardPrefixes::empty) == StandardNamespaces::empty))
+ {
+ constructors.append(create(new NamespaceConstructor(nb), @$, parseInfo));
+ resolver->addBinding(nb);
+ }
+ }
+ }
+ }
+
+ if(parseInfo->elementConstructorDepth == 1 && !hasDefaultDeclaration)
+ {
+ /* TODO But mostly this isn't needed, since the default element
+ * namespace is empty? How does this at all work? */
+ const QXmlName def(resolver->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ constructors.append(create(new NamespaceConstructor(def), @$, parseInfo));
+ }
+
+ parseInfo->staticContext->setNamespaceBindings(resolver);
+ $<expressionList>$ = constructors;
+
+ /* Resolve the name of the element, now that the namespace attributes are read. */
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ const QXmlName ele = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($2, parseInfo->staticContext, resolver, &ryy);
+ parseInfo->tagStack.push(ele);
+ }
+
+ parseInfo->tokenizer->resumeTokenizationFrom($<enums.tokenizerPosition>3);
+ }
+ POSITION_SET
+ DirAttributeList
+ DirElemConstructorTail /* [96] */
+ {
+ /* We add the content constructor after the attribute constructors. This might result
+ * in nested ExpressionSequences, but it will be optimized away later on. */
+
+ Expression::List attributes($<expressionList>5);
+ const NamePool::Ptr namePool(parseInfo->staticContext->namePool());
+ const int len = $7.size();
+ QSet<QXmlName> declaredAttributes;
+ declaredAttributes.reserve(len);
+
+ /* For each namespace, resolve its name(now that we have resolved the namespace declarations) and
+ * turn it into an attribute constructor. */
+ for(int i = 0; i < len; ++i)
+ {
+ QString strLocalName;
+ QString strPrefix;
+
+ XPathHelper::splitQName($7.at(i).first, strPrefix, strLocalName);
+ const QXmlName::PrefixCode prefix = namePool->allocatePrefix(strPrefix);
+ const QXmlName::LocalNameCode localName = namePool->allocateLocalName(strLocalName);
+
+ if(prefix == StandardPrefixes::xmlns ||
+ (prefix == StandardPrefixes::empty && localName == StandardLocalNames::xmlns))
+ {
+ const Expression::ID id = $7.at(i).second->id();
+
+ if(id == Expression::IDStringValue || id == Expression::IDEmptySequence)
+ {
+ /* It's a namespace declaration, and we've already handled those above. */
+ continue;
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The namespace URI must be a constant and cannot "
+ "use enclosed expressions."),
+ ReportContext::XQST0022, fromYYLTYPE(@$, parseInfo));
+ }
+
+ }
+ else
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+ const QXmlName att = QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($7.at(i).first, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(),
+ &ryy, true);
+ if(declaredAttributes.contains(att))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("An attribute by name %1 has already appeared on this element.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), att)),
+ ReportContext::XQST0040, fromYYLTYPE(@$, parseInfo));
+
+ }
+ else
+ declaredAttributes.insert(att);
+
+ /* wrapLiteral() needs the SourceLocationReflection of the AttributeConstructor, but
+ * it's unknown inside the arguments to its constructor. Hence we have to do this workaround of setting
+ * it twice.
+ *
+ * The AttributeConstructor's arguments are just dummies. */
+ const Expression::Ptr ctor(create(new AttributeConstructor($7.at(i).second, $7.at(i).second), @$, parseInfo));
+
+ Expression::List ops;
+ ops.append(wrapLiteral(toItem(QNameValue::fromValue(namePool, att)), parseInfo->staticContext, ctor.data()));
+ ops.append($7.at(i).second);
+ ctor->setOperands(ops);
+
+ attributes.append(ctor);
+ }
+ }
+
+ Expression::Ptr contentOp;
+
+ if(attributes.isEmpty())
+ contentOp = $8;
+ else
+ {
+ attributes.append($8);
+ contentOp = create(new ExpressionSequence(attributes), @$, parseInfo);
+ }
+
+ const Expression::Ptr name(create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), parseInfo->tagStack.top()))), @$, parseInfo));
+ $$ = create(new ElementConstructor(name, contentOp, parseInfo->isXSLT()), @$, parseInfo);
+
+ /* Restore the old context. We don't want the namespaces
+ * to be in-scope for expressions appearing after the
+ * element they appeared on. */
+ parseInfo->staticContext->setNamespaceBindings(parseInfo->resolvers.pop());
+ parseInfo->tagStack.pop();
+
+ --parseInfo->elementConstructorDepth;
+ }
+
+DirElemConstructorTail: QUICK_TAG_END
+ {
+ $$ = create(new EmptySequence(), @$, parseInfo);
+ }
+| G_GT DirElemContent BEGIN_END_TAG ElementName G_GT
+ {
+ if(!$4.isLexicallyEqual(parseInfo->tagStack.top()))
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("A direct element constructor is not "
+ "well-formed. %1 is ended with %2.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool()->toLexical(parseInfo->tagStack.top())),
+ formatKeyword(parseInfo->staticContext->namePool()->toLexical($4))),
+ ReportContext::XPST0003, fromYYLTYPE(@$, parseInfo));
+ }
+
+ if($2.isEmpty())
+ $$ = create(new EmptySequence(), @$, parseInfo);
+ else if($2.size() == 1)
+ $$ = $2.first();
+ else
+ $$ = create(new ExpressionSequence($2), @$, parseInfo);
+ }
+
+DirAttributeList: /* empty */ /* [97] */
+ {
+ $$ = AttributeHolderVector();
+ }
+| DirAttributeList Attribute
+ {
+ $1.append($2);
+ $$ = $1;
+ }
+
+Attribute: LexicalName G_EQ DirAttributeValue /* [X] */
+ {
+ $$ = qMakePair($1, $3);
+ }
+
+DirAttributeValue: QUOTE AttrValueContent QUOTE /* [98] */
+ {
+ $$ = createDirAttributeValue($2, parseInfo, @$);
+ }
+
+| APOS AttrValueContent APOS
+ {
+ $$ = createDirAttributeValue($2, parseInfo, @$);
+ }
+
+AttrValueContent: /* Empty. */ /* [X] */
+ {
+ $$ = Expression::List();
+ }
+| EnclosedExpr AttrValueContent
+ {
+ Expression::Ptr content($1);
+
+ if(parseInfo->isBackwardsCompat.top())
+ content = create(GenericPredicate::createFirstItem(content), @$, parseInfo);
+
+ $2.prepend(createSimpleContent(content, @$, parseInfo));
+ $$ = $2;
+ }
+| StringLiteral AttrValueContent
+ {
+ $2.prepend(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo));
+ $$ = $2;
+ }
+
+DirElemContent: /* empty */ /* [101] */
+ {
+ $$ = Expression::List();
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent DirectConstructor
+ {
+ $1.append($2);
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent StringLiteral
+ {
+ if(parseInfo->staticContext->boundarySpacePolicy() == StaticContext::BSPStrip &&
+ XPathHelper::isWhitespaceOnly($2))
+ {
+ $$ = $1;
+ }
+ else
+ {
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+ }
+| DirElemContent NON_BOUNDARY_WS
+ {
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo));
+ $$ = $1;
+ parseInfo->isPreviousEnclosedExpr = false;
+ }
+| DirElemContent EnclosedExpr
+ {
+ /* We insert a text node constructor that send an empty text node between
+ * the two enclosed expressions, in order to ensure that no space is inserted.
+ *
+ * However, we only do it when we have no node constructors. */
+ if(parseInfo->isPreviousEnclosedExpr &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($2->staticType()->itemType()) &&
+ BuiltinTypes::xsAnyAtomicType->xdtTypeMatches($1.last()->staticType()->itemType()))
+ $1.append(create(new TextNodeConstructor(create(new Literal(AtomicString::fromValue(QString())), @$, parseInfo)), @$, parseInfo));
+ else
+ parseInfo->isPreviousEnclosedExpr = true;
+
+ $1.append(createCopyOf($2, parseInfo, @$));
+ $$ = $1;
+ }
+
+DirCommentConstructor: COMMENT_START COMMENT_CONTENT /* [103] */
+ {
+ $$ = create(new CommentConstructor(create(new Literal(AtomicString::fromValue($2)), @$, parseInfo)), @$, parseInfo);
+ }
+
+DirPIConstructor: PI_START PI_TARGET PI_CONTENT /* [105] */
+ {
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+ NCNameConstructor::validateTargetName<StaticContext::Ptr,
+ ReportContext::XPST0003,
+ ReportContext::XPST0003>($2,
+ parseInfo->staticContext, &ryy);
+
+ $$ = create(new ProcessingInstructionConstructor(
+ create(new Literal(AtomicString::fromValue($2)), @$, parseInfo),
+ create(new Literal(AtomicString::fromValue($3)), @$, parseInfo)), @$, parseInfo);
+ }
+
+ComputedConstructor: CompDocConstructor /* [109] */
+| CompElemConstructor
+| CompAttrConstructor
+| CompTextConstructor
+| CompCommentConstructor
+| CompPIConstructor
+| CompNamespaceConstructor
+
+CompDocConstructor: DOCUMENT IsInternal EnclosedExpr /* [110] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ $$ = create(new DocumentConstructor($3), @$, parseInfo);
+ }
+
+CompElemConstructor: ELEMENT IsInternal CompElementName
+ {
+ /* This value is incremented before the action below is executed. */
+ ++parseInfo->elementConstructorDepth;
+ }
+ EnclosedOptionalExpr /* [111] */
+ {
+ Q_ASSERT(5);
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ Expression::Ptr effExpr;
+
+ if($5)
+ effExpr = createCopyOf($5, parseInfo, @$);
+ else
+ effExpr = create(new EmptySequence(), @$, parseInfo);
+
+ const QXmlName::NamespaceCode ns = parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty);
+
+ /* Ensure the default namespace gets counted as an in-scope binding, if such a one exists. If we're
+ * a child of another constructor, it has already been done. */
+ if(parseInfo->elementConstructorDepth == 1 && ns != StandardNamespaces::empty)
+ {
+ Expression::List exprList;
+
+ /* We append the namespace constructor before the body, in order to
+ * comply with QAbstractXmlPushHandler's contract. */
+ const QXmlName def(parseInfo->resolvers.top()->lookupNamespaceURI(StandardPrefixes::empty), StandardLocalNames::empty);
+ exprList.append(create(new NamespaceConstructor(def), @$, parseInfo));
+
+ exprList.append(effExpr);
+
+ effExpr = create(new ExpressionSequence(exprList), @$, parseInfo);
+ }
+
+ --parseInfo->elementConstructorDepth;
+ $$ = create(new ElementConstructor($3, effExpr, parseInfo->isXSLT()), @$, parseInfo);
+ }
+
+IsInternal: /* Empty. */ /* [X] */
+ {
+ $$ = false;
+ }
+| INTERNAL
+ {
+ $$ = true;
+ }
+
+CompAttrConstructor: ATTRIBUTE
+ IsInternal
+ CompAttributeName
+ EnclosedOptionalExpr /* [113] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ const Expression::Ptr name(create(new AttributeNameValidator($3), @$, parseInfo));
+
+ if($4)
+ $$ = create(new AttributeConstructor(name, createSimpleContent($4, @$, parseInfo)), @$, parseInfo);
+ else
+ $$ = create(new AttributeConstructor(name, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
+ }
+
+CompTextConstructor: TEXT IsInternal EnclosedExpr /* [114] */
+ {
+ $$ = create(new TextNodeConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+
+CompCommentConstructor: COMMENT IsInternal EnclosedExpr /* [115] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ $$ = create(new CommentConstructor(createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+
+CompPIConstructor: PROCESSING_INSTRUCTION CompPIName EnclosedOptionalExpr /* [116] */
+ {
+ allowedIn(QXmlQuery::XQuery10, parseInfo, @$, $2);
+
+ if($3)
+ {
+ $$ = create(new ProcessingInstructionConstructor($2, createSimpleContent($3, @$, parseInfo)), @$, parseInfo);
+ }
+ else
+ $$ = create(new ProcessingInstructionConstructor($2, create(new EmptySequence(), @$, parseInfo)), @$, parseInfo);
+ }
+
+CompAttributeName: {
+ parseInfo->nodeTestSource = BuiltinTypes::attribute;
+ }
+ ElementName
+ {
+ parseInfo->restoreNodeTestSource();
+ } /* [X] */
+ {
+ $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $2))), @$, parseInfo);
+ }
+| CompNameExpr
+
+CompElementName: ElementName /* [X] */
+ {
+ $$ = create(new Literal(toItem(QNameValue::fromValue(parseInfo->staticContext->namePool(), $1))), @$, parseInfo);
+ }
+| CompNameExpr
+
+CompNameExpr: EnclosedExpr
+ {
+ if(BuiltinTypes::xsQName->xdtTypeMatches($1->staticType()->itemType()))
+ $$ = $1;
+ else
+ {
+ $$ = create(new QNameConstructor($1,
+ parseInfo->staticContext->namespaceBindings()),
+ @$, parseInfo);
+ }
+ }
+
+/*
+ * We always create an NCNameConstructor here. If will be rewritten away if not needed.
+ */
+CompPIName: NCNAME
+ {
+ $$ = create(new NCNameConstructor(create(new Literal(AtomicString::fromValue($1)), @$, parseInfo)), @$, parseInfo);
+ }
+| EnclosedExpr
+ {
+ $$ = create(new NCNameConstructor($1), @$, parseInfo);
+ }
+
+/*
+ * This expression is used for implementing XSL-T 2.0's xsl:namespace
+ * instruction.
+ */
+CompNamespaceConstructor: NAMESPACE EnclosedExpr EnclosedExpr /* [X] */
+{
+ $$ = create(new ComputedNamespaceConstructor($2, $3), @$, parseInfo);
+}
+
+SingleType: AtomicType /* [117] */
+ {
+ $$ = makeGenericSequenceType($1, Cardinality::exactlyOne());
+ }
+| AtomicType QUESTION
+ {
+ $$ = makeGenericSequenceType($1, Cardinality::zeroOrOne());
+ }
+
+TypeDeclaration: /* empty */ /* [118] */
+ {
+ $$ = CommonSequenceTypes::ZeroOrMoreItems;
+ }
+| AS SequenceType
+ {
+ $$ = $2;
+ }
+
+SequenceType: ItemType OccurrenceIndicator /* [119] */
+ {
+ $$ = makeGenericSequenceType($1, $2);
+ }
+
+| EMPTY_SEQUENCE EmptyParanteses
+ {
+ $$ = CommonSequenceTypes::Empty;
+ }
+
+OccurrenceIndicator: /* empty */ {$$ = Cardinality::exactlyOne();} /* [120] */
+| PLUS {$$ = Cardinality::oneOrMore();}
+| STAR {$$ = Cardinality::zeroOrMore();}
+| QUESTION {$$ = Cardinality::zeroOrOne();}
+
+ItemType: AtomicType /* [121] */
+| KindTest
+| AnyAttributeTest
+| ITEM EmptyParanteses
+ {
+ $$ = BuiltinTypes::item;
+ }
+
+AtomicType: ElementName /* [122] */
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($1));
+
+ if(!t)
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name %1 does not refer to any schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $1)), ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ else if(BuiltinTypes::xsAnyAtomicType->wxsTypeMatches(t))
+ $$ = AtomicType::Ptr(t);
+ else
+ {
+ /* Try to give an intelligent message. */
+ if(t->isComplexType())
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an complex type. Casting to complex "
+ "types is not possible. However, casting "
+ "to atomic types such as %2 works.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t))
+ .arg(formatType(parseInfo->staticContext->namePool(), BuiltinTypes::xsInteger)),
+ ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not an atomic type. Casting "
+ "is only possible to atomic types.")
+ .arg(formatType(parseInfo->staticContext->namePool(), t)),
+ ReportContext::XPST0051, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+ }
+
+/* This non-terminal does not contain SchemaAttributeTest and AttributeTest.
+ Those are in the AnyAttributeTest non-terminal. This is in order to get the axis
+ right for attribute tests in the abbreviated syntax. */
+KindTest: DocumentTest /* [123] */
+| ElementTest
+| SchemaElementTest
+| PITest
+| CommentTest
+| TextTest
+| AnyKindTest
+
+AnyKindTest: NODE EmptyParanteses /* [124] */
+ {
+ $$ = BuiltinTypes::node;
+ }
+
+DocumentTest: DOCUMENT_NODE EmptyParanteses /* [125] */
+ {
+ $$ = BuiltinTypes::document;
+ }
+
+| DOCUMENT_NODE LPAREN AnyElementTest RPAREN
+ {
+ // TODO support for document element testing
+ $$ = BuiltinTypes::document;
+ }
+
+AnyElementTest: ElementTest /* [X] */
+| SchemaElementTest
+
+TextTest: TEXT EmptyParanteses /* [126] */
+ {
+ $$ = BuiltinTypes::text;
+ }
+
+CommentTest: COMMENT EmptyParanteses /* [127] */
+ {
+ $$ = BuiltinTypes::comment;
+ }
+
+PITest: PROCESSING_INSTRUCTION EmptyParanteses /* [128] */
+ {
+ $$ = BuiltinTypes::pi;
+ }
+
+| PROCESSING_INSTRUCTION LPAREN NCNAME RPAREN
+ {
+ $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
+ }
+
+| PROCESSING_INSTRUCTION LPAREN StringLiteral RPAREN
+ {
+ if(QXmlUtils::isNCName($3))
+ {
+ $$ = LocalNameTest::create(BuiltinTypes::pi, parseInfo->staticContext->namePool()->allocateLocalName($3));
+ }
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not a valid name for a "
+ "processing-instruction.")
+ .arg(formatKeyword($3)),
+ ReportContext::XPTY0004,
+ fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+AnyAttributeTest: AttributeTest
+| SchemaAttributeTest
+
+AttributeTest: ATTRIBUTE EmptyParanteses /* [129] */
+ {
+ $$ = BuiltinTypes::attribute;
+ }
+
+| ATTRIBUTE LPAREN STAR RPAREN
+ {
+ $$ = BuiltinTypes::attribute;
+ }
+
+| ATTRIBUTE LPAREN AttributeName RPAREN
+ {
+ $$ = QNameTest::create(BuiltinTypes::attribute, $3);
+ }
+| ATTRIBUTE LPAREN AttributeName COMMA TypeName RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+| ATTRIBUTE LPAREN STAR COMMA TypeName RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::attribute;
+ else
+ {
+ parseInfo->staticContext->error(unknownType().arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+SchemaAttributeTest: SCHEMA_ATTRIBUTE LPAREN ElementName RPAREN /* [131] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ $$.reset();
+ }
+
+ElementTest: ELEMENT EmptyParanteses /* [133] */
+ {
+ $$ = BuiltinTypes::element;
+ }
+
+| ELEMENT LPAREN STAR RPAREN
+ {
+ $$ = BuiltinTypes::element;
+ }
+
+| ELEMENT LPAREN ElementName RPAREN
+ {
+ $$ = QNameTest::create(BuiltinTypes::element, $3);
+ }
+
+| ELEMENT LPAREN ElementName COMMA TypeName OptionalQuestionMark RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(unknownType()
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+| ELEMENT LPAREN STAR COMMA TypeName OptionalQuestionMark RPAREN
+ {
+ const SchemaType::Ptr t(parseInfo->staticContext->schemaDefinitions()->createSchemaType($5));
+
+ if(t)
+ $$ = BuiltinTypes::element;
+ else
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is an unknown schema type.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $5)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ }
+ }
+
+OptionalQuestionMark: /* Empty. */
+| QUESTION
+
+SchemaElementTest: SCHEMA_ELEMENT LPAREN ElementName RPAREN /* [135] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("%1 is not in the in-scope attribute "
+ "declarations. Note that the schema import "
+ "feature is not supported.")
+ .arg(formatKeyword(parseInfo->staticContext->namePool(), $3)),
+ ReportContext::XPST0008, fromYYLTYPE(@$, parseInfo));
+ $$.reset();
+ }
+
+EmptyParanteses: LPAREN RPAREN /* [X] */
+
+AttributeName: NCNAME /* [137] */
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+
+| QName
+
+/*
+ * When a QName appear with no prefix, it uses a certain default namespace
+ * depending on where the QName occurs. These two rules, invoked in the appropriate
+ * contexts, performs this distinction.
+ */
+ElementName: NCNAME /* [138] */
+ {
+ if(parseInfo->nodeTestSource == BuiltinTypes::element)
+ $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->namespaceBindings()->lookupNamespaceURI(StandardPrefixes::empty), $1);
+ else
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::empty, $1);
+ }
+| QName
+
+TypeName: ElementName /* [139] */
+
+FunctionName: NCName /* [X] */
+| QName
+
+NCName: NCNAME
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(parseInfo->staticContext->defaultFunctionNamespace(), $1);
+ }
+| INTERNAL_NAME NCNAME
+ {
+ $$ = parseInfo->staticContext->namePool()->allocateQName(StandardNamespaces::InternalXSLT, $2);
+ }
+
+LexicalName: NCNAME
+| QNAME
+
+PragmaName: NCNAME /* [X] */
+ {
+ parseInfo->staticContext->error(QtXmlPatterns::tr("The name of an extension expression must be in "
+ "a namespace."),
+ ReportContext::XPST0081, fromYYLTYPE(@$, parseInfo));
+ }
+| QName
+
+URILiteral: StringLiteral /* [140] */
+
+StringLiteral: STRING_LITERAL /* [144] */
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+| XPATH2_STRING_LITERAL
+ {
+ allowedIn(QueryLanguages(QXmlQuery::XQuery10 | QXmlQuery::XPath20), parseInfo, @$);
+ }
+
+QName: QNAME /* [154] */
+ {
+
+ const ReflectYYLTYPE ryy(@$, parseInfo);
+
+ $$ = QNameConstructor::
+ expandQName<StaticContext::Ptr,
+ ReportContext::XPST0081,
+ ReportContext::XPST0081>($1, parseInfo->staticContext,
+ parseInfo->staticContext->namespaceBindings(), &ryy);
+
+ }
+| CLARK_NAME
+ {
+ $$ = parseInfo->staticContext->namePool()->fromClarkName($1);
+ }
+
+%%
+
+QString Tokenizer::tokenToString(const Token &token)
+{
+ switch(token.type)
+ {
+ case NCNAME:
+ /* Fallthrough. */
+ case QNAME:
+ /* Fallthrough. */
+ case NUMBER:
+ /* Fallthrough. */
+ case XPATH2_NUMBER:
+ return token.value;
+ case STRING_LITERAL:
+ return QLatin1Char('"') + token.value + QLatin1Char('"');
+ default:
+ {
+ const QString raw(QString::fromLatin1(yytname[YYTRANSLATE(token.type)]));
+
+ /* Remove the quotes. */
+ if(raw.at(0) == QLatin1Char('"') && raw.length() > 1)
+ return raw.mid(1, raw.length() - 2);
+ else
+ return raw;
+ }
+ }
+}
+
+} /* namespace Patternist */
+
+QT_END_NAMESPACE
+
+// vim: et:ts=4:sw=4:sts=4:syntax=yacc
diff --git a/src/xmlpatterns/parser/qxquerytokenizer.cpp b/src/xmlpatterns/parser/qxquerytokenizer.cpp
new file mode 100644
index 0000000..13f5a6e
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer.cpp
@@ -0,0 +1,2249 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <QByteArray>
+
+#include "qquerytransformparser_p.h"
+
+#include "qxquerytokenizer_p.h"
+
+#include "qtokenlookup.cpp"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+#define handleWhitespace() \
+{ \
+ const TokenType t = consumeWhitespace(); \
+ if(t != SUCCESS) \
+ return Token(t); \
+}
+
+XQueryTokenizer::XQueryTokenizer(const QString &query,
+ const QUrl &location,
+ const State startingState) : Tokenizer(location)
+ , m_data(query)
+ , m_length(query.length())
+ , m_state(startingState)
+ , m_pos(0)
+ , m_line(1)
+ , m_columnOffset(0)
+ , m_scanOnly(false)
+{
+ Q_ASSERT(location.isValid() || location.isEmpty());
+}
+
+const QChar XQueryTokenizer::current() const
+{
+ if(m_pos < m_length)
+ return m_data.at(m_pos);
+ else
+ return QChar();
+}
+
+char XQueryTokenizer::peekCurrent() const
+{
+ return current().toAscii();
+}
+
+int XQueryTokenizer::peekForColonColon() const
+{
+ /* Note, we don't modify m_pos in this function, so we need to do offset
+ * calculations. */
+ int pos = m_pos;
+
+ while(pos < m_length)
+ {
+ switch(m_data.at(pos).toAscii())
+ {
+ /* Fallthrough these four. */
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ case ':':
+ {
+ if(peekAhead((pos - m_pos) + 1) == ':')
+ return pos - m_pos;
+ /* Fallthrough. */
+ }
+ default:
+ return -1;
+ }
+ ++pos;
+ }
+
+ return -1;
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndChangeState(const TokenType code,
+ const State s,
+ const int advance)
+{
+ Q_ASSERT(advance >= 0);
+ m_pos += advance;
+ setState(s);
+ return Token(code);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndChangeState(const TokenType code,
+ const QString &value,
+ const State s)
+{
+ setState(s);
+ return Token(code, value);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenAndAdvance(const TokenType code,
+ const int advance)
+{
+ Q_ASSERT(advance >= 0);
+ m_pos += advance;
+ return Token(code);
+}
+
+QString XQueryTokenizer::normalizeEOL(const QString &input,
+ const CharacterSkips &characterSkips)
+{
+ const int len = input.count();
+ QString result;
+
+ /* The likely hood is rather high it'll be the same content. */
+ result.reserve(len);
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QChar &at = input.at(i);
+
+ if(characterSkips.contains(i))
+ {
+ result.append(at);
+ continue;
+ }
+ switch(input.at(i).unicode())
+ {
+ case '\r':
+ {
+ if(i + 1 < len && input.at(i + 1) == QLatin1Char('\n'))
+ ++i;
+
+ /* Else, fallthrough. */
+ }
+ case '\n':
+ {
+ result.append(QLatin1Char('\n'));
+ continue;
+ }
+ default:
+ {
+ result.append(at);
+ }
+ }
+ }
+
+ return result;
+}
+
+Tokenizer::TokenType XQueryTokenizer::consumeComment()
+{
+ /* Below, we return ERROR instead of END_OF_FILE such that the parser
+ * sees an invalid comment. */
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ':':
+ {
+ ++m_pos; /* Consume ':' */
+ if(atEnd())
+ return ERROR;
+
+ if(peekCurrent() == ')')
+ {
+ ++m_pos; /* Consume ')' */
+ return SUCCESS; /* The comment closed nicely. */
+ }
+ continue; /* We don't want to increment m_pos twice. */
+ }
+ case '(':
+ { /* It looks like the start of a comment. */
+ ++m_pos;
+
+ if(atEnd())
+ return END_OF_FILE;
+ else if(peekCurrent() == ':')
+ {
+ /* And it is a nested comment -- parse it. */
+ const TokenType retval = consumeComment();
+ if(retval == SUCCESS)
+ continue; /* Continue with our "own" comment. */
+ else
+ return retval; /* Return the error in the nested comment. */
+ }
+ break;
+ }
+ case '\n':
+ /* Fallthrough. */
+ case '\r':
+ {
+ /* We want to count \r\n as a single line break. */
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ }
+ ++m_pos;
+ }
+
+ return ERROR; /* Error: we reached the end while inside a comment. */
+}
+
+bool XQueryTokenizer::consumeRawWhitespace()
+{
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ' ':
+ case '\t':
+ break;
+ case '\n':
+ case '\r':
+ {
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ default:
+ return false;
+ }
+ ++m_pos;
+ }
+ return true;
+}
+
+Tokenizer::TokenType XQueryTokenizer::consumeWhitespace()
+{
+ while(m_pos < m_length)
+ {
+ switch(peekCurrent())
+ {
+ case ' ':
+ case '\t':
+ break;
+ case '\n':
+ case '\r':
+ {
+ /* We want to count \r\n as a single line break. */
+ if(peekAhead() == '\n')
+ ++m_pos;
+
+ m_columnOffset = m_pos;
+ ++m_line;
+
+ break;
+ }
+ case '(':
+ {
+ if(peekAhead() == ':')
+ {
+ m_pos += 2; /* Consume "(:" */
+
+ const TokenType comment = consumeComment();
+ if(comment == SUCCESS)
+ continue;
+ else
+ return comment;
+ }
+ }
+ default:
+ return SUCCESS;
+ }
+ ++m_pos;
+ }
+
+ return END_OF_FILE;
+}
+
+char XQueryTokenizer::peekAhead(const int length) const
+{
+ if(m_pos + length < m_length)
+ return m_data.at(m_pos + length).toAscii();
+ else
+ return 0;
+}
+
+Tokenizer::Token XQueryTokenizer::error()
+{
+ return Token(ERROR);
+}
+
+bool XQueryTokenizer::isDigit(const char ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+
+/* Replace with function in QXmlUtils. Write test cases for this. */
+bool XQueryTokenizer::isNCNameStart(const QChar ch)
+{
+ if(ch == QLatin1Char('_'))
+ return true;
+
+ switch(ch.category())
+ {
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Other:
+ case QChar::Letter_Titlecase:
+ case QChar::Number_Letter:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isNCNameBody(const QChar ch)
+{
+ switch(ch.unicode())
+ {
+ case '.':
+ case '_':
+ case '-':
+ return true;
+ }
+
+ switch(ch.category())
+ {
+ case QChar::Letter_Lowercase:
+ case QChar::Letter_Uppercase:
+ case QChar::Letter_Other:
+ case QChar::Letter_Titlecase:
+ case QChar::Number_Letter:
+ case QChar::Mark_SpacingCombining:
+ case QChar::Mark_Enclosing:
+ case QChar::Mark_NonSpacing:
+ case QChar::Letter_Modifier:
+ case QChar::Number_DecimalDigit:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isPhraseKeyword(const TokenType code)
+{
+ switch(code)
+ {
+ /* Fallthrough all these. */
+ case CASTABLE:
+ case CAST:
+ case COPY_NAMESPACES:
+ case DECLARE:
+ case EMPTY:
+ case MODULE:
+ case IMPORT:
+ case INSTANCE:
+ case ORDER:
+ case ORDERING:
+ case XQUERY:
+ case STABLE:
+ case TREAT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool XQueryTokenizer::isOperatorKeyword(const TokenType code)
+{
+ switch(code)
+ {
+ /* Fallthrough all these. */
+ case AS:
+ case ASCENDING:
+ case AT:
+ case CASE:
+ case CAST:
+ case CASTABLE:
+ case EQ:
+ case EXTERNAL:
+ case GE:
+ case G_EQ:
+ case G_GT:
+ case G_LT:
+ case G_NE:
+ case GT:
+ case IN:
+ case INHERIT:
+ case INSTANCE:
+ case IS:
+ case ITEM:
+ case LE:
+ case LT:
+ case NE:
+ case NO_INHERIT:
+ case NO_PRESERVE:
+ case OF:
+ case PRESERVE:
+ case RETURN:
+ case STABLE:
+ case TO:
+ case TREAT:
+ return true;
+ default:
+ return false;
+ };
+}
+
+bool XQueryTokenizer::isTypeToken(const TokenType t)
+{
+ switch(t)
+ {
+ /* Fallthrough all these. */
+ case ATTRIBUTE:
+ case COMMENT:
+ case DOCUMENT:
+ case DOCUMENT_NODE:
+ case ELEMENT:
+ case ITEM:
+ case NODE:
+ case PROCESSING_INSTRUCTION:
+ case SCHEMA_ATTRIBUTE:
+ case SCHEMA_ELEMENT:
+ case TEXT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNCNameOrQName()
+{
+ const int start = m_pos;
+
+ const Token t1 = tokenizeNCName();
+ if(t1.hasError())
+ return t1;
+
+ if(peekCurrent() != ':' || peekAhead() == '=')
+ return t1;
+
+ ++m_pos;
+
+ const Token t2 = tokenizeNCName();
+ if(t2.hasError())
+ return t2;
+ else
+ return Token(QNAME, m_data.mid(start, m_pos - start));
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNumberLiteral()
+{
+ setState(Operator);
+ const int startPos = m_pos;
+ bool hasDot = false;
+ bool isXPath20 = false;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ QChar ch(current());
+
+ char cell = ch.cell();
+
+ if(cell == 'e' || cell == 'E')
+ {
+ isXPath20 = true;
+ ++m_pos;
+ ch = current();
+
+ if(ch.row() != 0)
+ break;
+
+ cell = ch.cell();
+
+ if(cell == '+' || cell == '-')
+ continue;
+ }
+
+ if(isNCNameStart(ch))
+ return error();
+
+ if(cell < '0' || cell > '9')
+ {
+ if(cell == '.' && !hasDot)
+ hasDot = true;
+ else
+ break;
+ }
+ }
+
+ return Token(isXPath20 ? XPATH2_NUMBER : NUMBER, m_data.mid(startPos, m_pos - startPos));
+}
+
+QString XQueryTokenizer::tokenizeCharacterReference()
+{
+ Q_ASSERT(peekCurrent() == '&');
+
+ const int theEnd = m_data.indexOf(QLatin1Char(';'), m_pos + 1);
+
+ if(theEnd == -1) /* No ';' found, a syntax error. i18n. */
+ return QString();
+
+ QString content(m_data.mid(m_pos + 1, (theEnd - m_pos) - 1));
+ m_pos = theEnd;
+
+ const QChar charRef(charForReference(content));
+
+ if(!charRef.isNull())
+ return charRef;
+ else if(content.startsWith(QLatin1Char('#')))
+ {
+ int base;
+
+ /* It is only '#' or '#x'. */
+ if(content.length() < 2)
+ return QString();
+
+ /* We got a hex number if it starts with 'x', otherwise it's a decimal. */
+ if(content.at(1) == QLatin1Char('x'))
+ {
+ base = 16;
+ content = content.mid(2); /* Remove "#x". */
+ }
+ else
+ {
+ base = 10;
+ content = content.mid(1); /* Remove "#". */
+ }
+
+ bool conversionOK = false;
+ const int codepoint = content.toInt(&conversionOK, base);
+
+ if(conversionOK)
+ {
+ const QChar ch(codepoint);
+
+ if(ch.isNull())
+ {
+ /* We likely have something which require surrogate pairs. */
+ QString result;
+ result += QChar(QChar::highSurrogate(codepoint));
+ result += QChar(QChar::lowSurrogate(codepoint));
+ return result;
+ }
+ else
+ return ch;
+ }
+ else
+ return QString();
+ }
+ else
+ return QString();
+}
+
+int XQueryTokenizer::scanUntil(const char *const content)
+{
+ const int end = m_data.indexOf(QString::fromLatin1(content), m_pos);
+
+ if(end == -1)
+ return -1;
+ else
+ {
+ const int len = end - m_pos;
+ m_pos += len;
+ return len;
+ }
+}
+
+QChar XQueryTokenizer::charForReference(const QString &reference)
+{
+ if(m_charRefs.isEmpty())
+ {
+ /* Initialize. */
+ m_charRefs.reserve(5);
+ m_charRefs.insert(QLatin1String("lt"), QLatin1Char('<'));
+ m_charRefs.insert(QLatin1String("gt"), QLatin1Char('>'));
+ m_charRefs.insert(QLatin1String("amp"), QLatin1Char('&'));
+ m_charRefs.insert(QLatin1String("quot"), QLatin1Char('"'));
+ m_charRefs.insert(QLatin1String("apos"), QLatin1Char('\''));
+ }
+
+ return m_charRefs.value(reference);
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeStringLiteral()
+{
+ const QChar delimiter(current());
+ /* We cannot unfortunately just scan and then do mid(),
+ * since we can encounter character references. */
+ QString result;
+
+ /* This is more likely than QString's default allocation. */
+ result.reserve(8);
+
+ CharacterSkips skipEOLNormalization;
+
+ /* Advance over the initial quote character. */
+ ++m_pos;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ const QChar c(current());
+
+ if(c == QLatin1Char('&'))
+ {
+ const QString charRef(tokenizeCharacterReference());
+
+ if(charRef.isNull())
+ return error();
+ else
+ {
+ skipEOLNormalization.insert(result.count());
+ result.append(charRef);
+ }
+
+ }
+ else if(c == delimiter)
+ {
+ /* Maybe the escaping mechanism is used. For instance, "s""s"
+ * has the value `s"s'. */
+ ++m_pos;
+
+ if(current() == delimiter) /* Double quote. */
+ result += delimiter;
+ else
+ return Token(STRING_LITERAL, normalizeEOL(result, skipEOLNormalization));
+ }
+ else
+ result += c;
+ }
+
+ return error();
+}
+
+Tokenizer::Token XQueryTokenizer::tokenizeNCName()
+{
+ const int startPos = m_pos;
+
+ if(m_pos < m_length && isNCNameStart(current()))
+ {
+ ++m_pos;
+
+ for(; m_pos < m_length; ++m_pos)
+ {
+ if(!isNCNameBody(current()))
+ break;
+ }
+
+ return Token(NCNAME, m_data.mid(startPos, m_pos - startPos));
+ }
+ else
+ return error();
+}
+
+bool XQueryTokenizer::aheadEquals(const char *const chs,
+ const int len,
+ const int offset) const
+{
+ Q_ASSERT(len > 0);
+ Q_ASSERT(qstrlen(chs) == uint(len));
+
+ if(m_pos + len >= m_length)
+ return false;
+
+ for(int i = offset; i < (len + offset); ++i)
+ {
+ if(m_data.at(m_pos + i).toAscii() != chs[i - offset])
+ return false;
+ }
+
+ return true;
+}
+
+const TokenMap *XQueryTokenizer::lookupKeyword(const QString &keyword)
+{
+ return TokenLookup::value(keyword.toAscii().constData(), keyword.length());
+}
+
+XQueryTokenizer::State XQueryTokenizer::state() const
+{
+ return m_state;
+}
+
+void XQueryTokenizer::setState(const State s)
+{
+ m_state = s;
+}
+
+void XQueryTokenizer::pushState(const State s)
+{
+ m_stateStack.push(s);
+}
+
+void XQueryTokenizer::pushState()
+{
+ m_stateStack.push(m_state);
+}
+
+void XQueryTokenizer::popState()
+{
+ /* QStack::pop() asserts if it's empty, so we need to check
+ * it, since we might receive unbalanced curlies. */
+ if(!m_stateStack.isEmpty())
+ m_state = m_stateStack.pop();
+}
+
+Tokenizer::Token XQueryTokenizer::nextToken()
+{
+ switch(state())
+ {
+ /* We want to skip or do special whitespace handling for these
+ * states. So fallthrough all of the following. */
+ case AposAttributeContent:
+ case Axis:
+ case ElementContent:
+ case EndTag:
+ case Pragma:
+ case PragmaContent:
+ case ProcessingInstructionName:
+ case QuotAttributeContent:
+ case StartTag:
+ case XMLComment:
+ break;
+ default:
+ handleWhitespace();
+ }
+
+ switch(state())
+ {
+ case XMLSpaceDecl:
+ /* Fallthrough. */
+ case NamespaceKeyword:
+ {
+ switch(peekCurrent())
+ {
+ case ',':
+ return tokenAndAdvance(COMMA);
+ case '"':
+ /* Fallthrough. */
+ case '\'':
+ {
+ setState(NamespaceDecl);
+ return tokenizeStringLiteral();
+ }
+ }
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+ if(keyword)
+ {
+ switch(keyword->token)
+ {
+ case INHERIT:
+ /* Fallthrough. */
+ case NO_INHERIT:
+ {
+ setState(Default);
+ break;
+ }
+ case NAMESPACE:
+ {
+ setState(NamespaceDecl);
+ break;
+ }
+ case ORDERED:
+ /* Fallthrough. */
+ case UNORDERED:
+ /* Fallthrough. */
+ case STRIP:
+ {
+ setState(Default);
+ break;
+ }
+ case PRESERVE:
+ {
+ if(state() != NamespaceKeyword)
+ setState(Default);
+ }
+ default:
+ break;
+ }
+
+ return Token(keyword->token);
+ }
+ else
+ return id;
+
+ Q_ASSERT(false);
+ }
+ case NamespaceDecl:
+ {
+ switch(peekCurrent())
+ {
+ case '=':
+ return tokenAndAdvance(G_EQ);
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ case '\'':
+ /* Fallthrough. */
+ case '\"':
+ return tokenizeStringLiteral();
+ }
+
+ const Token nc(tokenizeNCName());
+
+ handleWhitespace();
+
+ const char pc = peekCurrent();
+ const TokenMap* const t = lookupKeyword(nc.value);
+
+ if(pc == '\'' || (pc == '"' && t))
+ return tokenAndChangeState(t->token, Default, 0);
+ else
+ return nc;
+
+ Q_ASSERT(false);
+ }
+ case Axis:
+ {
+ if(peekCurrent() == ':')
+ {
+ Q_ASSERT(peekAhead() == ':');
+ m_pos += 2;
+ setState(AfterAxisSeparator);
+ return Token(COLONCOLON);
+ }
+ /* Fallthrough. */
+ }
+ case AfterAxisSeparator:
+ /* Fallthrough. */
+ case Default:
+ /* State Operator and state Default have a lot of tokens in common except
+ * for minor differences. So we treat them the same way, and sprinkles logic
+ * here and there to handle the small differences. */
+ /* Fallthrough. */
+ case Operator:
+ {
+ switch(peekCurrent())
+ {
+ case '=':
+ return tokenAndChangeState(G_EQ, Default);
+ case '-':
+ return tokenAndChangeState(MINUS, Default);
+ case '+':
+ return tokenAndChangeState(PLUS, Default);
+ case '[':
+ return tokenAndChangeState(LBRACKET, Default);
+ case ']':
+ return tokenAndChangeState(RBRACKET, Operator);
+ case ',':
+ return tokenAndChangeState(COMMA, Default);
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ case '$':
+ return tokenAndChangeState(DOLLAR, VarName);
+ case '|':
+ return tokenAndChangeState(BAR, Default);
+ case '?':
+ return tokenAndChangeState(QUESTION, Operator);
+ case ')':
+ return tokenAndChangeState(RPAREN, Operator);
+ case '@':
+ return tokenAndChangeState(AT_SIGN, Default);
+ /* Fallthrough all these. */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '0':
+ return tokenizeNumberLiteral();
+ case '.':
+ {
+ const char next = peekAhead();
+ if(next == '.')
+ return tokenAndChangeState(DOTDOT, Operator, 2);
+ /* .5 is allowed, as short form for 0.5:
+ * <tt>[142] DecimalLiteral ::= ("." Digits) | (Digits "." [0-9]*)</tt>
+ */
+ else if(isDigit(next))
+ return tokenizeNumberLiteral();
+ else
+ return tokenAndChangeState(DOT, Operator);
+ }
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ {
+ setState(Operator);
+ return tokenizeStringLiteral();
+
+ }
+ case '(':
+ {
+ if(peekAhead() == '#')
+ return tokenAndChangeState(PRAGMA_START, Pragma, 2);
+ else
+ return tokenAndChangeState(LPAREN, Default);
+ }
+ case '*':
+ {
+ if(peekAhead() == ':')
+ {
+ m_pos += 2; /* Consume *:. */
+ const Token nc = tokenizeNCName();
+
+ if(nc.hasError())
+ return error();
+ else
+ return tokenAndChangeState(ANY_PREFIX, nc.value, Operator);
+ }
+ else
+ return tokenAndChangeState(STAR, state() == Default ? Operator : Default);
+ }
+ case ':':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(ASSIGN, Default, 2);
+ case ':':
+ return tokenAndChangeState(COLONCOLON, Default, 2);
+ default:
+ return error();
+ }
+ }
+ case '!':
+ {
+ if(peekAhead() == '=')
+ return tokenAndChangeState(G_NE, Default, 2);
+ else
+ return error();
+ }
+ case '<':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(G_LE, Default, 2);
+ case '<':
+ return tokenAndChangeState(PRECEDES, Default, 2);
+ case '?':
+ {
+ pushState(Operator);
+ return tokenAndChangeState(PI_START, ProcessingInstructionName, 2);
+ }
+ case '!':
+ {
+ if(aheadEquals("!--", 3))
+ {
+ m_pos += 3; /* Consume "!--". */
+ pushState(Operator);
+ return tokenAndChangeState(COMMENT_START, XMLComment);
+ }
+ /* Fallthrough. It's a syntax error, and this is a good way to report it. */
+ }
+ default:
+ {
+ if((m_pos + 1) < m_length && isNCNameStart(m_data.at(m_pos + 1)))
+ {
+ /* We assume it's an element constructor. */
+ pushState(Operator);
+ }
+
+ return tokenAndChangeState(G_LT, state() == Operator ? Default : StartTag);
+ }
+ }
+ }
+ case '>':
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return tokenAndChangeState(G_GE, Default, 2);
+ case '>':
+ return tokenAndChangeState(FOLLOWS, Default, 2);
+ default:
+ return tokenAndChangeState(G_GT, Default);
+ }
+ }
+ case '/':
+ {
+ if(peekAhead() == '/')
+ return tokenAndChangeState(SLASHSLASH, Default, 2);
+ else
+ return tokenAndChangeState(SLASH, Default);
+ }
+ case '{':
+ {
+ pushState(Operator);
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ case '}':
+ {
+ popState();
+
+ return tokenAndAdvance(CURLY_RBRACE);
+ }
+ }
+
+ /* Ok. We're in state Default or Operator, and it wasn't a simple
+ * character. */
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+
+ if(state() == Operator)
+ {
+ if(keyword)
+ {
+ if(keyword->token == DEFAULT || keyword->token == ASCENDING || keyword->token == DESCENDING)
+ setState(Operator);
+ else if(keyword->token == RETURN)
+ setState(Default);
+ else if(isPhraseKeyword(keyword->token))
+ {
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR)
+ return error();
+
+ const Token id2(tokenizeNCName());
+ const TokenMap *const keyword2 = lookupKeyword(id2.value);
+
+ if(keyword2)
+ {
+ if(keyword->token == TREAT && keyword2->token == AS)
+ setState(ItemType);
+ else if (keyword->token == CAST || (keyword->token == CASTABLE && keyword2->token == AS) || keyword2->token == BY)
+ setState(Default);
+
+ m_tokenStack.push(Token(keyword2->token));
+ }
+ else
+ m_tokenStack.push(id2);
+
+ return Token(keyword->token);
+ }
+ else
+ {
+ /* Such that we tokenize the second token in "empty greatest". */
+ if(keyword->token != EMPTY)
+ setState(Default);
+ }
+
+ if(keyword->token == AS || keyword->token == CASE)
+ setState(ItemType);
+
+ return Token(keyword->token);
+ }
+ else
+ return id;
+ }
+
+ Q_ASSERT(state() == Default || state() == Axis || state() == AfterAxisSeparator);
+
+ /*
+ * This is hard. Consider this:
+ *
+ * Valid: child ::nameTest
+ * Valid: child:: nameTest
+ * Syntax Error: child :localName
+ * Syntax Error: child: localName
+ *
+ * Consider "child ::name". Right now, we're here:
+ * ^
+ * We don't know whether "child" is a prefix and hence the whitespace is invalid,
+ * or whether it's an axis and hence skippable. */
+ {
+ const int wsLength = peekForColonColon();
+ /* We cannot call handleWhitespace() because it returns on
+ * END_OF_FILE, and we have parsed up keyword, and we need to
+ * deal with that.
+ *
+ * If we have a colon colon, which means the whitespace is
+ * allowed, we skip it. */
+ if(wsLength != -1)
+ m_pos += wsLength;
+ }
+
+ /* Handle name tests. */
+ if(peekCurrent() == ':')
+ {
+ switch(peekAhead())
+ {
+ case '=':
+ return id;
+ case '*':
+ {
+ m_pos += 2;
+ return tokenAndChangeState(ANY_LOCAL_NAME, id.value, Operator);
+ }
+ case ':':
+ {
+ /* We have an axis. */
+ setState(Axis);
+ return keyword ? Token(keyword->token) : id;
+ }
+ default:
+ {
+ /* It's a QName. */
+ ++m_pos; /* Consume the colon. */
+
+ const Token id2(tokenizeNCName());
+
+ if(id2.type != NCNAME)
+ {
+ --m_pos;
+ return id;
+ }
+
+ setState(Operator);
+ const int qNameLen = id.value.length() + id2.value.length() + 1;
+ return Token(QNAME, m_data.mid(m_pos - qNameLen, qNameLen));
+ }
+ }
+ }
+
+ if(!keyword || isOperatorKeyword(keyword->token))
+ {
+ setState(Operator);
+ return id;
+ }
+
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR) // TODO this should test for success. Write test.
+ return Token(ERROR);
+
+ if(atEnd())
+ {
+ setState(Operator);
+ return id;
+ }
+
+ /* Let the if-body apply for constructors, and node type tests. */
+ if(isTypeToken(keyword->token) ||
+ keyword->token == TYPESWITCH ||
+ keyword->token == ORDERED ||
+ keyword->token == UNORDERED ||
+ keyword->token == IF)
+ {
+ switch(peekCurrent())
+ {
+ case '(':
+ {
+ // TODO See if we can remove DOCUMENT from isTypeToken.
+ if(isTypeToken(keyword->token) && keyword->token != DOCUMENT)
+ {
+ m_tokenStack.push(Token(LPAREN));
+ ++m_pos; /* Consume '('. */
+ pushState(Operator);
+
+ if(keyword->token == PROCESSING_INSTRUCTION)
+ setState(KindTestForPI);
+ else
+ setState(KindTest);
+
+ return Token(keyword->token);
+ }
+ else if(keyword->token == TYPESWITCH || keyword->token == IF)
+ return Token(keyword->token);
+ else /* It's a function call. */
+ return id;
+ }
+ case '{':
+ {
+ m_tokenStack.push(Token(CURLY_LBRACE));
+ ++m_pos; /* Consume '{'. */
+ pushState(Operator);
+ /* Stay in state Default. */
+ return Token(keyword->token);
+ }
+ default:
+ {
+ /* We have read in a token which is for instance
+ * "return", and now it can be an element
+ * test("element") a node kind test("element()"), or a
+ * computed element constructor("element name {...").
+ * We need to do a two-token lookahead here, because
+ * "element return" can be an element test followed by
+ * the return keyword, but it can also be an element
+ * constructor("element return {"). */
+ if(isNCNameStart(current()))
+ {
+ const int currentPos = m_pos;
+ const Token token2 = tokenizeNCNameOrQName();
+
+ if(token2.hasError())
+ return token2;
+
+ handleWhitespace();
+
+ if(peekCurrent() == '{')
+ {
+ /* An element constructor. */
+ m_tokenStack.push(token2);
+ return Token(keyword->token);
+ }
+
+ /* We jump back in the stream, we need to tokenize token2 according
+ * to the state. */
+ m_pos = currentPos;
+ setState(Operator);
+ return Token(NCNAME, QLatin1String(keyword->name));
+ }
+ }
+ }
+ }
+
+ if(peekCurrent() == '$')
+ {
+ setState(VarName);
+ return Token(keyword->token);
+ }
+
+ /* It's not a node type, it's not the typeswitch expression, but it is a function callsite. */
+ if(peekCurrent() == '(')
+ return id;
+ else if(peekCurrent() == '{' && keyword->token == VALIDATE)
+ return Token(keyword->token);
+
+ if(!isNCNameStart(current()))
+ {
+ setState(Operator);
+ return id;
+ }
+
+ const Token id2(tokenizeNCName());
+ const TokenMap *const keyword2 = lookupKeyword(id2.value);
+
+ if(!keyword2)
+ {
+ /* It's a syntax error. All cases of two subsequent ncnames are keywords(e.g, declarations). */
+ setState(Operator);
+ return id;
+ }
+
+ switch(keyword->token)
+ {
+ case DECLARE:
+ {
+ switch(keyword2->token)
+ {
+ case VARIABLE:
+ /* Fallthrough. */
+ case FUNCTION:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return Token(keyword->token);
+ }
+ case OPTION:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return Token(keyword->token);
+ }
+ case COPY_NAMESPACES:
+ /* Fallthrough. */
+ case ORDERING:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(NamespaceKeyword);
+ return Token(keyword->token);
+ }
+ case CONSTRUCTION:
+ {
+ // TODO identical to CONSTRUCTION?
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Operator);
+ return Token(keyword->token);
+ }
+ case NAMESPACE:
+ /* Fallthrough. */
+ case BASEURI:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(NamespaceDecl);
+ return Token(keyword->token);
+ }
+ case BOUNDARY_SPACE:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(XMLSpaceDecl);
+ return Token(keyword->token);
+ }
+ case DEFAULT:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ const TokenType ws2 = consumeWhitespace();
+ if(ws2 != SUCCESS)
+ {
+ m_tokenStack.prepend(Token(ws2));
+ return Token(keyword->token);
+ }
+
+ const Token id3(tokenizeNCName());
+
+ if(id3.type != NCNAME)
+ {
+ m_tokenStack.prepend(id3);
+ return Token(keyword->token);
+ }
+
+ const TokenMap *const keyword3 = lookupKeyword(id3.value);
+ if(!keyword3)
+ {
+ m_tokenStack.prepend(id3);
+ return Token(keyword->token);
+ }
+ else
+ {
+ m_tokenStack.prepend(Token(keyword3->token));
+
+ if(keyword3->token == ORDER)
+ setState(Operator);
+ else
+ setState(NamespaceDecl);
+ }
+
+ return Token(keyword->token);
+ }
+ default:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Default);
+ return id;
+ }
+ }
+ }
+ case XQUERY:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ if(keyword2->token == VERSION)
+ {
+ setState(NamespaceDecl);
+ return Token(keyword->token);
+ }
+ else
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ case IMPORT:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ switch(keyword2->token)
+ {
+ case SCHEMA:
+ /* Fallthrough. */
+ case MODULE:
+ {
+ setState(NamespaceKeyword);
+ return Token(keyword->token);
+ }
+ default:
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ }
+ case VALIDATE:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+
+ switch(keyword2->token)
+ {
+ case LAX:
+ case STRICT:
+ {
+ pushState(Operator);
+ return Token(keyword->token);
+ }
+ default:
+ {
+ setState(Operator);
+ return id;
+ }
+ }
+ }
+ default:
+ {
+ m_tokenStack.push(Token(keyword2->token));
+ setState(Operator);
+ return id;
+ }
+ }
+
+ Q_ASSERT(false);
+
+ }
+ case VarName:
+ {
+ if(peekCurrent() == '$')
+ return tokenAndAdvance(DOLLAR);
+
+ setState(Operator);
+ return tokenizeNCNameOrQName();
+ Q_ASSERT(false);
+ }
+ case ItemType:
+ {
+ switch(peekCurrent())
+ {
+ case '(':
+ return tokenAndChangeState(LPAREN, KindTest);
+ case '$':
+ return tokenAndChangeState(DOLLAR, VarName);
+ }
+
+ const Token name(tokenizeNCNameOrQName());
+
+ if(name.hasError())
+ return error();
+
+ else if(name.type == QNAME)
+ {
+ setState(OccurrenceIndicator);
+ return name;
+ }
+ else
+ {
+ const TokenMap *const keyword = lookupKeyword(name.value);
+
+ if(keyword)
+ {
+ pushState(OccurrenceIndicator);
+ return Token(keyword->token);
+ }
+ else
+ {
+ setState(Default);
+ return name;
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case KindTest:
+ {
+ switch(peekCurrent())
+ {
+ case ')':
+ {
+ popState();
+ return tokenAndAdvance(RPAREN);
+ }
+ case '(':
+ return tokenAndAdvance(LPAREN);
+ case ',':
+ return tokenAndAdvance(COMMA);
+ case '*':
+ return tokenAndAdvance(STAR);
+ case '?':
+ return tokenAndAdvance(QUESTION);
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ }
+
+ const Token nc(tokenizeNCNameOrQName());
+ if(nc.hasError())
+ return nc;
+
+ const TokenType ws = consumeWhitespace();
+ if(ws == ERROR)
+ return error();
+
+ if(peekCurrent() == '(')
+ {
+ const TokenMap *const keyword = lookupKeyword(nc.value);
+ if(keyword)
+ {
+ pushState(KindTest);
+ return Token(keyword->token);
+ }
+ else
+ return nc;
+ }
+ else
+ return nc;
+ Q_ASSERT(false);
+ }
+ case KindTestForPI:
+ {
+ switch(peekCurrent())
+ {
+ case ')':
+ {
+ popState();
+ return tokenAndAdvance(RPAREN);
+ }
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ default:
+ return tokenizeNCName();
+ }
+ Q_ASSERT(false);
+ }
+ case OccurrenceIndicator:
+ {
+ switch(peekCurrent())
+ {
+ case '?':
+ return tokenAndChangeState(QUESTION, Operator);
+ case '*':
+ return tokenAndChangeState(STAR, Operator);
+ case '+':
+ return tokenAndChangeState(PLUS, Operator);
+ default:
+ {
+ setState(Operator);
+ return nextToken();
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case XQueryVersion:
+ {
+ switch(peekCurrent())
+ {
+ case '\'':
+ /* Fallthrough. */
+ case '"':
+ return tokenizeStringLiteral();
+ case ';':
+ return tokenAndChangeState(SEMI_COLON, Default);
+ }
+
+ const Token id(tokenizeNCName());
+
+ if(id.type != NCNAME)
+ return id;
+
+ const TokenMap *const keyword = lookupKeyword(id.value);
+ if(keyword)
+ return tokenAndChangeState(keyword->token, Default);
+ else
+ return id;
+ Q_ASSERT(false);
+ }
+ case StartTag:
+ {
+ if(peekAhead(-1) == '<')
+ {
+ if(current().isSpace())
+ return Token(ERROR);
+ }
+ else
+ {
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+ }
+
+ switch(peekCurrent())
+ {
+ case '/':
+ {
+ if(peekAhead() == '>')
+ {
+ m_pos += 2;
+
+ if(m_scanOnly)
+ return Token(POSITION_SET);
+ else
+ {
+ popState();
+ return Token(QUICK_TAG_END);
+ }
+ }
+ else
+ return error();
+ }
+ case '>':
+ {
+ if(m_scanOnly)
+ return tokenAndChangeState(POSITION_SET, StartTag);
+ else
+ return tokenAndChangeState(G_GT, ElementContent);
+ }
+ case '=':
+ return tokenAndAdvance(G_EQ);
+ case '\'':
+ return tokenAndChangeState(APOS, AposAttributeContent);
+ case '"':
+ return tokenAndChangeState(QUOTE, QuotAttributeContent);
+ default:
+ return tokenizeNCNameOrQName();
+ }
+ Q_ASSERT(false);
+ }
+ case AposAttributeContent:
+ /* Fallthrough. */
+ case QuotAttributeContent:
+ {
+ const QChar sep(state() == AposAttributeContent ? QLatin1Char('\'') : QLatin1Char('"'));
+ QString result;
+ result.reserve(20);
+
+ if(m_scanOnly)
+ {
+ int stack = 0;
+ return attributeAsRaw(sep, stack, m_pos, true, result);
+ }
+
+ Q_ASSERT(!m_scanOnly);
+ while(true)
+ {
+ if(atEnd())
+ {
+ /* In the case that the XSL-T tokenizer invokes us with
+ * default state QuotAttributeContent, we need to be able
+ * to return a single string, in case that is all we have
+ * accumulated. */
+ if(result.isEmpty())
+ return Token(END_OF_FILE);
+ else
+ return Token(STRING_LITERAL, result);
+ }
+
+ const QChar curr(current());
+
+ if(curr == sep)
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+
+ if(m_data.at(m_pos + 1) == sep)
+ {
+ /* The quoting mechanism was used. */
+ m_pos += 2;
+ result.append(sep);
+ continue;
+ }
+
+ const QChar next(m_data.at(m_pos + 1));
+ if(!next.isSpace() && next != QLatin1Char('/') && next != QLatin1Char('>'))
+ return Token(ERROR); // i18n Space must separate attributes
+ else if(result.isEmpty())
+ {
+ return tokenAndChangeState(state() == AposAttributeContent ? APOS : QUOTE,
+ StartTag, 1);
+ }
+ else
+ {
+ /* Don't consume the sep, but leave it so we next time return a token for it. */
+ return Token(STRING_LITERAL, result);
+ }
+
+ ++m_pos;
+ continue;
+ }
+ else if(curr == QLatin1Char('{'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '{')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('{'));
+ }
+ else
+ {
+ if(result.isEmpty())
+ {
+ /* The Attribute Value Template appeared directly in the attribute. */
+ pushState();
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ else
+ {
+ /* We don't advance, keep '{' as next token. */
+ return Token(STRING_LITERAL, result);
+ }
+ }
+ }
+ else if(curr == QLatin1Char('}'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '}')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('}'));
+ }
+ else
+ return Token(ERROR);
+ }
+ else if(curr == QLatin1Char('&'))
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ result.append(ret);
+ }
+ else if(curr == QLatin1Char('<'))
+ return Token(STRING_LITERAL, result);
+ else
+ {
+ /* See Extensible Markup Language (XML) 1.0 (Fourth Edition),
+ * 3.3.3 Attribute-Value Normalization.
+ *
+ * However, it is complicated a bit by that AVN is defined on top of
+ * EOL normalization and we do those two in one go here. */
+ switch(curr.unicode())
+ {
+ case 0xD:
+ {
+ if(peekAhead() == '\n')
+ {
+ result.append(QLatin1Char(' '));
+ ++m_pos;
+ break;
+ }
+ }
+ case 0xA:
+ /* Fallthrough. */
+ case 0x9:
+ {
+ result.append(QLatin1Char(' '));
+ break;
+ }
+ default:
+ result.append(curr);
+ }
+ }
+
+ ++m_pos;
+ }
+ Q_ASSERT(false);
+ }
+ case ElementContent:
+ {
+ QString result;
+ result.reserve(20);
+
+ /* Whether the text node, result, may be whitespace only. Character references
+ * and CDATA sections disables that. */
+ bool mayBeWS = true;
+
+ CharacterSkips skipEOLNormalization;
+
+ while(true)
+ {
+ if(atEnd())
+ return Token(END_OF_FILE);
+
+ switch(peekCurrent())
+ {
+ case '<':
+ {
+ if(!result.isEmpty() && peekAhead(2) != '[')
+ {
+ /* We encountered the end, and it was not a CDATA section. */
+ /* We don't advance. Next time we'll handle the <... stuff. */
+ return Token(mayBeWS ? STRING_LITERAL : NON_BOUNDARY_WS, normalizeEOL(result, skipEOLNormalization));
+ }
+
+ ++m_pos;
+ if(atEnd())
+ return Token(END_OF_FILE);
+
+ const QChar ahead(current());
+ if(ahead.isSpace())
+ return error();
+ else if(ahead == QLatin1Char('/'))
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(m_data.at(m_pos + 1).isSpace())
+ return error();
+ else
+ return tokenAndChangeState(BEGIN_END_TAG, EndTag);
+ }
+ else if(isNCNameStart(ahead))
+ {
+ pushState();
+ return tokenAndChangeState(G_LT, StartTag, 0);
+ }
+ else if(aheadEquals("!--", 3, 0))
+ {
+ pushState();
+ m_pos += 3;
+ return tokenAndChangeState(COMMENT_START, XMLComment, 0);
+ }
+ else if(aheadEquals("![CDATA[", 8, 0))
+ {
+ mayBeWS = false;
+ m_pos += 8;
+ const int start = m_pos;
+ const int len = scanUntil("]]>");
+
+ if(len == -1)
+ return Token(END_OF_FILE);
+
+ m_pos += 2; /* Consume "]]>". Note that m_pos is on '!'. */
+ result.append(m_data.mid(start, len));
+ break;
+ }
+ else if(ahead == QLatin1Char('?'))
+ {
+ pushState();
+ return tokenAndChangeState(PI_START, ProcessingInstructionName);
+ }
+ else
+ return Token(G_LT);
+ }
+ case '&':
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ {
+ skipEOLNormalization.insert(result.count());
+ result.append(ret);
+ mayBeWS = false;
+ break;
+ }
+ }
+ case '{':
+ {
+ // TODO remove this check, also below.
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '{')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('{'));
+ }
+ else
+ {
+ if(result.isEmpty())
+ {
+ pushState();
+ return tokenAndChangeState(CURLY_LBRACE, Default);
+ }
+ else
+ {
+ /* We don't advance here. */
+ return Token(mayBeWS ? STRING_LITERAL : NON_BOUNDARY_WS, normalizeEOL(result, skipEOLNormalization));
+ }
+ }
+ break;
+ }
+ case '}':
+ {
+ if(m_pos + 1 == m_length)
+ return Token(END_OF_FILE);
+ else if(peekAhead() == '}')
+ {
+ ++m_pos;
+ result.append(QLatin1Char('}'));
+ }
+ else
+ {
+ /* This is a parse error, and the grammar won't be able
+ * to reduce this CURLY_RBRACE. */
+ return tokenAndChangeState(CURLY_RBRACE, Default);
+ }
+ break;
+ }
+ case '\n':
+ {
+ /* We want to translate \r\n into \n. */
+ if(peekAhead(-1) == '\r')
+ break;
+ /* else, fallthrough. */
+ }
+ case '\r':
+ {
+ result.append(QLatin1Char('\n'));
+ break;
+ }
+ default:
+ {
+ result.append(current());
+ break;
+ }
+ }
+ ++m_pos;
+ }
+ Q_ASSERT(false);
+ }
+ case ProcessingInstructionName:
+ {
+ const int start = m_pos;
+
+ while(true)
+ {
+ ++m_pos;
+ if(m_pos >= m_length)
+ return Token(END_OF_FILE);
+
+ const QChar next(current());
+ if(next.isSpace() || next == QLatin1Char('?'))
+ {
+ return tokenAndChangeState(PI_TARGET, m_data.mid(start, m_pos - start),
+ ProcessingInstructionContent);
+ }
+ }
+ Q_ASSERT(false);
+ }
+ case ProcessingInstructionContent:
+ {
+ /* Consume whitespace between the name and the content. */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ const int start = m_pos;
+ const int len = scanUntil("?>");
+
+ if(len == -1)
+ return Token(END_OF_FILE);
+ else
+ {
+ m_pos += 2; /* Consume "?>" */
+ popState();
+ return Token(PI_CONTENT, normalizeEOL(m_data.mid(start, len), CharacterSkips()));
+ }
+ Q_ASSERT(false);
+ }
+ case EndTag:
+ {
+ if(consumeRawWhitespace())
+ return END_OF_FILE;
+
+ if(peekCurrent() == '>')
+ {
+ popState();
+ return tokenAndAdvance(G_GT);
+ }
+ else
+ return tokenizeNCNameOrQName();
+ Q_ASSERT(false);
+ }
+ case XMLComment:
+ {
+ const int start = m_pos;
+ const int len = scanUntil("--");
+
+ if(len == -1)
+ return END_OF_FILE;
+ else
+ {
+ m_pos += 2; /* Consume "--". */
+ popState();
+
+ if(peekCurrent() == '>')
+ {
+ ++m_pos;
+ return Token(COMMENT_CONTENT, normalizeEOL(m_data.mid(start, len), CharacterSkips()));
+ }
+ else
+ return error();
+ }
+ Q_ASSERT(false);
+ }
+ case Pragma:
+ {
+ /* Consume whitespace. */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ setState(PragmaContent);
+ return tokenizeNCNameOrQName();
+ }
+ case PragmaContent:
+ {
+ QString result;
+ result.reserve(20);
+
+ const bool hasWS = m_pos < m_length && current().isSpace();
+
+ /* Consume all whitespace up to the pragma content(if any). */
+ if(consumeRawWhitespace())
+ return Token(END_OF_FILE);
+
+ if(peekCurrent() == '#' && peekAhead() == ')')
+ {
+ /* We reached the end, and there's no pragma content. */
+ return tokenAndChangeState(PRAGMA_END, Default, 2);
+ }
+ else if(!hasWS)
+ {
+ /* A separating space is required if there's pragma content. */
+ return error(); /* i18n */
+ }
+
+ const int start = m_pos;
+ const int len = scanUntil("#)");
+ if(len == -1)
+ return Token(END_OF_FILE);
+
+ return Token(STRING_LITERAL, m_data.mid(start, len));
+ Q_ASSERT(false);
+ }
+ }
+
+ Q_ASSERT(false);
+ return error();
+}
+
+Tokenizer::Token XQueryTokenizer::attributeAsRaw(const QChar sep,
+ int &sepStack,
+ const int startPos,
+ const bool aInLiteral,
+ QString &result)
+{
+ bool inLiteral = aInLiteral;
+ const char otherSep = (sep == QLatin1Char('"') ? '\'' : '"');
+
+ while(true)
+ {
+ if(atEnd())
+ return END_OF_FILE;
+
+ if(peekCurrent() == sep.unicode())
+ {
+ if(inLiteral)
+ inLiteral = false;
+ else
+ inLiteral = true;
+
+ if(peekAhead() == sep.unicode())
+ {
+ /* The quoting mechanism was used. */
+ result.append(current());
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ /* Don't consume the separator, such that we
+ * return a token for it next time. */
+ if(m_pos == startPos)
+ {
+ ++m_pos;
+ setState(StartTag);
+ return Token(sep == QLatin1Char('"') ? QUOTE : APOS);
+ }
+
+
+ if(sepStack == 0)
+ {
+ return Token(STRING_LITERAL, result);
+ }
+ else
+ {
+ result.append(current());
+ ++m_pos;
+ continue;
+ }
+ }
+ }
+ else if(peekCurrent() == '&')
+ {
+ const QString ret(tokenizeCharacterReference());
+ if(ret.isNull())
+ return Token(ERROR);
+ else
+ {
+ result.append(ret);
+ ++m_pos;
+ continue;
+ }
+ }
+ else if(peekCurrent() == otherSep)
+ {
+ result.append(current());
+ ++m_pos;
+
+ if(peekCurrent() == otherSep)
+ ++m_pos;
+
+ if(inLiteral)
+ inLiteral = false;
+ else
+ inLiteral = true;
+
+ continue;
+ }
+ else if(peekCurrent() == '{')
+ {
+ result.append(current());
+
+ if(peekAhead() == '{')
+ {
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ ++m_pos;
+ ++sepStack;
+ const Token t(attributeAsRaw(sep, sepStack, startPos, false, result));
+ if(t.type != SUCCESS)
+ return t;
+ }
+
+ }
+ else if(peekCurrent() == '}')
+ {
+ if(inLiteral && peekAhead() == '}')
+ {
+ result.append(current());
+ m_pos += 2;
+ continue;
+ }
+ else
+ {
+ ++m_pos;
+ --sepStack;
+ return Token(SUCCESS); /* The return value is arbitrary. */
+ }
+ }
+ else
+ {
+ result.append(current());
+ ++m_pos;
+ }
+ }
+}
+
+Tokenizer::Token XQueryTokenizer::nextToken(YYLTYPE *const sourceLocator)
+{
+ sourceLocator->first_line = m_line;
+ sourceLocator->first_column = m_pos - m_columnOffset + 1; /* Plus 1, since m_pos is 0-based. */
+
+ if(m_tokenStack.isEmpty())
+ return nextToken();
+ else
+ {
+ const Token retval(m_tokenStack.pop());
+
+ switch(retval.type)
+ {
+ case MODULE:
+ /* Fallthrough.*/
+ case SCHEMA:
+ /* Fallthrough.*/
+ case COPY_NAMESPACES:
+ {
+ setState(NamespaceKeyword);
+ break;
+ }
+ case VERSION:
+ {
+ setState(XQueryVersion);
+ break;
+ }
+ case AS:
+ /* Fallthrough. */
+ case OF:
+ {
+ setState(ItemType);
+ break;
+ }
+ default:
+ {
+ if(isOperatorKeyword(retval.type))
+ setState(Default);
+
+ break;
+ }
+ };
+
+ return retval;
+ }
+}
+
+int XQueryTokenizer::commenceScanOnly()
+{
+ m_scanOnly = true;
+ return m_pos;
+}
+
+void XQueryTokenizer::resumeTokenizationFrom(const int pos)
+{
+ m_scanOnly = false;
+ m_pos = pos;
+}
+
+void XQueryTokenizer::setParserContext(const ParserContext::Ptr &)
+{
+}
+
+#undef handleWhitespace
+
+} // namespace QPatternist
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/parser/qxquerytokenizer_p.h b/src/xmlpatterns/parser/qxquerytokenizer_p.h
new file mode 100644
index 0000000..36611ef
--- /dev/null
+++ b/src/xmlpatterns/parser/qxquerytokenizer_p.h
@@ -0,0 +1,332 @@
+/****************************************************************************
+**
+** 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_XQueryTokenizer_H
+#define Patternist_XQueryTokenizer_H
+
+#include <QHash>
+#include <QSet>
+#include <QStack>
+#include <QString>
+#include <QUrl>
+
+#include "qtokenizer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ struct TokenMap;
+
+ /**
+ * @short A hand-written tokenizer which tokenizes XQuery 1.0 & XPath 2.0,
+ * and delivers tokens to the Bison generated parser.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class XQueryTokenizer : public Tokenizer
+ {
+ public:
+ /**
+ * Tokenizer states. Organized alphabetically.
+ */
+ enum State
+ {
+ AfterAxisSeparator,
+ AposAttributeContent,
+ Axis,
+ Default,
+ ElementContent,
+ EndTag,
+ ItemType,
+ KindTest,
+ KindTestForPI,
+ NamespaceDecl,
+ NamespaceKeyword,
+ OccurrenceIndicator,
+ Operator,
+ Pragma,
+ PragmaContent,
+ ProcessingInstructionContent,
+ ProcessingInstructionName,
+ QuotAttributeContent,
+ StartTag,
+ VarName,
+ XMLComment,
+ XMLSpaceDecl,
+ XQueryVersion
+ };
+
+ XQueryTokenizer(const QString &query,
+ const QUrl &location,
+ const State startingState = Default);
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+ virtual int commenceScanOnly();
+ virtual void resumeTokenizationFrom(const int position);
+
+ /**
+ * Does nothing.
+ */
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ private:
+
+ /**
+ * Returns the character corresponding to the builtin reference @p
+ * reference. For instance, passing @c gt will give you '>' in return.
+ *
+ * If @p reference is an invalid character reference, a null QChar is
+ * returned.
+ *
+ * @see QChar::isNull()
+ */
+ QChar charForReference(const QString &reference);
+
+ inline Token tokenAndChangeState(const TokenType code,
+ const State state,
+ const int advance = 1);
+ inline Token tokenAndChangeState(const TokenType code,
+ const QString &value,
+ const State state);
+ inline Token tokenAndAdvance(const TokenType code,
+ const int advance = 1);
+ QString tokenizeCharacterReference();
+
+ inline Token tokenizeStringLiteral();
+ inline Token tokenizeNumberLiteral();
+
+ /**
+ * @returns the character @p length characters from the current
+ * position.
+ */
+ inline char peekAhead(const int length = 1) const;
+
+ /**
+ * @returns whether the stream, starting from @p offset from the
+ * current position, matches @p chs. The length of @p chs is @p len.
+ */
+ inline bool aheadEquals(const char *const chs,
+ const int len,
+ const int offset = 1) const;
+
+ inline Token tokenizeNCName();
+ static inline bool isOperatorKeyword(const TokenType);
+
+ static inline bool isDigit(const char ch);
+ static inline Token error();
+ inline TokenType consumeWhitespace();
+
+ /**
+ * @short Returns the character at the current position, converted to
+ * @c ASCII.
+ *
+ * Equivalent to calling:
+ *
+ * @code
+ * current().toAscii();
+ * @endcode
+ */
+ inline char peekCurrent() const;
+
+ /**
+ * Disregarding encoding conversion, equivalent to calling:
+ *
+ * @code
+ * peekAhead(0);
+ * @endcode
+ */
+ inline const QChar current() const;
+
+ /**
+ * @p hadWhitespace is always set to a proper value.
+ *
+ * @returns the length of whitespace scanned before reaching "::", or
+ * -1 if something else was found.
+ */
+ int peekForColonColon() const;
+
+ static inline bool isNCNameStart(const QChar ch);
+ static inline bool isNCNameBody(const QChar ch);
+ static inline const TokenMap *lookupKeyword(const QString &keyword);
+ inline void popState();
+ inline void pushState(const State state);
+ inline State state() const;
+ inline void setState(const State s);
+ static bool isTypeToken(const TokenType t);
+
+ inline Token tokenizeNCNameOrQName();
+ /**
+ * Advances m_pos until content is encountered.
+ *
+ * Returned is the length stretching from m_pos when starting, until
+ * @p content is encountered. @p content is not included in the length.
+ */
+ int scanUntil(const char *const content);
+
+ /**
+ * Same as calling:
+ * @code
+ * pushState(currentState());
+ * @endcode
+ */
+ inline void pushState();
+
+ /**
+ * Consumes only whitespace, in the traditional sense. The function exits
+ * if non-whitespace is encountered, such as the start of a comment.
+ *
+ * @returns @c true if the end was reached, otherwise @c false
+ */
+ inline bool consumeRawWhitespace();
+
+ /**
+ * @short Parses comments: <tt>(: comment content :)</tt>. It recurses for
+ * parsing nested comments.
+ *
+ * It is assumed that the start token for the comment, "(:", has
+ * already been parsed.
+ *
+ * Typically, don't call this function, but ignoreWhitespace().
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#comments">XML Path Language (XPath)
+ * 2.0, 2.6 Comments</a>
+ * @returns
+ * - SUCCESS if everything went ok
+ * - ERROR if there was an error in parsing one or more comments
+ * - END_OF_FILE if the end was reached
+ */
+ Tokenizer::TokenType consumeComment();
+
+ /**
+ * Determines whether @p code is a keyword
+ * that is followed by a second keyword. For instance <tt>declare
+ * function</tt>.
+ */
+ static inline bool isPhraseKeyword(const TokenType code);
+
+ /**
+ * A set of indexes into a QString, the one being passed to
+ * normalizeEOL() whose characters shouldn't be normalized. */
+ typedef QSet<int> CharacterSkips;
+
+ /**
+ * Returns @p input, normalized according to
+ * <a href="http://www.w3.org/TR/xquery/#id-eol-handling">XQuery 1.0:
+ * An XML Query Language, A.2.3 End-of-Line Handling</a>
+ */
+ static QString normalizeEOL(const QString &input,
+ const CharacterSkips &characterSkips);
+
+ inline bool atEnd() const
+ {
+ return m_pos == m_length;
+ }
+
+ Token nextToken();
+ /**
+ * Instead of recognizing and tokenizing embedded expressions in
+ * direct attriute constructors, this function is essentially a mini
+ * recursive-descent parser that has the necessary logic to recognize
+ * embedded expressions and their potentially interfering string literals, in
+ * order to scan to the very end of the attribute value, and return the
+ * whole as a string.
+ *
+ * There is of course syntax errors this function will not detect, but
+ * that is ok since the attributes will be parsed once more.
+ *
+ * An inelegant solution, but which gets the job done.
+ *
+ * @see commenceScanOnly(), resumeTokenizationFrom()
+ */
+ Token attributeAsRaw(const QChar separator,
+ int &stack,
+ const int startPos,
+ const bool inLiteral,
+ QString &result);
+
+ const QString m_data;
+ const int m_length;
+ State m_state;
+ QStack<State> m_stateStack;
+ int m_pos;
+
+ /**
+ * The current line number.
+ *
+ * The line number and column number both starts at 1.
+ */
+ int m_line;
+
+ /**
+ * The offset into m_length for where
+ * the current column starts. So m_length - m_columnOffset
+ * is the current column.
+ *
+ * The line number and column number both starts at 1.
+ */
+ int m_columnOffset;
+
+ const NamePool::Ptr m_namePool;
+ QStack<Token> m_tokenStack;
+ QHash<QString, QChar> m_charRefs;
+ bool m_scanOnly;
+
+ Q_DISABLE_COPY(XQueryTokenizer)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qxslttokenizer.cpp b/src/xmlpatterns/parser/qxslttokenizer.cpp
new file mode 100644
index 0000000..81498ce
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer.cpp
@@ -0,0 +1,2717 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#include <QStringList>
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qquerytransformparser_p.h"
+#include "qxquerytokenizer_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qxslttokenizer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Tokenizer::Token SingleTokenContainer::nextToken(YYLTYPE *const location)
+{
+ if(m_hasDelivered)
+ return Tokenizer::Token(END_OF_FILE);
+ else
+ {
+ *location = m_location;
+ m_hasDelivered = true;
+ return m_token;
+ }
+}
+
+XSLTTokenizer::XSLTTokenizer(QIODevice *const queryDevice,
+ const QUrl &location,
+ const ReportContext::Ptr &context,
+ const NamePool::Ptr &np) : Tokenizer(location)
+ , MaintainingReader<XSLTTokenLookup>(createElementDescriptions(), createStandardAttributes(), context, queryDevice)
+ , m_location(location)
+ , m_namePool(np)
+ /* We initialize after all name constants. */
+ , m_validationAlternatives(createValidationAlternatives())
+ , m_parseInfo(0)
+{
+ Q_ASSERT(m_namePool);
+
+ pushState(OutsideDocumentElement);
+}
+
+bool XSLTTokenizer::isAnyAttributeAllowed() const
+{
+ return m_processingMode.top() == ForwardCompatible;
+}
+
+void XSLTTokenizer::setParserContext(const ParserContext::Ptr &parseInfo)
+{
+ m_parseInfo = parseInfo;
+}
+
+void XSLTTokenizer::validateElement() const
+{
+ MaintainingReader<XSLTTokenLookup>::validateElement(currentElementName());
+}
+
+QSet<XSLTTokenizer::NodeName> XSLTTokenizer::createStandardAttributes()
+{
+ QSet<NodeName> retval;
+ enum
+ {
+ ReservedForAttributes = 6
+ };
+
+ retval.reserve(6);
+
+ retval.insert(DefaultCollation);
+ retval.insert(ExcludeResultPrefixes);
+ retval.insert(ExtensionElementPrefixes);
+ retval.insert(UseWhen);
+ retval.insert(Version);
+ retval.insert(XpathDefaultNamespace);
+
+ Q_ASSERT(retval.count() == ReservedForAttributes);
+
+ return retval;
+}
+
+ElementDescription<XSLTTokenLookup>::Hash XSLTTokenizer::createElementDescriptions()
+{
+ ElementDescription<XSLTTokenLookup>::Hash result;
+ enum
+ {
+ ReservedForElements = 40
+ };
+ result.reserve(ReservedForElements);
+
+ /* xsl:apply-templates */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ApplyTemplates];
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Mode);
+ }
+
+ /* xsl:template */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Template];
+ e.optionalAttributes.insert(Match);
+ e.optionalAttributes.insert(Name);
+ e.optionalAttributes.insert(Mode);
+ e.optionalAttributes.insert(Priority);
+ e.optionalAttributes.insert(As);
+ }
+
+ /* xsl:text, xsl:choose and xsl:otherwise */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Text];
+ result.insert(Choose, e);
+ result.insert(Otherwise, e);
+ }
+
+ /* xsl:stylesheet */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Stylesheet];
+
+ e.requiredAttributes.insert(Version);
+
+ e.optionalAttributes.insert(Id);
+ e.optionalAttributes.insert(ExtensionElementPrefixes);
+ e.optionalAttributes.insert(ExcludeResultPrefixes);
+ e.optionalAttributes.insert(XpathDefaultNamespace);
+ e.optionalAttributes.insert(DefaultValidation);
+ e.optionalAttributes.insert(DefaultCollation);
+ e.optionalAttributes.insert(InputTypeAnnotations);
+ }
+
+ /* xsl:transform */
+ {
+ result[Transform] = result[Stylesheet];
+ }
+
+ /* xsl:value-of */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ValueOf];
+ e.optionalAttributes.insert(Separator);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:variable */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Variable];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ }
+
+ /* xsl:when & xsl:if */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[When];
+
+ e.requiredAttributes.insert(Test);
+
+ result.insert(If, e);
+ }
+
+ /* xsl:sequence, xsl:for-each */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Sequence];
+
+ e.requiredAttributes.insert(Select);
+
+ result.insert(ForEach, e);
+ }
+
+ /* xsl:comment */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[XSLTTokenLookup::Comment];
+
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:processing-instruction */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[XSLTTokenLookup::ProcessingInstruction];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:document */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Document];
+
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:element */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Element];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(InheritNamespaces);
+ e.optionalAttributes.insert(UseAttributeSets);
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:attribute */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Attribute];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Separator);
+ e.optionalAttributes.insert(Validation);
+ e.optionalAttributes.insert(Type);
+ }
+
+ /* xsl:function */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Function];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Override);
+ }
+
+ /* xsl:param */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Param];
+
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Required);
+ e.optionalAttributes.insert(Tunnel);
+ }
+
+ /* xsl:namespace */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Namespace];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(Select);
+ }
+
+ /* xsl:call-template */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[CallTemplate];
+ e.requiredAttributes.insert(Name);
+ }
+
+ /* xsl:perform-sort */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[PerformSort];
+ e.requiredAttributes.insert(Select);
+ }
+
+ /* xsl:sort */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Sort];
+
+ e.optionalAttributes.reserve(7);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Lang);
+ e.optionalAttributes.insert(Order);
+ e.optionalAttributes.insert(Collation);
+ e.optionalAttributes.insert(Stable);
+ e.optionalAttributes.insert(CaseOrder);
+ e.optionalAttributes.insert(DataType);
+ }
+
+ /* xsl:import-schema */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ImportSchema];
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(Namespace);
+ e.optionalAttributes.insert(SchemaLocation);
+ }
+
+ /* xsl:message */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Message];
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(Terminate);
+ }
+
+ /* xsl:copy-of */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[CopyOf];
+
+ e.requiredAttributes.insert(Select);
+
+ e.optionalAttributes.reserve(2);
+ e.optionalAttributes.insert(CopyNamespaces);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:copy */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Copy];
+
+ e.optionalAttributes.reserve(5);
+ e.optionalAttributes.insert(CopyNamespaces);
+ e.optionalAttributes.insert(InheritNamespaces);
+ e.optionalAttributes.insert(UseAttributeSets);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:output */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Output];
+
+ e.optionalAttributes.reserve(17);
+ e.optionalAttributes.insert(Name);
+ e.optionalAttributes.insert(Method);
+ e.optionalAttributes.insert(ByteOrderMark);
+ e.optionalAttributes.insert(CdataSectionElements);
+ e.optionalAttributes.insert(DoctypePublic);
+ e.optionalAttributes.insert(DoctypeSystem);
+ e.optionalAttributes.insert(Encoding);
+ e.optionalAttributes.insert(EscapeUriAttributes);
+ e.optionalAttributes.insert(IncludeContentType);
+ e.optionalAttributes.insert(Indent);
+ e.optionalAttributes.insert(MediaType);
+ e.optionalAttributes.insert(NormalizationForm);
+ e.optionalAttributes.insert(OmitXmlDeclaration);
+ e.optionalAttributes.insert(Standalone);
+ e.optionalAttributes.insert(UndeclarePrefixes);
+ e.optionalAttributes.insert(UseCharacterMaps);
+ e.optionalAttributes.insert(Version);
+ }
+
+ /* xsl:attribute-set */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[AttributeSet];
+
+ e.requiredAttributes.insert(Name);
+ e.optionalAttributes.insert(UseAttributeSets);
+ }
+
+ /* xsl:include and xsl:import. */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Include];
+ e.requiredAttributes.insert(Href);
+ result[Import] = e;
+ }
+
+ /* xsl:with-param */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[WithParam];
+ e.requiredAttributes.insert(Name);
+
+ e.optionalAttributes.insert(Select);
+ e.optionalAttributes.insert(As);
+ e.optionalAttributes.insert(Tunnel);
+ }
+
+ /* xsl:strip-space */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[StripSpace];
+ e.requiredAttributes.insert(Elements);
+
+ result.insert(PreserveSpace, e);
+ }
+
+ /* xsl:result-document */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[ResultDocument];
+
+ e.optionalAttributes.insert(ByteOrderMark);
+ e.optionalAttributes.insert(CdataSectionElements);
+ e.optionalAttributes.insert(DoctypePublic);
+ e.optionalAttributes.insert(DoctypeSystem);
+ e.optionalAttributes.insert(Encoding);
+ e.optionalAttributes.insert(EscapeUriAttributes);
+ e.optionalAttributes.insert(Format);
+ e.optionalAttributes.insert(Href);
+ e.optionalAttributes.insert(IncludeContentType);
+ e.optionalAttributes.insert(Indent);
+ e.optionalAttributes.insert(MediaType);
+ e.optionalAttributes.insert(Method);
+ e.optionalAttributes.insert(NormalizationForm);
+ e.optionalAttributes.insert(OmitXmlDeclaration);
+ e.optionalAttributes.insert(OutputVersion);
+ e.optionalAttributes.insert(Standalone);
+ e.optionalAttributes.insert(Type);
+ e.optionalAttributes.insert(UndeclarePrefixes);
+ e.optionalAttributes.insert(UseCharacterMaps);
+ e.optionalAttributes.insert(Validation);
+ }
+
+ /* xsl:key */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[Key];
+
+ e.requiredAttributes.insert(Name);
+ e.requiredAttributes.insert(Match);
+
+ e.optionalAttributes.insert(Use);
+ e.optionalAttributes.insert(Collation);
+ }
+
+ /* xsl:analyze-string */
+ {
+ ElementDescription<XSLTTokenLookup> &e = result[AnalyzeString];
+
+ e.requiredAttributes.insert(Select);
+ e.requiredAttributes.insert(Regex);
+
+ e.optionalAttributes.insert(Flags);
+ }
+
+ /* xsl:matching-substring */
+ {
+ /* We insert a default constructed value. */
+ result[MatchingSubstring];
+ }
+
+ /* xsl:non-matching-substring */
+ {
+ /* We insert a default constructed value. */
+ result[NonMatchingSubstring];
+ }
+
+ Q_ASSERT(result.count() == ReservedForElements);
+
+ return result;
+}
+
+QHash<QString, int> XSLTTokenizer::createValidationAlternatives()
+{
+ QHash<QString, int> retval;
+
+ retval.insert(QLatin1String("preserve"), 0);
+ retval.insert(QLatin1String("strip"), 1);
+ retval.insert(QLatin1String("strict"), 2);
+ retval.insert(QLatin1String("lax"), 3);
+
+ return retval;
+}
+
+bool XSLTTokenizer::whitespaceToSkip() const
+{
+ return m_stripWhitespace.top() && isWhitespace();
+}
+
+void XSLTTokenizer::unexpectedContent(const ReportContext::ErrorCode code) const
+{
+ QString message;
+
+ ReportContext::ErrorCode effectiveCode = code;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case Include:
+ effectiveCode = ReportContext::XTSE0170;
+ break;
+ case Import:
+ effectiveCode = ReportContext::XTSE0190;
+ break;
+ default:
+ ;
+ }
+ }
+
+ message = QtXmlPatterns::tr("Element %1 is not allowed at this location.")
+ .arg(formatKeyword(name()));
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ return;
+
+ message = QtXmlPatterns::tr("Text nodes are not allowed at this location.");
+ break;
+ }
+ case QXmlStreamReader::Invalid:
+ {
+ /* It's an issue with well-formedness. */
+ message = escape(errorString());
+ break;
+ }
+ default:
+ Q_ASSERT(false);
+ }
+
+ error(message, effectiveCode);
+}
+
+void XSLTTokenizer::checkForParseError() const
+{
+ if(hasError())
+ {
+ error(QtXmlPatterns::tr("Parse error: %1").arg(escape(errorString())), ReportContext::XTSE0010);
+ }
+}
+
+QString XSLTTokenizer::readElementText()
+{
+ QString result;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::Characters:
+ {
+ result += text().toString();
+ continue;
+ }
+ case QXmlStreamReader::Comment:
+ /* Fallthrough. */
+ case QXmlStreamReader::ProcessingInstruction:
+ continue;
+ case QXmlStreamReader::EndElement:
+ return result;
+ default:
+ unexpectedContent();
+ }
+ }
+
+ checkForParseError();
+ return result;
+}
+
+int XSLTTokenizer::commenceScanOnly()
+{
+ /* Do nothing, return a dummy value. */
+ return 0;
+}
+
+void XSLTTokenizer::resumeTokenizationFrom(const int position)
+{
+ /* Do nothing. */
+ Q_UNUSED(position);
+}
+
+void XSLTTokenizer::handleXSLTVersion(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isXSLTElement,
+ const QXmlStreamAttributes *atts,
+ const bool generateCode,
+ const bool setGlobalVersion)
+{
+ const QString ns(isXSLTElement ? QString() : CommonNamespaces::XSLT);
+ const QXmlStreamAttributes effectiveAtts(atts ? *atts : attributes());
+
+ if(!effectiveAtts.hasAttribute(ns, QLatin1String("version")))
+ return;
+
+ const QString attribute(effectiveAtts.value(ns, QLatin1String("version")).toString());
+ const AtomicValue::Ptr number(Decimal::fromLexical(attribute));
+
+ if(number->hasError())
+ {
+ error(QtXmlPatterns::tr("The value of the XSL-T version attribute "
+ "must be a value of type %1, which %2 isn't.").arg(formatType(m_namePool, BuiltinTypes::xsDecimal),
+ formatData(attribute)),
+ ReportContext::XTSE0110);
+ }
+ else
+ {
+
+ if(generateCode)
+ {
+ queueToken(Token(XSLT_VERSION, attribute), to);
+ queueToken(CURLY_LBRACE, to);
+ }
+
+ const xsDecimal version = number->as<Numeric>()->toDecimal();
+ if(version == 2.0)
+ m_processingMode.push(NormalProcessing);
+ else if(version == 1.0)
+ {
+ /* See section 3.6 Stylesheet Element discussing this. */
+ warning(QtXmlPatterns::tr("Running an XSL-T 1.0 stylesheet with a 2.0 processor."));
+ m_processingMode.push(BackwardsCompatible);
+
+ if(setGlobalVersion)
+ {
+ m_parseInfo->staticContext->setCompatModeEnabled(true);
+ m_parseInfo->isBackwardsCompat.push(true);
+ }
+ }
+ else if(version > 2.0)
+ m_processingMode.push(ForwardCompatible);
+ else if(version < 2.0)
+ m_processingMode.push(BackwardsCompatible);
+ }
+
+ if(generateCode)
+ queueOnExit->push(CURLY_RBRACE);
+}
+
+void XSLTTokenizer::handleXMLBase(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isInstruction,
+ const QXmlStreamAttributes *atts)
+{
+ const QXmlStreamAttributes effectiveAtts(atts ? *atts : m_currentAttributes);
+
+ if(effectiveAtts.hasAttribute(QLatin1String("xml:base")))
+ {
+ const QStringRef val(effectiveAtts.value(QLatin1String("xml:base")));
+
+ if(!val.isEmpty())
+ {
+ if(isInstruction)
+ {
+ queueToken(BASEURI, to);
+ queueToken(Token(STRING_LITERAL, val.toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ queueOnExit->push(CURLY_RBRACE);
+ }
+ else
+ {
+ queueToken(DECLARE, to);
+ queueToken(BASEURI, to);
+ queueToken(INTERNAL, to);
+ queueToken(Token(STRING_LITERAL, val.toString()), to);
+ queueToken(SEMI_COLON, to);
+ }
+ }
+ }
+}
+
+void XSLTTokenizer::handleStandardAttributes(const bool isXSLTElement)
+{
+ /* We're not necessarily StartElement, that's why we have atts passed in. */
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(m_hasHandledStandardAttributes)
+ return;
+
+ m_hasHandledStandardAttributes = true;
+
+ const QString ns(isXSLTElement ? QString() : CommonNamespaces::XSLT);
+ const int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &att = m_currentAttributes.at(i);
+
+ if(att.qualifiedName() == QLatin1String("xml:space"))
+ {
+ const QStringRef val(m_currentAttributes.value(CommonNamespaces::XML, QLatin1String("space")));
+
+ /* We raise an error if the value is not recognized.
+ *
+ * Extensible Markup Language (XML) 1.0 (Fourth Edition), 2.10
+ * White Space Handling:
+ *
+ * 'This specification does not give meaning to any value of
+ * xml:space other than "default" and "preserve". It is an error
+ * for other values to be specified; the XML processor may report
+ * the error or may recover by ignoring the attribute specification
+ * or by reporting the (erroneous) value to the application.' */
+ m_stripWhitespace.push(readToggleAttribute(QLatin1String("xml:space"),
+ QLatin1String("default"),
+ QLatin1String("preserve"),
+ &m_currentAttributes));
+ }
+
+ if(att.namespaceUri() != ns)
+ continue;
+
+ switch(toToken(att.name()))
+ {
+ case Type:
+ /* Fallthrough. */
+ case Validation:
+ /* Fallthrough. */
+ case UseAttributeSets:
+ /* Fallthrough. */
+ case Version:
+ /* These are handled by other function such as
+ * handleValidationAttributes() and handleXSLTVersion(). */
+ continue;
+ default:
+ {
+ if(!isXSLTElement) /* validateElement() will take care of it, and we
+ * don't want to flag non-standard XSL-T attributes. */
+ {
+ error(QtXmlPatterns::tr("Unknown XSL-T attribute %1.")
+ .arg(formatKeyword(att.name())),
+ ReportContext::XTSE0805);
+ }
+ }
+ }
+ }
+}
+
+void XSLTTokenizer::handleValidationAttributes(const bool isLRE) const
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ const QString ns(isLRE ? QString() : CommonNamespaces::XSLT);
+
+ const bool hasValidation = hasAttribute(ns, QLatin1String("validation"));
+ const bool hasType = hasAttribute(ns, QLatin1String("type"));
+
+ if(!hasType && !hasValidation)
+ return;
+
+ if(hasType && hasValidation)
+ {
+ error(QtXmlPatterns::tr("Attribute %1 and %2 are mutually exclusive.")
+ .arg(formatKeyword(QLatin1String("validation")),
+ formatKeyword(QLatin1String("type"))),
+ ReportContext::XTSE1505);
+ }
+
+ /* QXmlStreamReader surely doesn't make this easy. */
+ QXmlStreamAttribute validationAttribute;
+ int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &at = m_currentAttributes.at(i);
+ if(at.name() == QLatin1String("validation") && at.namespaceUri() == ns)
+ validationAttribute = at;
+ }
+
+ Q_ASSERT_X(!validationAttribute.name().isNull(), Q_FUNC_INFO,
+ "We should always find the attribute.");
+
+ /* We don't care about the return value, we just want to check it's a valid
+ * one. */
+ readAlternativeAttribute(m_validationAlternatives,
+ validationAttribute);
+}
+
+Tokenizer::Token XSLTTokenizer::nextToken(YYLTYPE *const sourceLocator)
+{
+ Q_UNUSED(sourceLocator);
+
+ if(m_tokenSource.isEmpty())
+ {
+ switch(m_state.top())
+ {
+ case OutsideDocumentElement:
+ outsideDocumentElement();
+ break;
+ case InsideStylesheetModule:
+ insideStylesheetModule();
+ break;
+ case InsideSequenceConstructor:
+ insideSequenceConstructor(&m_tokenSource);
+ break;
+ }
+
+ if(m_tokenSource.isEmpty())
+ {
+ *sourceLocator = currentSourceLocator();
+ return Token(END_OF_FILE);
+ }
+ else
+ return m_tokenSource.head()->nextToken(sourceLocator);
+ }
+ else
+ {
+ do
+ {
+ const Token candidate(m_tokenSource.head()->nextToken(sourceLocator));
+ if(candidate.type == END_OF_FILE)
+ m_tokenSource.dequeue();
+ else
+ return candidate;
+ }
+ while(!m_tokenSource.isEmpty());
+
+ /* Now we will resume parsing inside the regular XSL-T(XML) file. */
+ return nextToken(sourceLocator);
+ }
+}
+
+bool XSLTTokenizer::isElement(const XSLTTokenLookup::NodeName &name) const
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement);
+
+ return currentElementName() == name;
+}
+
+inline bool XSLTTokenizer::isXSLT() const
+{
+ Q_ASSERT_X(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement,
+ Q_FUNC_INFO, "The current token state must be StartElement or EndElement.");
+ /* Possible optimization: let MaintainingReader set an m_isXSLT which we
+ * read. */
+ return namespaceUri() == CommonNamespaces::XSLT;
+}
+
+void XSLTTokenizer::queueOnExit(QStack<Token> &source,
+ TokenSource::Queue *const destination)
+{
+ while(!source.isEmpty())
+ queueToken(source.pop(), destination);
+}
+
+void XSLTTokenizer::outsideDocumentElement()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ /* First, we synthesize one of the built-in templates,
+ * see section 6.6 Built-in Template Rules.
+ *
+ * Note that insideStylesheetModule() can be called multiple
+ * times so we can't do it there. */
+ {
+ /* Start with the one for text nodes and attributes.
+ * declare template matches (text() | @*) mode #all
+ * {
+ * text{.}
+ * };
+ */
+
+ /* declare template matches (text() | @*) */
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+ queueToken(MATCHES, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(TEXT, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+ queueToken(BAR, &m_tokenSource);
+ queueToken(AT_SIGN, &m_tokenSource);
+ queueToken(STAR, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ /* mode #all */
+ queueToken(MODE, &m_tokenSource);
+ queueToken(Token(NCNAME, QLatin1String("#all")), &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ /* text{.} { */
+ queueToken(TEXT, &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+ queueToken(DOT, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+
+ /* }; */
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(SEMI_COLON, &m_tokenSource);
+ }
+
+ if(isXSLT() && isStylesheetElement())
+ {
+ handleStandardAttributes(true);
+ QStack<Token> onExitTokens;
+ handleXMLBase(&m_tokenSource, &onExitTokens, false);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true, 0, false, true);
+ validateElement();
+ queueNamespaceDeclarations(&m_tokenSource, 0, true);
+
+ /* We're a regular stylesheet. */
+
+ pushState(InsideStylesheetModule);
+ insideStylesheetModule();
+ }
+ else
+ {
+ /* We're a simplified stylesheet. */
+
+ if(!hasAttribute(CommonNamespaces::XSLT, QLatin1String("version")))
+ {
+ error(QtXmlPatterns::tr("In a simplified stylesheet module, attribute %1 must be present.")
+ .arg(formatKeyword(QLatin1String("version"))),
+ ReportContext::XTSE0010);
+ }
+
+ QStack<Token> onExitTokens;
+
+ /* We synthesize this as exemplified in
+ * 3.7 Simplified Stylesheet Modules. */
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+ queueToken(MATCHES, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(SLASH, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+ pushState(InsideSequenceConstructor);
+
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, false, 0, true);
+ handleStandardAttributes(false);
+
+ insideSequenceConstructor(&m_tokenSource, false);
+
+ queueOnExit(onExitTokens, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(CURLY_RBRACE, &m_tokenSource);
+ queueToken(SEMI_COLON, &m_tokenSource);
+ }
+
+ queueToken(APPLY_TEMPLATE, &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ break;
+ }
+ default:
+ /* Do nothing. */;
+ }
+ }
+ checkForParseError();
+}
+
+void XSLTTokenizer::queueToken(const Token &token,
+ TokenSource::Queue *const to)
+{
+ TokenSource::Queue *const effective = to ? to : &m_tokenSource;
+
+ effective->enqueue(TokenSource::Ptr(new SingleTokenContainer(token, currentSourceLocator())));
+}
+
+void XSLTTokenizer::pushState(const State nextState)
+{
+ m_state.push(nextState);
+}
+
+void XSLTTokenizer::leaveState()
+{
+ m_state.pop();
+}
+
+void XSLTTokenizer::insideTemplate()
+{
+ const bool hasPriority = hasAttribute(QLatin1String("priority"));
+ const bool hasMatch = hasAttribute(QLatin1String("match"));
+ const bool hasName = hasAttribute(QLatin1String("name"));
+ const bool hasMode = hasAttribute(QLatin1String("mode"));
+ const bool hasAs = hasAttribute(QLatin1String("as"));
+
+ if(!hasMatch &&
+ (hasMode ||
+ hasPriority))
+ {
+ error(QtXmlPatterns::tr("If element %1 has no attribute %2, it cannot have attribute %3 or %4.")
+ .arg(formatKeyword(QLatin1String("template")),
+ formatKeyword(QLatin1String("match")),
+ formatKeyword(QLatin1String("mode")),
+ formatKeyword(QLatin1String("priority"))),
+ ReportContext::XTSE0500);
+ }
+ else if(!hasMatch && !hasName)
+ {
+ error(QtXmlPatterns::tr("Element %1 must have at least one of the attributes %2 or %3.")
+ .arg(formatKeyword(QLatin1String("template")),
+ formatKeyword(QLatin1String("name")),
+ formatKeyword(QLatin1String("match"))),
+ ReportContext::XTSE0500);
+ }
+
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(TEMPLATE, &m_tokenSource);
+
+ if(hasName)
+ {
+ queueToken(NAME, &m_tokenSource);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), &m_tokenSource);
+ }
+
+ if(hasMatch)
+ {
+ queueToken(MATCHES, &m_tokenSource);
+ queueExpression(readAttribute(QLatin1String("match")), &m_tokenSource);
+ }
+
+ if(hasMode)
+ {
+ const QString modeString(readAttribute(QLatin1String("mode")).simplified());
+
+ if(modeString.isEmpty())
+ {
+ error(QtXmlPatterns::tr("At least one mode must be specified in the %1-attribute on element %2.")
+ .arg(formatKeyword(QLatin1String("mode")),
+ formatKeyword(QLatin1String("template"))),
+ ReportContext::XTSE0500);
+ }
+
+ queueToken(MODE, &m_tokenSource);
+
+ const QStringList modeList(modeString.split(QLatin1Char(' ')));
+
+ for(int i = 0; i < modeList.count(); ++i)
+ {
+ const QString &mode = modeList.at(i);
+
+ queueToken(Token(mode.contains(QLatin1Char(':')) ? QNAME : NCNAME, mode), &m_tokenSource);
+
+ if(i < modeList.count() - 1)
+ queueToken(COMMA, &m_tokenSource);
+ }
+ }
+
+ if(hasPriority)
+ {
+ queueToken(PRIORITY, &m_tokenSource);
+ queueToken(Token(STRING_LITERAL, readAttribute(QLatin1String("priority"))), &m_tokenSource);
+ }
+
+ QStack<Token> onExitTokens;
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ /* queueParams moves the reader so we need to freeze the attributes. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+ handleStandardAttributes(true);
+ queueToken(LPAREN, &m_tokenSource);
+ queueParams(Template, &m_tokenSource);
+ queueToken(RPAREN, &m_tokenSource);
+
+ if(hasAs)
+ {
+ queueToken(AS, &m_tokenSource);
+ queueSequenceType(atts.value(QLatin1String("as")).toString());
+ }
+
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ handleXMLBase(&m_tokenSource, &onExitTokens, true, &atts);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true, &atts);
+ pushState(InsideSequenceConstructor);
+ startStorageOfCurrent(&m_tokenSource);
+ insideSequenceConstructor(&m_tokenSource, onExitTokens, false);
+ queueOnExit(onExitTokens, &m_tokenSource);
+}
+
+void XSLTTokenizer::queueExpression(const QString &expr,
+ TokenSource::Queue *const to,
+ const bool wrapWithParantheses)
+{
+ TokenSource::Queue *const effectiveTo = to ? to : &m_tokenSource;
+
+ if(wrapWithParantheses)
+ queueToken(LPAREN, effectiveTo);
+
+ effectiveTo->enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI())));
+
+ if(wrapWithParantheses)
+ queueToken(RPAREN, effectiveTo);
+}
+
+void XSLTTokenizer::queueAVT(const QString &expr,
+ TokenSource::Queue *const to)
+{
+ queueToken(AVT, to);
+ queueToken(LPAREN, to);
+ to->enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI(),
+ XQueryTokenizer::QuotAttributeContent)));
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::queueSequenceType(const QString &expr)
+{
+ m_tokenSource.enqueue(TokenSource::Ptr(new XQueryTokenizer(expr, queryURI(),
+ XQueryTokenizer::ItemType)));
+}
+
+void XSLTTokenizer::commencingExpression(bool &hasWrittenExpression,
+ TokenSource::Queue *const to)
+{
+ if(hasWrittenExpression)
+ queueToken(COMMA, to);
+ else
+ hasWrittenExpression = true;
+}
+
+void XSLTTokenizer::queueEmptySequence(TokenSource::Queue *const to)
+{
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::insideChoose(TokenSource::Queue *const to)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ bool hasHandledOtherwise = false;
+ bool hasEncounteredAtLeastOneWhen = false;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ QStack<Token> onExitTokens;
+ handleStandardAttributes(true);
+ validateElement();
+
+ switch(currentElementName())
+ {
+ case When:
+ {
+ if(hasHandledOtherwise)
+ {
+ error(QtXmlPatterns::tr("Element %1 must come last.")
+ .arg(formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueExpression(readAttribute(QLatin1String("test")), to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(RPAREN, to);
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement);
+ queueToken(ELSE, to);
+ hasEncounteredAtLeastOneWhen = true;
+ queueOnExit(onExitTokens, to);
+ break;
+ }
+ case Otherwise:
+ {
+ if(!hasEncounteredAtLeastOneWhen)
+ {
+ error(QtXmlPatterns::tr("At least one %1-element must occur before %2.")
+ .arg(formatKeyword(QLatin1String("when")),
+ formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+ else if(hasHandledOtherwise)
+ {
+ error(QtXmlPatterns::tr("Only one %1-element can appear.")
+ .arg(formatKeyword(QLatin1String("otherwise"))),
+ ReportContext::XTSE0010);
+ }
+
+ pushState(InsideSequenceConstructor);
+ queueToken(LPAREN, to);
+ insideSequenceConstructor(to, to);
+ queueToken(RPAREN, to);
+ hasHandledOtherwise = true;
+ queueOnExit(onExitTokens, to);
+ break;
+ }
+ default:
+ unexpectedContent();
+ }
+ }
+ else
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case Choose:
+ {
+ if(!hasEncounteredAtLeastOneWhen)
+ {
+ error(QtXmlPatterns::tr("At least one %1-element must occur inside %2.")
+ .arg(formatKeyword(QLatin1String("when")),
+ formatKeyword(QLatin1String("choose"))),
+ ReportContext::XTSE0010);
+ }
+
+ if(!hasHandledOtherwise)
+ queueEmptySequence(to);
+ return;
+ }
+ case Otherwise:
+ continue;
+ default:
+ unexpectedContent();
+ }
+ }
+ else
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::Comment:
+ /* Fallthrough. */
+ case QXmlStreamReader::ProcessingInstruction:
+ continue;
+ case QXmlStreamReader::Characters:
+ {
+ /* We ignore regardless of what xml:space says, see step 4 in
+ * 4.2 Stripping Whitespace from the Stylesheet. */
+ if(isWhitespace())
+ continue;
+ /* Fallthrough. */
+ }
+ default:
+ /* Fallthrough. */
+ unexpectedContent();
+ break;
+ }
+ }
+ checkForParseError();
+}
+
+bool XSLTTokenizer::queueSelectOrSequenceConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const QXmlStreamAttributes *const attsP,
+ const bool queueEmptyOnEmpty)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement || attsP);
+ const NodeName elementName(currentElementName());
+ const QXmlStreamAttributes atts(attsP ? *attsP : m_currentAttributes);
+
+ if(atts.hasAttribute(QLatin1String("select")))
+ {
+ queueExpression(atts.value(QLatin1String("select")).toString(), to);
+
+ /* First, verify that we don't have a body. */
+ if(skipSubTree(true))
+ {
+ error(QtXmlPatterns::tr("When attribute %1 is present on %2, a sequence "
+ "constructor cannot be used.").arg(formatKeyword(QLatin1String("select")),
+ formatKeyword(toString(elementName))),
+ code);
+ }
+
+ return true;
+ }
+ else
+ {
+ pushState(InsideSequenceConstructor);
+ if(!insideSequenceConstructor(to, true, queueEmptyOnEmpty) && !emptynessAllowed)
+ {
+ error(QtXmlPatterns::tr("Element %1 must have either a %2-attribute "
+ "or a sequence constructor.").arg(formatKeyword(toString(elementName)),
+ formatKeyword(QLatin1String("select"))),
+ code);
+
+ }
+
+ return false;
+ }
+}
+
+void XSLTTokenizer::queueSimpleContentConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const bool selectOnlyFirst)
+{
+ queueToken(INTERNAL_NAME, to);
+ queueToken(Token(NCNAME, QLatin1String("generic-string-join")), to);
+ queueToken(LPAREN, to);
+
+ /* We have to read the attribute before calling
+ * queueSelectOrSequenceConstructor(), since it advances the reader. */
+ const bool hasSeparator = m_currentAttributes.hasAttribute(QLatin1String("separator"));
+ const QString separatorAVT(m_currentAttributes.value(QLatin1String("separator")).toString());
+
+ queueToken(LPAREN, to);
+ const bool viaSelectAttribute = queueSelectOrSequenceConstructor(code, emptynessAllowed, to);
+ queueToken(RPAREN, to);
+
+ if(selectOnlyFirst)
+ {
+ queueToken(LBRACKET, to);
+ queueToken(Token(NUMBER, QChar::fromLatin1('1')), to);
+ queueToken(RBRACKET, to);
+ }
+
+ queueToken(COMMA, to);
+
+ if(hasSeparator)
+ queueAVT(separatorAVT, to);
+ else
+ {
+ /* The default value depends on whether the value is from @select, or from
+ * the sequence constructor. */
+ queueToken(Token(STRING_LITERAL, viaSelectAttribute ? QString(QLatin1Char(' '))
+ : QString()),
+ to);
+ }
+
+ queueToken(RPAREN, to);
+}
+
+void XSLTTokenizer::queueTextConstructor(QString &chars,
+ bool &hasWrittenExpression,
+ TokenSource::Queue *const to)
+{
+ if(!chars.isEmpty())
+ {
+ commencingExpression(hasWrittenExpression, to);
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(Token(STRING_LITERAL, chars), to);
+ queueToken(CURLY_RBRACE, to);
+ chars.clear();
+ }
+}
+
+void XSLTTokenizer::queueVariableDeclaration(const VariableType variableType,
+ TokenSource::Queue *const to)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ if(variableType == VariableInstruction)
+ {
+ queueToken(LET, to);
+ queueToken(INTERNAL, to);
+ }
+ else if(variableType == VariableDeclaration || variableType == GlobalParameter)
+ {
+ queueToken(DECLARE, to);
+ queueToken(VARIABLE, to);
+ queueToken(INTERNAL, to);
+ }
+
+ queueToken(DOLLAR, to);
+
+ queueExpression(readAttribute(QLatin1String("name")), to, false);
+
+ const bool hasAs = m_currentAttributes.hasAttribute(QLatin1String("as"));
+ if(hasAs)
+ {
+ queueToken(AS, to);
+ queueSequenceType(m_currentAttributes.value(QLatin1String("as")).toString());
+ }
+
+ if(variableType == FunctionParameter)
+ {
+ skipBodyOfParam(ReportContext::XTSE0760);
+ return;
+ }
+
+ /* We must do this here, because queueSelectOrSequenceConstructor()
+ * advances the reader. */
+ const bool hasSelect = hasAttribute(QLatin1String("select"));
+ const bool isRequired = hasAttribute(QLatin1String("required")) ? attributeYesNo(QLatin1String("required")) : false;
+
+ TokenSource::Queue storage;
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0620, true, &storage, 0, false);
+
+ /* XSL-T has some wicked rules, see
+ * 9.3 Values of Variables and Parameters. */
+
+ const bool hasQueuedContent = !storage.isEmpty();
+
+ /* The syntax for global parameters is:
+ *
+ * declare variable $var external := 'defaultValue';
+ */
+ if(variableType == GlobalParameter)
+ queueToken(EXTERNAL, to);
+
+ if(isRequired)
+ {
+ if(hasQueuedContent)
+ {
+ error(QtXmlPatterns::tr("When a parameter is required, a default value "
+ "cannot be supplied through a %1-attribute or "
+ "a sequence constructor.").arg(formatKeyword(QLatin1String("select"))),
+ ReportContext::XTSE0010);
+ }
+ }
+ else
+ {
+ if(hasQueuedContent)
+ {
+ queueToken(ASSIGN, to);
+
+ if(!hasSelect && !hasAs && !hasQueuedContent)
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ else if(hasAs || hasSelect)
+ queueToken(LPAREN, to);
+ else
+ {
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ }
+ }
+ else
+ {
+ if(!hasAs)
+ {
+ queueToken(ASSIGN, to);
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ }
+ else if(variableType == VariableDeclaration || variableType == VariableInstruction)
+ {
+ queueToken(ASSIGN, to);
+ queueEmptySequence(to);
+ }
+ }
+
+ /* storage has tokens if hasSelect or hasQueuedContent is true. */
+ if(hasSelect | hasQueuedContent)
+ *to += storage;
+
+ if(hasQueuedContent)
+ {
+ if(!hasSelect && !hasAs && !hasQueuedContent)
+ queueToken(Token(STRING_LITERAL, QString()), to);
+ else if(hasAs || hasSelect)
+ queueToken(RPAREN, to);
+ else
+ queueToken(CURLY_RBRACE, to);
+ }
+ }
+
+ if(variableType == VariableInstruction)
+ queueToken(RETURN, to);
+ else if(variableType == VariableDeclaration || variableType == GlobalParameter)
+ queueToken(SEMI_COLON, to);
+}
+
+void XSLTTokenizer::startStorageOfCurrent(TokenSource::Queue *const to)
+{
+ queueToken(CURRENT, to);
+ queueToken(CURLY_LBRACE, to);
+}
+
+void XSLTTokenizer::endStorageOfCurrent(TokenSource::Queue *const to)
+{
+ queueToken(CURLY_RBRACE, to);
+}
+
+void XSLTTokenizer::queueNamespaceDeclarations(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isDeclaration)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ Q_ASSERT_X(isDeclaration || queueOnExit,
+ Q_FUNC_INFO,
+ "If isDeclaration is false, queueOnExit must be passed.");
+
+ const QXmlStreamNamespaceDeclarations nss(namespaceDeclarations());
+
+ for(int i = 0; i < nss.count(); ++i)
+ {
+ const QXmlStreamNamespaceDeclaration &at = nss.at(i);
+ queueToken(DECLARE, to);
+ queueToken(NAMESPACE, to);
+ queueToken(Token(NCNAME, at.prefix().toString()), to);
+ queueToken(G_EQ, to);
+ queueToken(Token(STRING_LITERAL, at.namespaceUri().toString()), to);
+
+ if(isDeclaration)
+ {
+ queueToken(INTERNAL, to);
+ queueToken(SEMI_COLON, to);
+ }
+ else
+ {
+ queueToken(CURLY_LBRACE, to);
+ queueOnExit->push(CURLY_RBRACE);
+ }
+ }
+}
+
+bool XSLTTokenizer::insideSequenceConstructor(TokenSource::Queue *const to,
+ const bool initialAdvance,
+ const bool queueEmptyOnEmpty)
+{
+ QStack<Token> onExitTokens;
+ return insideSequenceConstructor(to, onExitTokens, initialAdvance, queueEmptyOnEmpty);
+}
+
+bool XSLTTokenizer::insideSequenceConstructor(TokenSource::Queue *const to,
+ QStack<Token> &onExitTokens,
+ const bool initialAdvance,
+ const bool queueEmptyOnEmpty)
+{
+ bool effectiveInitialAdvance = initialAdvance;
+ bool hasWrittenExpression = false;
+
+ /* Buffer which all text nodes, that might be split up by comments,
+ * processing instructions and CDATA sections, are appended to. */
+ QString characters;
+
+ while(!atEnd())
+ {
+ if(effectiveInitialAdvance)
+ readNext();
+ else
+ effectiveInitialAdvance = true;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ queueTextConstructor(characters, hasWrittenExpression, to);
+ handleXMLBase(to, &onExitTokens);
+
+ pushState(InsideSequenceConstructor);
+
+ commencingExpression(hasWrittenExpression, to);
+
+ if(isXSLT())
+ {
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ handleStandardAttributes(true);
+ validateElement();
+
+ queueNamespaceDeclarations(to, &onExitTokens);
+
+ switch(currentElementName())
+ {
+ case If:
+ {
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+
+ queueExpression(readAttribute(QLatin1String("test")), to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+
+ break;
+ }
+ case Choose:
+ {
+ insideChoose(to);
+ break;
+ }
+ case ValueOf:
+ {
+ /* We generate a computed text node constructor. */
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+
+ queueSimpleContentConstructor(ReportContext::XTSE0870, true, to,
+ !hasAttribute(QLatin1String("separator")) && m_processingMode.top() == BackwardsCompatible);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Sequence:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ parseFallbacksOnly();
+ break;
+ }
+ case Text:
+ {
+ queueToken(TEXT, to);
+ queueToken(CURLY_LBRACE, to);
+
+ queueToken(Token(STRING_LITERAL, readElementText()), to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Variable:
+ {
+ queueVariableDeclaration(VariableInstruction, to);
+
+ /* We wrap the children in parantheses since we may
+ * queue several expressions using the comma operator,
+ * and in that case the let-binding is only in-scope
+ * for the first expression. */
+ queueToken(LPAREN, to);
+
+ /* We don't want a comma outputted, we're expecting an
+ * expression now. */
+ hasWrittenExpression = false;
+
+ onExitTokens.push(RPAREN);
+
+ break;
+ }
+ case CallTemplate:
+ {
+ queueToken(CALL_TEMPLATE, to);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), to);
+ queueToken(LPAREN, to);
+ queueWithParams(CallTemplate, to);
+ queueToken(RPAREN, to);
+ break;
+ }
+ case ForEach:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ queueToken(MAP, to);
+ pushState(InsideSequenceConstructor);
+
+ TokenSource::Queue sorts;
+ queueSorting(false, &sorts);
+
+
+ if(sorts.isEmpty())
+ {
+ startStorageOfCurrent(to);
+ insideSequenceConstructor(to, false);
+ endStorageOfCurrent(to);
+ }
+ else
+ {
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ startStorageOfCurrent(to);
+ insideSequenceConstructor(to, false);
+ endStorageOfCurrent(to);
+ queueToken(END_SORT, to);
+ }
+
+ break;
+ }
+ case XSLTTokenLookup::Comment:
+ {
+ queueToken(COMMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0940, true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case CopyOf:
+ {
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ // TODO
+
+ if(readNext() == QXmlStreamReader::EndElement)
+ break;
+ else
+ {
+ error(QtXmlPatterns::tr("Element %1 cannot have children.").arg(formatKeyword(QLatin1String("copy-of"))),
+ ReportContext::XTSE0010);
+ }
+ break;
+ }
+ case AnalyzeString:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case ResultDocument:
+ {
+ // TODO
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ break;
+ }
+ case Copy:
+ {
+ /* We translate:
+ * <xsl:copy>expr</xsl:copy>
+ * into:
+ *
+ * let $body := expr
+ * return
+ * if(self::element()) then
+ * element internal {node-name()} {$body}
+ * else if(self::document-node()) then
+ * document internal {$body}
+ * else (: This includes comments, processing-instructions,
+ * attributes, and comments. :)
+ * .
+ *
+ * TODO node identity is the same as the old node.
+ * TODO namespace bindings are lost when elements are constructed
+ */
+
+ /* let $body := expr */
+ queueToken(LET, to);
+ queueToken(INTERNAL, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(ASSIGN, to);
+ queueToken(LPAREN, to);
+ pushState(InsideSequenceConstructor);
+ /* Don't queue an empty sequence, we want the dot. */
+ insideSequenceConstructor(to);
+ queueToken(RPAREN, to);
+ queueToken(RETURN, to);
+
+ /* if(self::element()) then */
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueToken(SELF, to);
+ queueToken(COLONCOLON, to);
+ queueToken(ELEMENT, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ /* element internal {node-name()} {$body} */
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(Token(NCNAME, QLatin1String("node-name")), to); // TODO what if the default ns changes?
+ queueToken(LPAREN, to);
+ queueToken(DOT, to);
+ queueToken(RPAREN, to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(CURLY_RBRACE, to);
+
+ /* else if(self::document-node()) then */
+ queueToken(ELSE, to);
+ queueToken(IF, to);
+ queueToken(LPAREN, to);
+ queueToken(SELF, to);
+ queueToken(COLONCOLON, to);
+ queueToken(DOCUMENT_NODE, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(RPAREN, to);
+ queueToken(THEN, to);
+
+ /* document internal {$body} */
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ queueToken(DOLLAR, to);
+ queueToken(Token(NCNAME, QString(QLatin1Char('b'))), to); // TODO we need an internal name
+ queueToken(CURLY_RBRACE, to);
+
+ /* else . */
+ queueToken(ELSE, to);
+ queueToken(DOT, to);
+
+ break;
+ }
+ case XSLTTokenLookup::ProcessingInstruction:
+ {
+ queueToken(PROCESSING_INSTRUCTION, to);
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0880, true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Document:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(DOCUMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(CURLY_LBRACE, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Element:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ // TODO only strings allowed, not qname values.
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Attribute:
+ {
+ handleValidationAttributes(false);
+
+ // TODO base-URI
+ queueToken(ATTRIBUTE, to);
+ queueToken(INTERNAL, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ // TODO only strings allowed, not qname values.
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ queueSimpleContentConstructor(ReportContext::XTSE0840,
+ true, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case Namespace:
+ {
+ queueToken(NAMESPACE, to);
+
+ /* The name. */
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(readAttribute(QLatin1String("name")), to);
+ queueToken(CURLY_RBRACE, to);
+
+ /* The sequence constructor. */
+ queueToken(CURLY_LBRACE, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE0910,
+ false, to);
+ queueToken(CURLY_RBRACE, to);
+ break;
+ }
+ case PerformSort:
+ {
+ /* For:
+ * <xsl:perform-sort select="$in">
+ * <xsl:sort select="@key"/>
+ * </xsl:perform-sort>
+ *
+ * we generate:
+ *
+ * $in map sort order by @key
+ * return .
+ * end_sort
+ */
+
+ /* In XQuery, the sort keys appear after the expression
+ * supplying the initial sequence, while in
+ * xsl:perform-sort, if a sequence constructor is used,
+ * they appear in the opposite order. Hence, we need to
+ * reorder it. */
+
+ /* We store the attributes of xsl:perform-sort, before
+ * queueSorting() advances the reader. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+
+ TokenSource::Queue sorts;
+ queueSorting(true, &sorts);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE1040,
+ true,
+ to,
+ &atts);
+ /* queueSelectOrSequenceConstructor() positions us on EndElement. */
+ effectiveInitialAdvance = false;
+ queueToken(MAP, to);
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ queueToken(DOT, to);
+ queueToken(END_SORT, to);
+
+ break;
+ }
+ case Message:
+ {
+ // TODO
+ queueEmptySequence(to);
+ skipSubTree();
+ break;
+ }
+ case ApplyTemplates:
+ {
+ if(hasAttribute(QLatin1String("select")))
+ queueExpression(readAttribute(QLatin1String("select")), to);
+ else
+ {
+ queueToken(CHILD, to);
+ queueToken(COLONCOLON, to);
+ queueToken(NODE, to);
+ queueToken(LPAREN, to);
+ queueToken(RPAREN, to);
+ }
+
+ bool hasMode = hasAttribute(QLatin1String("mode"));
+ QString mode;
+
+ if(hasMode)
+ mode = readAttribute(QLatin1String("mode")).trimmed();
+
+ queueToken(FOR_APPLY_TEMPLATE, to);
+
+ TokenSource::Queue sorts;
+ queueSorting(false, &sorts, true);
+
+ if(!sorts.isEmpty())
+ {
+ queueToken(SORT, to);
+ *to += sorts;
+ queueToken(RETURN, to);
+ }
+
+ queueToken(APPLY_TEMPLATE, to);
+
+ if(hasMode)
+ {
+ queueToken(MODE, to);
+ queueToken(Token(mode.startsWith(QLatin1Char('#')) ? NCNAME : QNAME, mode), to);
+ }
+
+ queueToken(LPAREN, to);
+ queueWithParams(ApplyTemplates, to, false);
+ queueToken(RPAREN, to);
+
+ if(!sorts.isEmpty())
+ queueToken(END_SORT, to);
+
+ break;
+ }
+ default:
+ unexpectedContent();
+ }
+ continue;
+ }
+ else
+ {
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ handleStandardAttributes(false);
+ handleValidationAttributes(false);
+
+ /* We're generating an element constructor. */
+ queueNamespaceDeclarations(to, &onExitTokens); // TODO same in the isXSLT() branch
+ queueToken(ELEMENT, to);
+ queueToken(INTERNAL, to);
+ queueToken(Token(QNAME, qualifiedName().toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ const int len = m_currentAttributes.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const QXmlStreamAttribute &at = m_currentAttributes.at(i);
+
+ /* We don't want to generate constructors for XSL-T attributes. */
+ if(at.namespaceUri() == CommonNamespaces::XSLT)
+ continue;
+
+ queueToken(ATTRIBUTE, to);
+ queueToken(INTERNAL, to);
+
+ queueToken(Token(at.prefix().isEmpty() ? NCNAME : QNAME, at.qualifiedName().toString()), to);
+ queueToken(CURLY_LBRACE, to);
+ queueAVT(at.value().toString(), to);
+ queueToken(CURLY_RBRACE, to);
+ queueToken(COMMA, to);
+ }
+
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(to);
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement || hasError());
+ continue;
+ }
+
+ unexpectedContent();
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ queueTextConstructor(characters, hasWrittenExpression, to);
+ leaveState();
+
+ if(!hasWrittenExpression && queueEmptyOnEmpty)
+ queueEmptySequence(to);
+
+ queueOnExit(onExitTokens, to);
+
+ if(isXSLT())
+ {
+ Q_ASSERT(!isElement(Sequence));
+
+ switch(currentElementName())
+ {
+ /* Fallthrough all these. */
+ case When:
+ case Choose:
+ case ForEach:
+ case Otherwise:
+ case PerformSort:
+ case Message:
+ case ResultDocument:
+ case Copy:
+ case CallTemplate:
+ case Text:
+ case ValueOf:
+ {
+ hasWrittenExpression = true;
+ break;
+ }
+ case If:
+ {
+ queueToken(RPAREN, to);
+ queueToken(ELSE, to);
+ queueEmptySequence(to);
+ break;
+ }
+ case Function:
+ {
+ queueToken(CURLY_RBRACE, to);
+ queueToken(SEMI_COLON, to);
+ break;
+ }
+ case Template:
+ {
+ endStorageOfCurrent(&m_tokenSource);
+ /* TODO, fallthrough to Function. */
+ queueToken(CURLY_RBRACE, to);
+ queueToken(SEMI_COLON, to);
+ break;
+ }
+ default:
+ ;
+ }
+ }
+ else
+ {
+ /* We're closing a direct element constructor. */
+ hasWrittenExpression = true;
+ queueToken(CURLY_RBRACE, to);
+ }
+
+ return hasWrittenExpression;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ /* We do nothing, we just ignore them. */
+ continue;
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ else
+ {
+ characters += text().toString();
+ continue;
+ }
+ }
+ default:
+ ;
+ }
+ }
+
+ leaveState();
+ return hasWrittenExpression;
+}
+
+bool XSLTTokenizer::isStylesheetElement() const
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement ||
+ tokenType() == QXmlStreamReader::EndElement);
+
+ const NodeName name = currentElementName();
+ return name == Stylesheet || name == Transform;
+}
+
+void XSLTTokenizer::skipBodyOfParam(const ReportContext::ErrorCode code)
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+ const NodeName name(currentElementName());
+
+ if(skipSubTree())
+ {
+ error(QtXmlPatterns::tr("Element %1 cannot have a sequence constructor.")
+ .arg(formatKeyword(toString(name))),
+ code);
+ }
+}
+
+void XSLTTokenizer::queueWithParams(const XSLTTokenLookup::NodeName parentName,
+ TokenSource::Queue *const to,
+ const bool initialAdvance)
+{
+ Q_ASSERT(parentName == ApplyTemplates || parentName == CallTemplate);
+
+ bool effectiveInitialAdvance = initialAdvance;
+ bool hasQueuedParam = false;
+
+ while(!atEnd())
+ {
+ if(effectiveInitialAdvance)
+ readNext();
+ else
+ effectiveInitialAdvance = true;
+
+ switch(tokenType())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(hasQueuedParam)
+ queueToken(COMMA, to);
+
+ if(isXSLT() && isElement(WithParam))
+ {
+ if(hasAttribute(QLatin1String("tunnel")) && attributeYesNo(QLatin1String("tunnel")))
+ queueToken(TUNNEL, to);
+
+ queueVariableDeclaration(WithParamVariable, to);
+ hasQueuedParam = true;
+ continue;
+ }
+ else
+ unexpectedContent();
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isElement(parentName))
+ return;
+ else
+ continue;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ case QXmlStreamReader::Characters:
+ if(whitespaceToSkip())
+ continue;
+ else
+ return;
+ default:
+ unexpectedContent();
+ }
+ }
+ unexpectedContent();
+}
+
+void XSLTTokenizer::queueParams(const XSLTTokenLookup::NodeName parentName,
+ TokenSource::Queue *const to)
+{
+ bool hasQueuedParam = false;
+
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(Param))
+ {
+ if(hasQueuedParam)
+ queueToken(COMMA, to);
+
+ validateElement();
+
+ if(parentName == Function && m_currentAttributes.hasAttribute(QLatin1String("select")))
+ {
+ error(QtXmlPatterns::tr("The attribute %1 cannot appear on %2, when it is a child of %3.")
+ .arg(formatKeyword(QLatin1String("select")),
+ formatKeyword(QLatin1String("param")),
+ formatKeyword(QLatin1String("function"))),
+ ReportContext::XTSE0760);
+ }
+
+ if(parentName == Function && m_currentAttributes.hasAttribute(QLatin1String("required")))
+ {
+ error(QtXmlPatterns::tr("The attribute %1 cannot appear on %2, when it is a child of %3.")
+ .arg(formatKeyword(QLatin1String("required")),
+ formatKeyword(QLatin1String("param")),
+ formatKeyword(QLatin1String("function"))),
+ ReportContext::XTSE0010);
+ }
+
+ const bool hasTunnel = m_currentAttributes.hasAttribute(QLatin1String("tunnel"));
+ const bool isTunnel = hasTunnel ? attributeYesNo(QLatin1String("tunnel")) : false;
+
+ if(isTunnel)
+ {
+ if(parentName == Function)
+ {
+ /* See W3C public report 5650: http://www.w3.org/Bugs/Public/show_bug.cgi?id=5650 */
+ error(QtXmlPatterns::tr("A parameter in a function cannot be declared to be a tunnel."),
+ ReportContext::XTSE0010);
+ }
+ else
+ queueToken(TUNNEL, to);
+ }
+
+ hasQueuedParam = true;
+ queueVariableDeclaration(parentName == Function ? FunctionParameter : TemplateParameter, to);
+ continue;
+ }
+ else
+ return;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ /* Fallthrough. */
+ }
+ case QXmlStreamReader::EndElement:
+ return;
+ default:
+ ;
+ }
+ }
+}
+
+bool XSLTTokenizer::skipSubTree(const bool exitOnContent)
+{
+ bool hasContent = false;
+ int depth = 0;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::Characters:
+ {
+ if(whitespaceToSkip())
+ continue;
+ else
+ {
+ hasContent = true;
+ if(exitOnContent)
+ return true;
+
+ break;
+ }
+ }
+ case QXmlStreamReader::StartElement:
+ {
+ hasContent = true;
+ if(exitOnContent)
+ return true;
+
+ ++depth;
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ --depth;
+ break;
+ }
+ default:
+ continue;
+ }
+
+ if(depth == -1)
+ return hasContent;
+ }
+
+ checkForParseError();
+ return hasContent;
+}
+
+void XSLTTokenizer::parseFallbacksOnly()
+{
+ Q_ASSERT(isXSLT());
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ skipSubTree();
+ Q_ASSERT(tokenType() == QXmlStreamReader::EndElement);
+}
+
+void XSLTTokenizer::insideAttributeSet()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(AttributeSet))
+ {
+ // TODO
+ skipSubTree();
+ }
+ else
+ unexpectedContent();
+ }
+ case QXmlStreamReader::EndElement:
+ return;
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ case QXmlStreamReader::Characters:
+ if(whitespaceToSkip())
+ continue;
+ /* Fallthrough. */
+ default:
+ unexpectedContent();
+ }
+ }
+ unexpectedContent();
+}
+
+void XSLTTokenizer::insideStylesheetModule()
+{
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT())
+ {
+ handleStandardAttributes(true);
+ handleXSLTVersion(0, 0, true, 0, false);
+ validateElement();
+
+ /* Handle the various declarations. */
+ switch(currentElementName())
+ {
+ case Template:
+ insideTemplate();
+ break;
+ case Function:
+ insideFunction();
+ break;
+ case Variable:
+ queueVariableDeclaration(VariableDeclaration, &m_tokenSource);
+ break;
+ case Param:
+ queueVariableDeclaration(GlobalParameter, &m_tokenSource);
+ break;
+ case ImportSchema:
+ {
+ error(QtXmlPatterns::tr("This processor is not Schema-aware and "
+ "therefore %1 cannot be used.").arg(formatKeyword(toString(ImportSchema))),
+ ReportContext::XTSE1660);
+ break;
+ }
+ case Output:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case StripSpace:
+ /* Fallthrough. */
+ case PreserveSpace:
+ {
+ // TODO @elements
+ skipSubTree(true);
+ readNext();
+
+ if(!isEndElement())
+ unexpectedContent();
+ break;
+ }
+ case Include:
+ {
+ // TODO
+ if(skipSubTree(true))
+ unexpectedContent();
+ break;
+ }
+ case Import:
+ {
+ // TODO
+ if(skipSubTree(true))
+ unexpectedContent();
+ break;
+ }
+ case Key:
+ {
+ // TODO
+ skipSubTree();
+ break;
+ }
+ case AttributeSet:
+ insideAttributeSet();
+ break;
+ default:
+ if(m_processingMode.top() != ForwardCompatible)
+ unexpectedContent();
+ }
+ }
+ else
+ {
+ /* We have a user-defined data element. See section 3.6.2. */
+
+ if(namespaceUri().isEmpty())
+ {
+ error(QtXmlPatterns::tr("Top level stylesheet elements must be "
+ "in a non-null namespace, which %1 isn't.").arg(formatKeyword(name())),
+ ReportContext::XTSE0130);
+ }
+ else
+ skipSubTree();
+ }
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ /* Regardless of xml:space, we skip whitespace, see step 4 in
+ * 4.2 Stripping Whitespace from the Stylesheet. */
+ if(isWhitespace())
+ continue;
+
+ unexpectedContent(ReportContext::XTSE0120);
+ break;
+ }
+ case QXmlStreamReader::EndElement:
+ {
+ if(isXSLT())
+ leaveState();
+
+ break;
+ }
+ default:
+ ;
+ }
+ }
+ checkForParseError();
+}
+
+bool XSLTTokenizer::readToggleAttribute(const QString &localName,
+ const QString &isTrue,
+ const QString &isFalse,
+ const QXmlStreamAttributes *const attsP) const
+{
+ const QXmlStreamAttributes atts(attsP ? *attsP : m_currentAttributes);
+ Q_ASSERT(atts.hasAttribute(localName));
+ const QString value(atts.value(localName).toString());
+
+ if(value == isTrue)
+ return true;
+ else if(value == isFalse)
+ return false;
+ else
+ {
+ error(QtXmlPatterns::tr("The value for attribute %1 on element %2 must either "
+ "be %3 or %4, not %5.").arg(formatKeyword(localName),
+ formatKeyword(name()),
+ formatData(isTrue),
+ formatData(isFalse),
+ formatData(value)),
+ ReportContext::XTSE0020);
+ /* Silences a compiler warning. */
+ return false;
+ }
+}
+
+int XSLTTokenizer::readAlternativeAttribute(const QHash<QString, int> &alternatives,
+ const QXmlStreamAttribute &attr) const
+{
+ const QString value(attr.value().toString().trimmed());
+
+ if(alternatives.contains(value))
+ return alternatives[value];
+
+ error(QtXmlPatterns::tr("Attribute %1 cannot have the value %2.")
+ .arg(formatKeyword(attr.name().toString()),
+ formatData(attr.value().toString())),
+ ReportContext::XTSE0020);
+ return 0; /* Silence compiler warning. */
+}
+
+bool XSLTTokenizer::attributeYesNo(const QString &localName) const
+{
+ return readToggleAttribute(localName, QLatin1String("yes"), QLatin1String("no"));
+}
+
+void XSLTTokenizer::queueSorting(const bool oneSortRequired,
+ TokenSource::Queue *const to,
+ const bool speciallyTreatWhitespace)
+{
+ Q_ASSERT(tokenType() == QXmlStreamReader::StartElement);
+
+ const NodeName elementName(currentElementName());
+ bool hasQueuedOneSort = false;
+
+ while(!atEnd())
+ {
+ switch(readNext())
+ {
+ case QXmlStreamReader::EndElement:
+ {
+ /* Let's say we have no sequence constructor, but only
+ * ignorable space. In that case we will actually loop
+ * infinitely if we don't have this check. */
+ if(isXSLT())
+ {
+ switch(currentElementName())
+ {
+ case PerformSort:
+ /* Fallthrough. */
+ case ForEach:
+ /* Fallthrough. */
+ case ApplyTemplates:
+ return;
+ default:
+ ;
+ }
+ }
+ continue;
+ }
+ case QXmlStreamReader::StartElement:
+ {
+ if(isXSLT() && isElement(Sort))
+ {
+ if(hasQueuedOneSort)
+ queueToken(COMMA, to);
+
+ /* sorts are by default stable. */
+ if(hasAttribute(QLatin1String("stable")))
+ {
+ if(hasQueuedOneSort)
+ {
+ error(QtXmlPatterns::tr("The attribute %1 can only appear on "
+ "the first %2 element.").arg(formatKeyword(QLatin1String("stable")),
+ formatKeyword(QLatin1String("sort"))),
+ ReportContext::XTSE0020);
+ }
+
+ if(attributeYesNo(QLatin1String("stable")))
+ queueToken(STABLE, to);
+ }
+
+ if(!hasQueuedOneSort)
+ {
+ queueToken(ORDER, to);
+ queueToken(BY, to);
+ }
+
+ /* We store a copy such that we can use them after
+ * queueSelectOrSequenceConstructor() advances the reader. */
+ const QXmlStreamAttributes atts(m_currentAttributes);
+
+ const int before = to->count();
+
+ // TODO This doesn't work as is. @data-type can be an AVT.
+ if(atts.hasAttribute(QLatin1String("data-type")))
+ {
+ if(readToggleAttribute(QLatin1String("data-type"),
+ QLatin1String("text"),
+ QLatin1String("number"),
+ &atts))
+ queueToken(Token(NCNAME, QLatin1String("string")), to);
+ else
+ queueToken(Token(NCNAME, QLatin1String("number")), to);
+ }
+ /* We queue these parantheses for the sake of the function
+ * call for attribute data-type. In the case we don't have
+ * such an attribute, the parantheses are just redundant. */
+ queueToken(LPAREN, to);
+ queueSelectOrSequenceConstructor(ReportContext::XTSE1015,
+ true,
+ to,
+ 0,
+ false);
+ /* If neither a select attribute or a sequence constructor is supplied,
+ * we're supposed to use the context item. */
+ queueToken(RPAREN, to);
+ if(before == to->count())
+ queueToken(DOT, to);
+
+ // TODO case-order
+ // TODO lang
+
+ // TODO This doesn't work as is. @order can be an AVT, and so can case-order and lang.
+ if(atts.hasAttribute(QLatin1String("order")) && readToggleAttribute(QLatin1String("order"),
+ QLatin1String("descending"),
+ QLatin1String("ascending"),
+ &atts))
+ {
+ queueToken(DESCENDING, to);
+ }
+ else
+ {
+ /* This is the default. */
+ queueToken(ASCENDING, to);
+ }
+
+ if(atts.hasAttribute(QLatin1String("collation")))
+ {
+ queueToken(INTERNAL, to);
+ queueToken(COLLATION, to);
+ queueAVT(atts.value(QLatin1String("collation")).toString(), to);
+ }
+
+ hasQueuedOneSort = true;
+ continue;
+ }
+ else
+ break;
+ }
+ case QXmlStreamReader::Characters:
+ {
+ if(speciallyTreatWhitespace && isWhitespace())
+ continue;
+
+ if(QXmlStreamReader::Characters && whitespaceToSkip())
+ continue;
+
+ /* We have an instruction which is a text node, we're done. */
+ break;
+ }
+ case QXmlStreamReader::ProcessingInstruction:
+ /* Fallthrough. */
+ case QXmlStreamReader::Comment:
+ continue;
+ default:
+ unexpectedContent();
+
+ };
+ if(oneSortRequired && !hasQueuedOneSort)
+ {
+ error(QtXmlPatterns::tr("At least one %1 element must appear as child of %2.")
+ .arg(formatKeyword(QLatin1String("sort")), formatKeyword(toString(elementName))),
+ ReportContext::XTSE0010);
+ }
+ else
+ return;
+ }
+ checkForParseError();
+}
+
+void XSLTTokenizer::insideFunction()
+{
+ queueToken(DECLARE, &m_tokenSource);
+ queueToken(FUNCTION, &m_tokenSource);
+ queueToken(INTERNAL, &m_tokenSource);
+ queueToken(Token(QNAME, readAttribute(QLatin1String("name"))), &m_tokenSource);
+ queueToken(LPAREN, &m_tokenSource);
+ const QString expectedType(hasAttribute(QLatin1String("as")) ? readAttribute(QLatin1String("as")): QString());
+
+ if(hasAttribute(QLatin1String("override")))
+ {
+ /* We currently have no external functions, so we don't pass it on currently. */
+ attributeYesNo(QLatin1String("override"));
+ }
+
+ queueParams(Function, &m_tokenSource);
+
+ queueToken(RPAREN, &m_tokenSource);
+
+ if(!expectedType.isNull())
+ {
+ queueToken(AS, &m_tokenSource);
+ queueSequenceType(expectedType);
+ }
+
+ QStack<Token> onExitTokens;
+ handleXMLBase(&m_tokenSource, &onExitTokens, true, &m_currentAttributes);
+ handleXSLTVersion(&m_tokenSource, &onExitTokens, true);
+ queueToken(CURLY_LBRACE, &m_tokenSource);
+
+ pushState(InsideSequenceConstructor);
+ insideSequenceConstructor(&m_tokenSource, onExitTokens, false);
+ /* We don't queue CURLY_RBRACE, because it's done in
+ * insideSequenceConstructor(). */
+}
+
+YYLTYPE XSLTTokenizer::currentSourceLocator() const
+{
+ YYLTYPE retval;
+ retval.first_line = lineNumber();
+ retval.first_column = columnNumber();
+ return retval;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qxslttokenizer_p.h b/src/xmlpatterns/parser/qxslttokenizer_p.h
new file mode 100644
index 0000000..cb14114
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenizer_p.h
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** 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_XSLTTokenizer_H
+#define Patternist_XSLTTokenizer_H
+
+#include <QQueue>
+#include <QStack>
+#include <QUrl>
+
+#include "qmaintainingreader_p.h"
+#include "qreportcontext_p.h"
+#include "qtokenizer_p.h"
+#include "qxslttokenlookup_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A TokenSource which contains one Tokenizer::Token.
+ *
+ * One possible way to optimize this is to let SingleTokenContainer
+ * actually contain a list of tokens, such that XSLTTokenizer::queueToken()
+ * could append to that, instead of instansiating a SingleTokenContainer
+ * all the time.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class SingleTokenContainer : public TokenSource
+ {
+ public:
+ inline SingleTokenContainer(const Tokenizer::Token &token,
+ const YYLTYPE &location);
+
+ virtual Tokenizer::Token nextToken(YYLTYPE *const sourceLocator);
+ private:
+ const Tokenizer::Token m_token;
+ const YYLTYPE m_location;
+ bool m_hasDelivered;
+ };
+
+ SingleTokenContainer::SingleTokenContainer(const Tokenizer::Token &token,
+ const YYLTYPE &location) : m_token(token)
+ , m_location(location)
+ , m_hasDelivered(false)
+ {
+ }
+
+ /**
+ * @short Tokenizes XSL-T 2.0 documents.
+ *
+ * XSLTTokenizer takes in its constructor a pointer to a QIODevice which is
+ * supposed to contain an XSL-T document. XSLTTokenizer then rewrites that
+ * document into XQuery tokens delivered via nextToken(), which the regular
+ * XQuery parser then reads. Hence, the XSL-T language is rewritten into
+ * XQuery code, slightly extended to handle the featuress specific to
+ * XSL-T.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class XSLTTokenizer : public Tokenizer
+ , private MaintainingReader<XSLTTokenLookup>
+ {
+ public:
+ /**
+ * XSLTTokenizer do not own @p queryDevice.
+ */
+ XSLTTokenizer(QIODevice *const queryDevice,
+ const QUrl &location,
+ const ReportContext::Ptr &context,
+ const NamePool::Ptr &np);
+
+ virtual Token nextToken(YYLTYPE *const sourceLocator);
+
+ /**
+ * For XSLT we don't need this mechanism, so we do nothing.
+ */
+ virtual int commenceScanOnly();
+
+ /**
+ * For XSLT we don't need this mechanism, so we do nothing.
+ */
+ virtual void resumeTokenizationFrom(const int position);
+
+ virtual void setParserContext(const ParserContext::Ptr &parseInfo);
+
+ virtual QUrl documentURI() const
+ {
+ return queryURI();
+ }
+
+ protected:
+ virtual bool isAnyAttributeAllowed() const;
+
+ private:
+ inline void validateElement() const;
+
+ YYLTYPE currentSourceLocator() const;
+
+ enum State
+ {
+ OutsideDocumentElement,
+ InsideStylesheetModule,
+ InsideSequenceConstructor
+ };
+
+ enum VariableType
+ {
+ FunctionParameter,
+ GlobalParameter,
+ TemplateParameter,
+ VariableDeclaration,
+ VariableInstruction,
+ WithParamVariable
+ };
+
+ void queueNamespaceDeclarations(TokenSource::Queue *const ts,
+ QStack<Token> *const target,
+ const bool isDeclaration = false);
+
+ inline void queueToken(const Token &token,
+ TokenSource::Queue *const ts);
+ void queueEmptySequence(TokenSource::Queue *const to);
+ void queueSequenceType(const QString &expr);
+ /**
+ * If @p emptynessAllowed is @c true, the @c select attribute may
+ * be empty while there also is no sequence constructor.
+ */
+ void queueSimpleContentConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const bool selectOnlyFirst = false);
+ /**
+ * Tokenizes and queues @p expr as if it was an attribute value
+ * template.
+ */
+ void queueAVT(const QString &expr,
+ TokenSource::Queue *const to);
+
+ void hasWrittenExpression(bool &beacon);
+ void commencingExpression(bool &hasWrittenExpression,
+ TokenSource::Queue *const to);
+
+ void outsideDocumentElement();
+ void insideChoose(TokenSource::Queue *const to);
+ void insideFunction();
+
+ bool attributeYesNo(const QString &localName) const;
+
+ /**
+ * Scans/skips @c xsl:fallback elements only. This is the case of the
+ * children of @c xsl:sequence, for instance.
+ */
+ void parseFallbacksOnly();
+
+ /**
+ * Returns true if the current element is either @c stylesheet
+ * or the synonym @c transform.
+ *
+ * This function assumes that m_reader is positioned at an element
+ * and that the namespace is XSL-T.
+ */
+ bool isStylesheetElement() const;
+
+ /**
+ * Returns true if the current element name is @p name.
+ *
+ * It is assumed that the namespace is XSL-T and that the current
+ * state in m_reader is either QXmlStreamReader::StartElement or
+ * QXmlStreamReader::EndElement.
+ */
+ bool isElement(const NodeName &name) const;
+
+ /**
+ * Queues a text constructor for @p chars, if @p chars is
+ * not empty.
+ */
+ void queueTextConstructor(QString &chars,
+ bool &hasWrittenExpression,
+ TokenSource::Queue *const to);
+
+ /**
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#stylesheet-structure">XSL
+ * Transformations (XSLT) Version 2, 3.6 Stylesheet Element</a>
+ */
+ void insideStylesheetModule();
+ void insideTemplate();
+
+ /**
+ * Takes @p expr for an XPath expression, and pushes the necessary
+ * things for having it delivered as a stream of token, appropriate
+ * for Effective Boolean Value parsing.
+ */
+ void queueExpression(const QString &expr,
+ TokenSource::Queue *const to,
+ const bool wrapWithParantheses = true);
+
+ void skipBodyOfParam(const ReportContext::ErrorCode code);
+
+ void queueParams(const NodeName parentName,
+ TokenSource::Queue *const to);
+
+ /**
+ * Used for @c xsl:apply-templates and @c xsl:call-templates.
+ */
+ void queueWithParams(const NodeName parentName,
+ TokenSource::Queue *const to,
+ const bool initialAdvance = true);
+
+ /**
+ * Queues an @c xsl:variable declaration. If @p isInstruction is @c
+ * true, it is assumed to be a an instruction, otherwise a top-level
+ * declaration element.
+ */
+ void queueVariableDeclaration(const VariableType variableType,
+ TokenSource::Queue *const to);
+
+ /**
+ * Skips the current sub-tree.
+ *
+ * If text nodes that aren't strippable whitespace, or elements are
+ * encountered, @c true is returned, otherwise @c false.
+ *
+ * If @p exitOnContent is @c true, this function exits immediately
+ * if content is encountered for which it would return @c false.
+ */
+ bool skipSubTree(const bool exitOnContent = false);
+
+ /**
+ * Queues the necessary tokens for the expression that is either
+ * supplied using a @c select attribute or a sequence constructor,
+ * while doing the necessary error handling for ensuring they are
+ * mutually exclusive.
+ *
+ * It is assumed that the current state of m_reader is
+ * QXmlStreamReader::StartElement, or that the attributes for the
+ * element is supplied through @p atts. This function advances m_reader
+ * up until the corresponding QXmlStreamReader::EndElement.
+ *
+ * If @p emptynessAllowed is @c false, the element must either have a
+ * sequence constructor or a @c select attribute. If @c true, both may
+ * be absent.
+ *
+ * Returns @c true if the queued expression was supplied through the
+ * @c select attribute otherwise @c false.
+ */
+ bool queueSelectOrSequenceConstructor(const ReportContext::ErrorCode code,
+ const bool emptynessAllowed,
+ TokenSource::Queue *const to,
+ const QXmlStreamAttributes *const atts = 0,
+ const bool queueEmptyOnEmpty = true);
+
+ /**
+ * If @p initialAdvance is @c true, insideSequenceConstructor() will
+ * advance m_reader, otherwise it won't. Not doing so is useful
+ * when the caller is already inside a sequence constructor.
+ *
+ * Returns @c true if a sequence constructor was found and queued.
+ * Returns @c false if none was found, and the empty sequence was
+ * synthesized.
+ */
+ bool insideSequenceConstructor(TokenSource::Queue *const to,
+ const bool initialAdvance = true,
+ const bool queueEmptyOnEmpty = true);
+
+ bool insideSequenceConstructor(TokenSource::Queue *const to,
+ QStack<Token> &queueOnExit,
+ const bool initialAdvance = true,
+ const bool queueEmptyOnEmpty = true);
+
+ void insideAttributeSet();
+ void pushState(const State nextState);
+ void leaveState();
+
+ /**
+ * @short Handles @c xml:space and standard attributes.
+ *
+ * If @p isXSLTElement is @c true, the current element is an XSL-T
+ * element, as opposed to a Literal Result Element.
+ *
+ * handleStandardAttributes() must be called before validateElement(),
+ * because the former determines the version in use, and
+ * validateElement() depends on that.
+ *
+ * The core of this function can't be run many times because it pushes
+ * whitespace handling onto m_stripWhitespace.
+ * m_hasHandledStandardAttributes protects helping against this.
+ *
+ * @see validateElement()
+ * @see <a href="http://www.w3.org/TR/xslt20/#standard-attributes">XSL
+ * Transformations (XSLT) Version 2.0, 3.5 Standard Attributes</a>
+ */
+ void handleStandardAttributes(const bool isXSLTElement);
+
+ /**
+ * @short Sends the tokens in @p source to @p destination.
+ */
+ inline void queueOnExit(QStack<Token> &source,
+ TokenSource::Queue *const destination);
+
+ /**
+ * Handles the @c type and @c validation attribute on instructions and
+ * literal result elements.
+ *
+ * @p isLRE should be true if the current element is not in the XSL-T
+ * namespace, that is if it's a Literal Result Element.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#validation">XSL
+ * Transformations (XSLT) Version 2.0, 19.2 Validation</a>
+ */
+ void handleValidationAttributes(const bool isLRE) const;
+
+ void unexpectedContent(const ReportContext::ErrorCode code = ReportContext::XTSE0010) const;
+
+ void checkForParseError() const;
+
+ inline void startStorageOfCurrent(TokenSource::Queue *const to);
+ inline void endStorageOfCurrent(TokenSource::Queue *const to);
+
+ /**
+ * Checks that @p attribute has a value in accordance with what
+ * is allowed and supported.
+ */
+ void handleXSLTVersion(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isXSLTElement,
+ const QXmlStreamAttributes *atts = 0,
+ const bool generateCode = true,
+ const bool setGlobalVersion = false);
+
+ /**
+ * @short Generates code for reflecting @c xml:base attributes.
+ */
+ void handleXMLBase(TokenSource::Queue *const to,
+ QStack<Token> *const queueOnExit,
+ const bool isInstruction = true,
+ const QXmlStreamAttributes *atts = 0);
+
+ /**
+ * Concatenates text nodes, ignores comments and processing
+ * instructions, and raises errors on everything else.
+ *
+ * Hence, similar to QXmlStreamReader::readElementText(), except
+ * for error handling.
+ */
+ QString readElementText();
+
+ /**
+ * Tokenizes and validate xsl:sort statements, if any, until
+ * other content is encountered. The produced tokens are returned
+ * in a list.
+ *
+ * If @p oneSortRequired, at least one @c sort element must appear,
+ * otherwise an error is raised.
+ *
+ * If @p speciallyTreatWhitespace whitespace will be treated as if it
+ * was one of the elements mentioned in step 4 in section 4.2 Stripping
+ * Whitespace from the Stylesheet.
+ */
+ void queueSorting(const bool oneSortRequired,
+ TokenSource::Queue *const to,
+ const bool speciallyTreatWhitespace = false);
+
+ static ElementDescription<XSLTTokenLookup>::Hash createElementDescriptions();
+ static QHash<QString, int> createValidationAlternatives();
+ static QSet<NodeName> createStandardAttributes();
+
+ /**
+ * Reads the attribute by name @p attributeName, and returns @c true if
+ * its value is @p isTrue, @c false if it is @p isFalse, and raise an
+ * error otherwise.
+ */
+ bool readToggleAttribute(const QString &attributeName,
+ const QString &isTrue,
+ const QString &isFalse,
+ const QXmlStreamAttributes *const atts = 0) const;
+
+ int readAlternativeAttribute(const QHash<QString, int> &alternatives,
+ const QXmlStreamAttribute &attr) const;
+
+ /**
+ * Returns @c true if the current text node can be skipped without
+ * it leading to a validation error, with respect to whitespace.
+ */
+ inline bool whitespaceToSkip() const;
+
+ const QUrl m_location;
+ const NamePool::Ptr m_namePool;
+ QStack<State> m_state;
+ TokenSource::Queue m_tokenSource;
+
+ enum ProcessMode
+ {
+ BackwardsCompatible,
+ ForwardCompatible,
+ NormalProcessing
+ };
+
+ /**
+ * Whether we're processing in Forwards-Compatible or
+ * Backwards-Compatible mode.
+ *
+ * This is set by handleStandardAttributes().
+ *
+ * ParserContext have similar information in
+ * ParserContext::isBackwardsCompat. A big distinction is that both the
+ * tokenizer and the parser buffer tokens and have positions disjoint
+ * to each other. E.g, the state the parser has when reducing into
+ * non-terminals, is different from the tokenizer's.
+ */
+ QStack<ProcessMode> m_processingMode;
+
+ /**
+ * Returns @c true if the current state in m_reader is in the XSLT
+ * namespace. It is assumed that the current state is an element.
+ */
+ inline bool isXSLT() const;
+
+ const QHash<QString, int> m_validationAlternatives;
+
+ ParserContext::Ptr m_parseInfo;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/parser/qxslttokenlookup.cpp b/src/xmlpatterns/parser/qxslttokenlookup.cpp
new file mode 100644
index 0000000..4730427
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup.cpp
@@ -0,0 +1,3006 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+/* NOTE: This file is AUTO GENERATED by qtokenautomaton2cpp.xsl. */
+
+#include "qxslttokenlookup_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XSLTTokenLookup::NodeName XSLTTokenLookup::classifier2(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ if(data[1] == 115)
+
+
+ return As;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+ if (data[1] == 100)
+
+
+ {
+
+
+ return Id;
+
+ }
+
+ else if (data[1] == 102)
+
+
+ {
+
+
+ return If;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier3(const QChar *data)
+
+ {
+ if (data[0] == 107)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Key;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Use;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier4(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 112, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Copy;
+
+ }
+
+ else if (data[0] == 104)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 102
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Href;
+
+ }
+
+ else if (data[0] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Lang;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Mode;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Name;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return Sort;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+ if (data[2] == 115)
+
+
+ {
+
+ if(data[3] == 116)
+
+
+ return Test;
+
+ }
+
+ else if (data[2] == 120)
+
+
+ {
+
+ if(data[3] == 116)
+
+
+ return Text;
+
+ }
+
+
+ }
+
+ else if (data[1] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 2) == 0)
+
+
+ return Type;
+
+ }
+
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 101, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 3) == 0)
+
+
+ return When;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier5(const QChar *data)
+
+ {
+ if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 97, 103, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Flags;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 99, 104
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Match;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 100, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Order;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 114, 97, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Param;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 103, 101, 120
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Regex;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier6(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 111, 111, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Choose;
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109, 97, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Format;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+ if (data[1] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 111, 114, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Import;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 110, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Indent;
+
+ }
+
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 116, 104, 111, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Method;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 116, 112, 117, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Output;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 99, 116
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Select;
+
+ }
+
+ else if (data[1] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 98, 108, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Stable;
+
+ }
+
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 110, 110, 101, 108
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Tunnel;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier7(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+ if (data[2] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 101, 110, 116
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 4) == 0)
+
+
+ return Comment;
+
+ }
+
+ else if (data[2] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 45, 111, 102
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 4) == 0)
+
+
+ return CopyOf;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Element;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Include;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 115, 97, 103, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Message;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Version;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier8(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 99, 117, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Document;
+
+ }
+
+ else if (data[0] == 101)
+
+
+ {
+ if (data[1] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 101, 110, 116, 115
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Elements;
+
+ }
+
+ else if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 111, 100, 105, 110, 103
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Encoding;
+
+ }
+
+
+ }
+
+ else if (data[0] == 102)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 45, 101, 97, 99, 104
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return ForEach;
+
+ }
+
+ else if (data[1] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 6) == 0)
+
+
+ return Function;
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 118, 101, 114, 114, 105, 100, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Override;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 105, 111, 114, 105, 116, 121
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Priority;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 113, 117, 105, 114, 101, 100
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Required;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 113, 117, 101, 110, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Sequence;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 109, 112, 108, 97, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Template;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 101, 45, 119, 104, 101, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 7) == 0)
+
+
+ return UseWhen;
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+ if (data[1] == 97)
+
+
+ {
+ if (data[2] == 108)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 101, 45, 111, 102
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return ValueOf;
+
+ }
+
+ else if (data[2] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 97, 98, 108, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 5) == 0)
+
+
+ return Variable;
+
+ }
+
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier9(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Attribute;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 108, 108, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Collation;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 97, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return DataType;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Namespace;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 104, 101, 114, 119, 105, 115, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Otherwise;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 112, 97, 114, 97, 116, 111, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 8) == 0)
+
+
+ return Separator;
+
+ }
+
+ else if (data[0] == 116)
+
+
+ {
+ if (data[1] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 109, 105, 110, 97, 116, 101
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Terminate;
+
+ }
+
+ else if (data[1] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 110, 115, 102, 111, 114, 109
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Transform;
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier10(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 115, 101, 45, 111, 114, 100, 101, 114
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return CaseOrder;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 100, 105, 97, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return MediaType;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+ if (data[1] == 116)
+
+
+ {
+ if (data[2] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 100, 97, 108, 111, 110, 101
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Standalone;
+
+ }
+
+ else if (data[2] == 121)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 108, 101, 115, 104, 101, 101, 116
+ };
+ if(memcmp(&data[3], &string, sizeof(QChar) * 7) == 0)
+
+
+ return Stylesheet;
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 118)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 105, 100, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return Validation;
+
+ }
+
+ else if (data[0] == 119)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 105, 116, 104, 45, 112, 97, 114, 97, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 9) == 0)
+
+
+ return WithParam;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier11(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 115, 116, 114, 105, 112, 45, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 11) == 0)
+
+
+ return StripSpace;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier12(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 101, 114, 102, 111, 114, 109, 45, 115, 111, 114, 116
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 12) == 0)
+
+
+ return PerformSort;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier13(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return AttributeSet;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 108, 108, 45, 116, 101, 109, 112, 108, 97, 116, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return CallTemplate;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 112, 111, 114, 116, 45, 115, 99, 104, 101, 109, 97
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 12) == 0)
+
+
+ return ImportSchema;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier14(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 97, 108, 121, 122, 101, 45, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return AnalyzeString;
+
+ }
+
+ else if (data[0] == 100)
+
+
+ {
+ if (data[1] == 111)
+
+
+ {
+ if (data[2] == 99)
+
+
+ {
+ if (data[3] == 116)
+
+
+ {
+ if (data[4] == 121)
+
+
+ {
+ if (data[5] == 112)
+
+
+ {
+ if (data[6] == 101)
+
+
+ {
+ if (data[7] == 45)
+
+
+ {
+ if (data[8] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 98, 108, 105, 99
+ };
+ if(memcmp(&data[9], &string, sizeof(QChar) * 5) == 0)
+
+
+ return DoctypePublic;
+
+ }
+
+ else if (data[8] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 115, 116, 101, 109
+ };
+ if(memcmp(&data[9], &string, sizeof(QChar) * 5) == 0)
+
+
+ return DoctypeSystem;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 117, 116, 112, 117, 116, 45, 118, 101, 114, 115, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return OutputVersion;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 101, 115, 101, 114, 118, 101, 45, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 13) == 0)
+
+
+ return PreserveSpace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier15(const QChar *data)
+
+ {
+ if (data[0] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 112, 108, 121, 45, 116, 101, 109, 112, 108, 97, 116, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ApplyTemplates;
+
+ }
+
+ else if (data[0] == 98)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 121, 116, 101, 45, 111, 114, 100, 101, 114, 45, 109, 97, 114, 107
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ByteOrderMark;
+
+ }
+
+ else if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 112, 121, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return CopyNamespaces;
+
+ }
+
+ else if (data[0] == 114)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 117, 108, 116, 45, 100, 111, 99, 117, 109, 101, 110, 116
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return ResultDocument;
+
+ }
+
+ else if (data[0] == 115)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 99, 104, 101, 109, 97, 45, 108, 111, 99, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 14) == 0)
+
+
+ return SchemaLocation;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier17(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 99, 111, 108, 108, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultCollation;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier18(const QChar *data)
+
+ {
+ if (data[0] == 100)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 102, 97, 117, 108, 116, 45, 118, 97, 108, 105, 100, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return DefaultValidation;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 104, 101, 114, 105, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return InheritNamespaces;
+
+ }
+
+ else if (data[0] == 109)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return MatchingSubstring;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 114, 109, 97, 108, 105, 122, 97, 116, 105, 111, 110, 45, 102, 111, 114, 109
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 17) == 0)
+
+
+ return NormalizationForm;
+
+ }
+
+ else if (data[0] == 117)
+
+
+ {
+ if (data[1] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 101, 99, 108, 97, 114, 101, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[2], &string, sizeof(QChar) * 16) == 0)
+
+
+ return UndeclarePrefixes;
+
+ }
+
+ else if (data[1] == 115)
+
+
+ {
+ if (data[2] == 101)
+
+
+ {
+ if (data[3] == 45)
+
+
+ {
+ if (data[4] == 97)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 115
+ };
+ if(memcmp(&data[5], &string, sizeof(QChar) * 13) == 0)
+
+
+ return UseAttributeSets;
+
+ }
+
+ else if (data[4] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 104, 97, 114, 97, 99, 116, 101, 114, 45, 109, 97, 112, 115
+ };
+ if(memcmp(&data[5], &string, sizeof(QChar) * 13) == 0)
+
+
+ return UseCharacterMaps;
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier20(const QChar *data)
+
+ {
+ if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 99, 108, 117, 100, 101, 45, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 19) == 0)
+
+
+ return IncludeContentType;
+
+ }
+
+ else if (data[0] == 111)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 109, 105, 116, 45, 120, 109, 108, 45, 100, 101, 99, 108, 97, 114, 97, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 19) == 0)
+
+
+ return OmitXmlDeclaration;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier21(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 115, 99, 97, 112, 101, 45, 117, 114, 105, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 21) == 0)
+
+
+ return EscapeUriAttributes;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier22(const QChar *data)
+
+ {
+ if (data[0] == 99)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 100, 97, 116, 97, 45, 115, 101, 99, 116, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return CdataSectionElements;
+
+ }
+
+ else if (data[0] == 105)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 110, 112, 117, 116, 45, 116, 121, 112, 101, 45, 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return InputTypeAnnotations;
+
+ }
+
+ else if (data[0] == 110)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 111, 110, 45, 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return NonMatchingSubstring;
+
+ }
+
+ else if (data[0] == 112)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 114, 111, 99, 101, 115, 115, 105, 110, 103, 45, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 21) == 0)
+
+
+ return ProcessingInstruction;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier23(const QChar *data)
+
+ {
+ if (data[0] == 101)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 120, 99, 108, 117, 100, 101, 45, 114, 101, 115, 117, 108, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 22) == 0)
+
+
+ return ExcludeResultPrefixes;
+
+ }
+
+ else if (data[0] == 120)
+
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 112, 97, 116, 104, 45, 100, 101, 102, 97, 117, 108, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101
+ };
+ if(memcmp(&data[1], &string, sizeof(QChar) * 22) == 0)
+
+
+ return XpathDefaultNamespace;
+
+ }
+
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::classifier26(const QChar *data)
+
+ {
+
+ static const unsigned short string[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115
+ };
+ if(memcmp(&data[0], &string, sizeof(QChar) * 26) == 0)
+
+
+ return ExtensionElementPrefixes;
+
+
+ return NoKeyword;
+ }
+ XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QChar *data, int length)
+ {
+ switch(length)
+ {
+
+ case 2:
+ return classifier2(data);
+
+
+ case 3:
+ return classifier3(data);
+
+
+ case 4:
+ return classifier4(data);
+
+
+ case 5:
+ return classifier5(data);
+
+
+ case 6:
+ return classifier6(data);
+
+
+ case 7:
+ return classifier7(data);
+
+
+ case 8:
+ return classifier8(data);
+
+
+ case 9:
+ return classifier9(data);
+
+
+ case 10:
+ return classifier10(data);
+
+
+ case 11:
+ return classifier11(data);
+
+
+ case 12:
+ return classifier12(data);
+
+
+ case 13:
+ return classifier13(data);
+
+
+ case 14:
+ return classifier14(data);
+
+
+ case 15:
+ return classifier15(data);
+
+
+ case 17:
+ return classifier17(data);
+
+
+ case 18:
+ return classifier18(data);
+
+
+ case 20:
+ return classifier20(data);
+
+
+ case 21:
+ return classifier21(data);
+
+
+ case 22:
+ return classifier22(data);
+
+
+ case 23:
+ return classifier23(data);
+
+
+ case 26:
+ return classifier26(data);
+
+
+ default:
+ return NoKeyword;
+ }
+ }
+
+
+ QString XSLTTokenLookup::toString(NodeName token)
+ {
+ const unsigned short *data = 0;
+ int length = 0;
+
+ switch(token)
+ {
+
+ case AnalyzeString:
+ {
+ static const unsigned short staticallyStoredAnalyzeString[] =
+ {
+ 97, 110, 97, 108, 121, 122, 101, 45, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredAnalyzeString;
+ length = 14;
+ break;
+ }
+
+ case ApplyTemplates:
+ {
+ static const unsigned short staticallyStoredApplyTemplates[] =
+ {
+ 97, 112, 112, 108, 121, 45, 116, 101, 109, 112, 108, 97, 116, 101, 115, 0
+ };
+ data = staticallyStoredApplyTemplates;
+ length = 15;
+ break;
+ }
+
+ case As:
+ {
+ static const unsigned short staticallyStoredAs[] =
+ {
+ 97, 115, 0
+ };
+ data = staticallyStoredAs;
+ length = 2;
+ break;
+ }
+
+ case Attribute:
+ {
+ static const unsigned short staticallyStoredAttribute[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 0
+ };
+ data = staticallyStoredAttribute;
+ length = 9;
+ break;
+ }
+
+ case AttributeSet:
+ {
+ static const unsigned short staticallyStoredAttributeSet[] =
+ {
+ 97, 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 0
+ };
+ data = staticallyStoredAttributeSet;
+ length = 13;
+ break;
+ }
+
+ case ByteOrderMark:
+ {
+ static const unsigned short staticallyStoredByteOrderMark[] =
+ {
+ 98, 121, 116, 101, 45, 111, 114, 100, 101, 114, 45, 109, 97, 114, 107, 0
+ };
+ data = staticallyStoredByteOrderMark;
+ length = 15;
+ break;
+ }
+
+ case CallTemplate:
+ {
+ static const unsigned short staticallyStoredCallTemplate[] =
+ {
+ 99, 97, 108, 108, 45, 116, 101, 109, 112, 108, 97, 116, 101, 0
+ };
+ data = staticallyStoredCallTemplate;
+ length = 13;
+ break;
+ }
+
+ case CaseOrder:
+ {
+ static const unsigned short staticallyStoredCaseOrder[] =
+ {
+ 99, 97, 115, 101, 45, 111, 114, 100, 101, 114, 0
+ };
+ data = staticallyStoredCaseOrder;
+ length = 10;
+ break;
+ }
+
+ case CdataSectionElements:
+ {
+ static const unsigned short staticallyStoredCdataSectionElements[] =
+ {
+ 99, 100, 97, 116, 97, 45, 115, 101, 99, 116, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredCdataSectionElements;
+ length = 22;
+ break;
+ }
+
+ case Choose:
+ {
+ static const unsigned short staticallyStoredChoose[] =
+ {
+ 99, 104, 111, 111, 115, 101, 0
+ };
+ data = staticallyStoredChoose;
+ length = 6;
+ break;
+ }
+
+ case Collation:
+ {
+ static const unsigned short staticallyStoredCollation[] =
+ {
+ 99, 111, 108, 108, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredCollation;
+ length = 9;
+ break;
+ }
+
+ case Comment:
+ {
+ static const unsigned short staticallyStoredComment[] =
+ {
+ 99, 111, 109, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredComment;
+ length = 7;
+ break;
+ }
+
+ case Copy:
+ {
+ static const unsigned short staticallyStoredCopy[] =
+ {
+ 99, 111, 112, 121, 0
+ };
+ data = staticallyStoredCopy;
+ length = 4;
+ break;
+ }
+
+ case CopyNamespaces:
+ {
+ static const unsigned short staticallyStoredCopyNamespaces[] =
+ {
+ 99, 111, 112, 121, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115, 0
+ };
+ data = staticallyStoredCopyNamespaces;
+ length = 15;
+ break;
+ }
+
+ case CopyOf:
+ {
+ static const unsigned short staticallyStoredCopyOf[] =
+ {
+ 99, 111, 112, 121, 45, 111, 102, 0
+ };
+ data = staticallyStoredCopyOf;
+ length = 7;
+ break;
+ }
+
+ case DataType:
+ {
+ static const unsigned short staticallyStoredDataType[] =
+ {
+ 100, 97, 116, 97, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredDataType;
+ length = 9;
+ break;
+ }
+
+ case DefaultCollation:
+ {
+ static const unsigned short staticallyStoredDefaultCollation[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 99, 111, 108, 108, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDefaultCollation;
+ length = 17;
+ break;
+ }
+
+ case DefaultValidation:
+ {
+ static const unsigned short staticallyStoredDefaultValidation[] =
+ {
+ 100, 101, 102, 97, 117, 108, 116, 45, 118, 97, 108, 105, 100, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredDefaultValidation;
+ length = 18;
+ break;
+ }
+
+ case DoctypePublic:
+ {
+ static const unsigned short staticallyStoredDoctypePublic[] =
+ {
+ 100, 111, 99, 116, 121, 112, 101, 45, 112, 117, 98, 108, 105, 99, 0
+ };
+ data = staticallyStoredDoctypePublic;
+ length = 14;
+ break;
+ }
+
+ case DoctypeSystem:
+ {
+ static const unsigned short staticallyStoredDoctypeSystem[] =
+ {
+ 100, 111, 99, 116, 121, 112, 101, 45, 115, 121, 115, 116, 101, 109, 0
+ };
+ data = staticallyStoredDoctypeSystem;
+ length = 14;
+ break;
+ }
+
+ case Document:
+ {
+ static const unsigned short staticallyStoredDocument[] =
+ {
+ 100, 111, 99, 117, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredDocument;
+ length = 8;
+ break;
+ }
+
+ case Element:
+ {
+ static const unsigned short staticallyStoredElement[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredElement;
+ length = 7;
+ break;
+ }
+
+ case Elements:
+ {
+ static const unsigned short staticallyStoredElements[] =
+ {
+ 101, 108, 101, 109, 101, 110, 116, 115, 0
+ };
+ data = staticallyStoredElements;
+ length = 8;
+ break;
+ }
+
+ case Encoding:
+ {
+ static const unsigned short staticallyStoredEncoding[] =
+ {
+ 101, 110, 99, 111, 100, 105, 110, 103, 0
+ };
+ data = staticallyStoredEncoding;
+ length = 8;
+ break;
+ }
+
+ case EscapeUriAttributes:
+ {
+ static const unsigned short staticallyStoredEscapeUriAttributes[] =
+ {
+ 101, 115, 99, 97, 112, 101, 45, 117, 114, 105, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 0
+ };
+ data = staticallyStoredEscapeUriAttributes;
+ length = 21;
+ break;
+ }
+
+ case ExcludeResultPrefixes:
+ {
+ static const unsigned short staticallyStoredExcludeResultPrefixes[] =
+ {
+ 101, 120, 99, 108, 117, 100, 101, 45, 114, 101, 115, 117, 108, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredExcludeResultPrefixes;
+ length = 23;
+ break;
+ }
+
+ case ExtensionElementPrefixes:
+ {
+ static const unsigned short staticallyStoredExtensionElementPrefixes[] =
+ {
+ 101, 120, 116, 101, 110, 115, 105, 111, 110, 45, 101, 108, 101, 109, 101, 110, 116, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredExtensionElementPrefixes;
+ length = 26;
+ break;
+ }
+
+ case Flags:
+ {
+ static const unsigned short staticallyStoredFlags[] =
+ {
+ 102, 108, 97, 103, 115, 0
+ };
+ data = staticallyStoredFlags;
+ length = 5;
+ break;
+ }
+
+ case ForEach:
+ {
+ static const unsigned short staticallyStoredForEach[] =
+ {
+ 102, 111, 114, 45, 101, 97, 99, 104, 0
+ };
+ data = staticallyStoredForEach;
+ length = 8;
+ break;
+ }
+
+ case Format:
+ {
+ static const unsigned short staticallyStoredFormat[] =
+ {
+ 102, 111, 114, 109, 97, 116, 0
+ };
+ data = staticallyStoredFormat;
+ length = 6;
+ break;
+ }
+
+ case Function:
+ {
+ static const unsigned short staticallyStoredFunction[] =
+ {
+ 102, 117, 110, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredFunction;
+ length = 8;
+ break;
+ }
+
+ case Href:
+ {
+ static const unsigned short staticallyStoredHref[] =
+ {
+ 104, 114, 101, 102, 0
+ };
+ data = staticallyStoredHref;
+ length = 4;
+ break;
+ }
+
+ case Id:
+ {
+ static const unsigned short staticallyStoredId[] =
+ {
+ 105, 100, 0
+ };
+ data = staticallyStoredId;
+ length = 2;
+ break;
+ }
+
+ case If:
+ {
+ static const unsigned short staticallyStoredIf[] =
+ {
+ 105, 102, 0
+ };
+ data = staticallyStoredIf;
+ length = 2;
+ break;
+ }
+
+ case Import:
+ {
+ static const unsigned short staticallyStoredImport[] =
+ {
+ 105, 109, 112, 111, 114, 116, 0
+ };
+ data = staticallyStoredImport;
+ length = 6;
+ break;
+ }
+
+ case ImportSchema:
+ {
+ static const unsigned short staticallyStoredImportSchema[] =
+ {
+ 105, 109, 112, 111, 114, 116, 45, 115, 99, 104, 101, 109, 97, 0
+ };
+ data = staticallyStoredImportSchema;
+ length = 13;
+ break;
+ }
+
+ case Include:
+ {
+ static const unsigned short staticallyStoredInclude[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 0
+ };
+ data = staticallyStoredInclude;
+ length = 7;
+ break;
+ }
+
+ case IncludeContentType:
+ {
+ static const unsigned short staticallyStoredIncludeContentType[] =
+ {
+ 105, 110, 99, 108, 117, 100, 101, 45, 99, 111, 110, 116, 101, 110, 116, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredIncludeContentType;
+ length = 20;
+ break;
+ }
+
+ case Indent:
+ {
+ static const unsigned short staticallyStoredIndent[] =
+ {
+ 105, 110, 100, 101, 110, 116, 0
+ };
+ data = staticallyStoredIndent;
+ length = 6;
+ break;
+ }
+
+ case InheritNamespaces:
+ {
+ static const unsigned short staticallyStoredInheritNamespaces[] =
+ {
+ 105, 110, 104, 101, 114, 105, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 115, 0
+ };
+ data = staticallyStoredInheritNamespaces;
+ length = 18;
+ break;
+ }
+
+ case InputTypeAnnotations:
+ {
+ static const unsigned short staticallyStoredInputTypeAnnotations[] =
+ {
+ 105, 110, 112, 117, 116, 45, 116, 121, 112, 101, 45, 97, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 0
+ };
+ data = staticallyStoredInputTypeAnnotations;
+ length = 22;
+ break;
+ }
+
+ case Key:
+ {
+ static const unsigned short staticallyStoredKey[] =
+ {
+ 107, 101, 121, 0
+ };
+ data = staticallyStoredKey;
+ length = 3;
+ break;
+ }
+
+ case Lang:
+ {
+ static const unsigned short staticallyStoredLang[] =
+ {
+ 108, 97, 110, 103, 0
+ };
+ data = staticallyStoredLang;
+ length = 4;
+ break;
+ }
+
+ case Match:
+ {
+ static const unsigned short staticallyStoredMatch[] =
+ {
+ 109, 97, 116, 99, 104, 0
+ };
+ data = staticallyStoredMatch;
+ length = 5;
+ break;
+ }
+
+ case MatchingSubstring:
+ {
+ static const unsigned short staticallyStoredMatchingSubstring[] =
+ {
+ 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredMatchingSubstring;
+ length = 18;
+ break;
+ }
+
+ case MediaType:
+ {
+ static const unsigned short staticallyStoredMediaType[] =
+ {
+ 109, 101, 100, 105, 97, 45, 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredMediaType;
+ length = 10;
+ break;
+ }
+
+ case Message:
+ {
+ static const unsigned short staticallyStoredMessage[] =
+ {
+ 109, 101, 115, 115, 97, 103, 101, 0
+ };
+ data = staticallyStoredMessage;
+ length = 7;
+ break;
+ }
+
+ case Method:
+ {
+ static const unsigned short staticallyStoredMethod[] =
+ {
+ 109, 101, 116, 104, 111, 100, 0
+ };
+ data = staticallyStoredMethod;
+ length = 6;
+ break;
+ }
+
+ case Mode:
+ {
+ static const unsigned short staticallyStoredMode[] =
+ {
+ 109, 111, 100, 101, 0
+ };
+ data = staticallyStoredMode;
+ length = 4;
+ break;
+ }
+
+ case Name:
+ {
+ static const unsigned short staticallyStoredName[] =
+ {
+ 110, 97, 109, 101, 0
+ };
+ data = staticallyStoredName;
+ length = 4;
+ break;
+ }
+
+ case Namespace:
+ {
+ static const unsigned short staticallyStoredNamespace[] =
+ {
+ 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredNamespace;
+ length = 9;
+ break;
+ }
+
+ case NonMatchingSubstring:
+ {
+ static const unsigned short staticallyStoredNonMatchingSubstring[] =
+ {
+ 110, 111, 110, 45, 109, 97, 116, 99, 104, 105, 110, 103, 45, 115, 117, 98, 115, 116, 114, 105, 110, 103, 0
+ };
+ data = staticallyStoredNonMatchingSubstring;
+ length = 22;
+ break;
+ }
+
+ case NormalizationForm:
+ {
+ static const unsigned short staticallyStoredNormalizationForm[] =
+ {
+ 110, 111, 114, 109, 97, 108, 105, 122, 97, 116, 105, 111, 110, 45, 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredNormalizationForm;
+ length = 18;
+ break;
+ }
+
+ case OmitXmlDeclaration:
+ {
+ static const unsigned short staticallyStoredOmitXmlDeclaration[] =
+ {
+ 111, 109, 105, 116, 45, 120, 109, 108, 45, 100, 101, 99, 108, 97, 114, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredOmitXmlDeclaration;
+ length = 20;
+ break;
+ }
+
+ case Order:
+ {
+ static const unsigned short staticallyStoredOrder[] =
+ {
+ 111, 114, 100, 101, 114, 0
+ };
+ data = staticallyStoredOrder;
+ length = 5;
+ break;
+ }
+
+ case Otherwise:
+ {
+ static const unsigned short staticallyStoredOtherwise[] =
+ {
+ 111, 116, 104, 101, 114, 119, 105, 115, 101, 0
+ };
+ data = staticallyStoredOtherwise;
+ length = 9;
+ break;
+ }
+
+ case Output:
+ {
+ static const unsigned short staticallyStoredOutput[] =
+ {
+ 111, 117, 116, 112, 117, 116, 0
+ };
+ data = staticallyStoredOutput;
+ length = 6;
+ break;
+ }
+
+ case OutputVersion:
+ {
+ static const unsigned short staticallyStoredOutputVersion[] =
+ {
+ 111, 117, 116, 112, 117, 116, 45, 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredOutputVersion;
+ length = 14;
+ break;
+ }
+
+ case Override:
+ {
+ static const unsigned short staticallyStoredOverride[] =
+ {
+ 111, 118, 101, 114, 114, 105, 100, 101, 0
+ };
+ data = staticallyStoredOverride;
+ length = 8;
+ break;
+ }
+
+ case Param:
+ {
+ static const unsigned short staticallyStoredParam[] =
+ {
+ 112, 97, 114, 97, 109, 0
+ };
+ data = staticallyStoredParam;
+ length = 5;
+ break;
+ }
+
+ case PerformSort:
+ {
+ static const unsigned short staticallyStoredPerformSort[] =
+ {
+ 112, 101, 114, 102, 111, 114, 109, 45, 115, 111, 114, 116, 0
+ };
+ data = staticallyStoredPerformSort;
+ length = 12;
+ break;
+ }
+
+ case PreserveSpace:
+ {
+ static const unsigned short staticallyStoredPreserveSpace[] =
+ {
+ 112, 114, 101, 115, 101, 114, 118, 101, 45, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredPreserveSpace;
+ length = 14;
+ break;
+ }
+
+ case Priority:
+ {
+ static const unsigned short staticallyStoredPriority[] =
+ {
+ 112, 114, 105, 111, 114, 105, 116, 121, 0
+ };
+ data = staticallyStoredPriority;
+ length = 8;
+ break;
+ }
+
+ case ProcessingInstruction:
+ {
+ static const unsigned short staticallyStoredProcessingInstruction[] =
+ {
+ 112, 114, 111, 99, 101, 115, 115, 105, 110, 103, 45, 105, 110, 115, 116, 114, 117, 99, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredProcessingInstruction;
+ length = 22;
+ break;
+ }
+
+ case Regex:
+ {
+ static const unsigned short staticallyStoredRegex[] =
+ {
+ 114, 101, 103, 101, 120, 0
+ };
+ data = staticallyStoredRegex;
+ length = 5;
+ break;
+ }
+
+ case Required:
+ {
+ static const unsigned short staticallyStoredRequired[] =
+ {
+ 114, 101, 113, 117, 105, 114, 101, 100, 0
+ };
+ data = staticallyStoredRequired;
+ length = 8;
+ break;
+ }
+
+ case ResultDocument:
+ {
+ static const unsigned short staticallyStoredResultDocument[] =
+ {
+ 114, 101, 115, 117, 108, 116, 45, 100, 111, 99, 117, 109, 101, 110, 116, 0
+ };
+ data = staticallyStoredResultDocument;
+ length = 15;
+ break;
+ }
+
+ case SchemaLocation:
+ {
+ static const unsigned short staticallyStoredSchemaLocation[] =
+ {
+ 115, 99, 104, 101, 109, 97, 45, 108, 111, 99, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredSchemaLocation;
+ length = 15;
+ break;
+ }
+
+ case Select:
+ {
+ static const unsigned short staticallyStoredSelect[] =
+ {
+ 115, 101, 108, 101, 99, 116, 0
+ };
+ data = staticallyStoredSelect;
+ length = 6;
+ break;
+ }
+
+ case Separator:
+ {
+ static const unsigned short staticallyStoredSeparator[] =
+ {
+ 115, 101, 112, 97, 114, 97, 116, 111, 114, 0
+ };
+ data = staticallyStoredSeparator;
+ length = 9;
+ break;
+ }
+
+ case Sequence:
+ {
+ static const unsigned short staticallyStoredSequence[] =
+ {
+ 115, 101, 113, 117, 101, 110, 99, 101, 0
+ };
+ data = staticallyStoredSequence;
+ length = 8;
+ break;
+ }
+
+ case Sort:
+ {
+ static const unsigned short staticallyStoredSort[] =
+ {
+ 115, 111, 114, 116, 0
+ };
+ data = staticallyStoredSort;
+ length = 4;
+ break;
+ }
+
+ case Stable:
+ {
+ static const unsigned short staticallyStoredStable[] =
+ {
+ 115, 116, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredStable;
+ length = 6;
+ break;
+ }
+
+ case Standalone:
+ {
+ static const unsigned short staticallyStoredStandalone[] =
+ {
+ 115, 116, 97, 110, 100, 97, 108, 111, 110, 101, 0
+ };
+ data = staticallyStoredStandalone;
+ length = 10;
+ break;
+ }
+
+ case StripSpace:
+ {
+ static const unsigned short staticallyStoredStripSpace[] =
+ {
+ 115, 116, 114, 105, 112, 45, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredStripSpace;
+ length = 11;
+ break;
+ }
+
+ case Stylesheet:
+ {
+ static const unsigned short staticallyStoredStylesheet[] =
+ {
+ 115, 116, 121, 108, 101, 115, 104, 101, 101, 116, 0
+ };
+ data = staticallyStoredStylesheet;
+ length = 10;
+ break;
+ }
+
+ case Template:
+ {
+ static const unsigned short staticallyStoredTemplate[] =
+ {
+ 116, 101, 109, 112, 108, 97, 116, 101, 0
+ };
+ data = staticallyStoredTemplate;
+ length = 8;
+ break;
+ }
+
+ case Terminate:
+ {
+ static const unsigned short staticallyStoredTerminate[] =
+ {
+ 116, 101, 114, 109, 105, 110, 97, 116, 101, 0
+ };
+ data = staticallyStoredTerminate;
+ length = 9;
+ break;
+ }
+
+ case Test:
+ {
+ static const unsigned short staticallyStoredTest[] =
+ {
+ 116, 101, 115, 116, 0
+ };
+ data = staticallyStoredTest;
+ length = 4;
+ break;
+ }
+
+ case Text:
+ {
+ static const unsigned short staticallyStoredText[] =
+ {
+ 116, 101, 120, 116, 0
+ };
+ data = staticallyStoredText;
+ length = 4;
+ break;
+ }
+
+ case Transform:
+ {
+ static const unsigned short staticallyStoredTransform[] =
+ {
+ 116, 114, 97, 110, 115, 102, 111, 114, 109, 0
+ };
+ data = staticallyStoredTransform;
+ length = 9;
+ break;
+ }
+
+ case Tunnel:
+ {
+ static const unsigned short staticallyStoredTunnel[] =
+ {
+ 116, 117, 110, 110, 101, 108, 0
+ };
+ data = staticallyStoredTunnel;
+ length = 6;
+ break;
+ }
+
+ case Type:
+ {
+ static const unsigned short staticallyStoredType[] =
+ {
+ 116, 121, 112, 101, 0
+ };
+ data = staticallyStoredType;
+ length = 4;
+ break;
+ }
+
+ case UndeclarePrefixes:
+ {
+ static const unsigned short staticallyStoredUndeclarePrefixes[] =
+ {
+ 117, 110, 100, 101, 99, 108, 97, 114, 101, 45, 112, 114, 101, 102, 105, 120, 101, 115, 0
+ };
+ data = staticallyStoredUndeclarePrefixes;
+ length = 18;
+ break;
+ }
+
+ case Use:
+ {
+ static const unsigned short staticallyStoredUse[] =
+ {
+ 117, 115, 101, 0
+ };
+ data = staticallyStoredUse;
+ length = 3;
+ break;
+ }
+
+ case UseAttributeSets:
+ {
+ static const unsigned short staticallyStoredUseAttributeSets[] =
+ {
+ 117, 115, 101, 45, 97, 116, 116, 114, 105, 98, 117, 116, 101, 45, 115, 101, 116, 115, 0
+ };
+ data = staticallyStoredUseAttributeSets;
+ length = 18;
+ break;
+ }
+
+ case UseCharacterMaps:
+ {
+ static const unsigned short staticallyStoredUseCharacterMaps[] =
+ {
+ 117, 115, 101, 45, 99, 104, 97, 114, 97, 99, 116, 101, 114, 45, 109, 97, 112, 115, 0
+ };
+ data = staticallyStoredUseCharacterMaps;
+ length = 18;
+ break;
+ }
+
+ case UseWhen:
+ {
+ static const unsigned short staticallyStoredUseWhen[] =
+ {
+ 117, 115, 101, 45, 119, 104, 101, 110, 0
+ };
+ data = staticallyStoredUseWhen;
+ length = 8;
+ break;
+ }
+
+ case Validation:
+ {
+ static const unsigned short staticallyStoredValidation[] =
+ {
+ 118, 97, 108, 105, 100, 97, 116, 105, 111, 110, 0
+ };
+ data = staticallyStoredValidation;
+ length = 10;
+ break;
+ }
+
+ case ValueOf:
+ {
+ static const unsigned short staticallyStoredValueOf[] =
+ {
+ 118, 97, 108, 117, 101, 45, 111, 102, 0
+ };
+ data = staticallyStoredValueOf;
+ length = 8;
+ break;
+ }
+
+ case Variable:
+ {
+ static const unsigned short staticallyStoredVariable[] =
+ {
+ 118, 97, 114, 105, 97, 98, 108, 101, 0
+ };
+ data = staticallyStoredVariable;
+ length = 8;
+ break;
+ }
+
+ case Version:
+ {
+ static const unsigned short staticallyStoredVersion[] =
+ {
+ 118, 101, 114, 115, 105, 111, 110, 0
+ };
+ data = staticallyStoredVersion;
+ length = 7;
+ break;
+ }
+
+ case When:
+ {
+ static const unsigned short staticallyStoredWhen[] =
+ {
+ 119, 104, 101, 110, 0
+ };
+ data = staticallyStoredWhen;
+ length = 4;
+ break;
+ }
+
+ case WithParam:
+ {
+ static const unsigned short staticallyStoredWithParam[] =
+ {
+ 119, 105, 116, 104, 45, 112, 97, 114, 97, 109, 0
+ };
+ data = staticallyStoredWithParam;
+ length = 10;
+ break;
+ }
+
+ case XpathDefaultNamespace:
+ {
+ static const unsigned short staticallyStoredXpathDefaultNamespace[] =
+ {
+ 120, 112, 97, 116, 104, 45, 100, 101, 102, 97, 117, 108, 116, 45, 110, 97, 109, 101, 115, 112, 97, 99, 101, 0
+ };
+ data = staticallyStoredXpathDefaultNamespace;
+ length = 23;
+ break;
+ }
+
+ default:
+ /* It's either the default token, or an undefined enum
+ * value. We silence a compiler warning, and return the
+ * empty string. */
+ ;
+ }
+
+ union
+ {
+ const unsigned short *data;
+ const QChar *asQChar;
+ } converter;
+ converter.data = data;
+
+ return QString::fromRawData(converter.asQChar, length);
+ }
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/parser/qxslttokenlookup.xml b/src/xmlpatterns/parser/qxslttokenlookup.xml
new file mode 100644
index 0000000..1972929
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tokenAutomaton scope="public"
+ className="XSLTTokenLookup"
+ headerFile="qxslttokenlookup_p.h"
+ sourceFile="qxslttokenlookup.cpp"
+ namespace="QPatternist"
+ defaultToken="NoKeyword"
+ hasToString="true"
+ tokenEnum="NodeName"
+ includeGuardName="qxslttokenlookup_p_H">
+ <tokens>
+ <token>analyze-string</token>
+ <token>apply-templates</token>
+ <token>as</token>
+ <token>attribute-set</token>
+ <token>attribute</token>
+ <token>byte-order-mark</token>
+ <token>call-template</token>
+ <token>case-order</token>
+ <token>cdata-section-elements</token>
+ <token>choose</token>
+ <token>collation</token>
+ <token>comment</token>
+ <token>copy-namespaces</token>
+ <token>copy-of</token>
+ <token>copy</token>
+ <token>data-type</token>
+ <token>default-collation</token>
+ <token>default-validation</token>
+ <token>doctype-public</token>
+ <token>doctype-system</token>
+ <token>document</token>
+ <token>elements</token>
+ <token>element</token>
+ <token>encoding</token>
+ <token>escape-uri-attributes</token>
+ <token>exclude-result-prefixes</token>
+ <token>extension-element-prefixes</token>
+ <token>flags</token>
+ <token>for-each</token>
+ <token>format</token>
+ <token>function</token>
+ <token>href</token>
+ <token>id</token>
+ <token>if</token>
+ <token>import-schema</token>
+ <token>import</token>
+ <token>include-content-type</token>
+ <token>include</token>
+ <token>indent</token>
+ <token>inherit-namespaces</token>
+ <token>input-type-annotations</token>
+ <token>key</token>
+ <token>lang</token>
+ <token>matching-substring</token>
+ <token>match</token>
+ <token>media-type</token>
+ <token>message</token>
+ <token>method</token>
+ <token>mode</token>
+ <token>namespace</token>
+ <token>name</token>
+ <token>non-matching-substring</token>
+ <token>normalization-form</token>
+ <token>omit-xml-declaration</token>
+ <token>order</token>
+ <token>otherwise</token>
+ <token>output</token>
+ <token>output-version</token>
+ <token>override</token>
+ <token>param</token>
+ <token>perform-sort</token>
+ <token>preserve-space</token>
+ <token>priority</token>
+ <token>processing-instruction</token>
+ <token>regex</token>
+ <token>required</token>
+ <token>result-document</token>
+ <token>schema-location</token>
+ <token>select</token>
+ <token>separator</token>
+ <token>sequence</token>
+ <token>sort</token>
+ <token>stable</token>
+ <token>standalone</token>
+ <token>strip-space</token>
+ <token>stylesheet</token>
+ <token>template</token>
+ <token>terminate</token>
+ <token>test</token>
+ <token>text</token>
+ <token>transform</token>
+ <token>tunnel</token>
+ <token>type</token>
+ <token>undeclare-prefixes</token>
+ <token>use-attribute-sets</token>
+ <token>use-character-maps</token>
+ <token>use</token>
+ <token>use-when</token>
+ <token>validation</token>
+ <token>value-of</token>
+ <token>variable</token>
+ <token>version</token>
+ <token>when</token>
+ <token>with-param</token>
+ <token>xpath-default-namespace</token>
+ </tokens>
+
+ <boilerplate>
+
+ <prolog>/****************************************************************************
+**
+** 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.
+//
+
+</prolog>
+
+ </boilerplate>
+
+</tokenAutomaton>
diff --git a/src/xmlpatterns/parser/qxslttokenlookup_p.h b/src/xmlpatterns/parser/qxslttokenlookup_p.h
new file mode 100644
index 0000000..3e65965
--- /dev/null
+++ b/src/xmlpatterns/parser/qxslttokenlookup_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** 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.
+//
+
+/* NOTE: This file is AUTO GENERATED by qautomaton2cpp.xsl. */
+
+#ifndef qxslttokenlookup_p_H
+#define qxslttokenlookup_p_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class XSLTTokenLookup
+ {
+ public:
+ enum NodeName
+
+ {
+ NoKeyword,
+ AnalyzeString,
+ ApplyTemplates,
+ As,
+ Attribute,
+ AttributeSet,
+ ByteOrderMark,
+ CallTemplate,
+ CaseOrder,
+ CdataSectionElements,
+ Choose,
+ Collation,
+ Comment,
+ Copy,
+ CopyNamespaces,
+ CopyOf,
+ DataType,
+ DefaultCollation,
+ DefaultValidation,
+ DoctypePublic,
+ DoctypeSystem,
+ Document,
+ Element,
+ Elements,
+ Encoding,
+ EscapeUriAttributes,
+ ExcludeResultPrefixes,
+ ExtensionElementPrefixes,
+ Flags,
+ ForEach,
+ Format,
+ Function,
+ Href,
+ Id,
+ If,
+ Import,
+ ImportSchema,
+ Include,
+ IncludeContentType,
+ Indent,
+ InheritNamespaces,
+ InputTypeAnnotations,
+ Key,
+ Lang,
+ Match,
+ MatchingSubstring,
+ MediaType,
+ Message,
+ Method,
+ Mode,
+ Name,
+ Namespace,
+ NonMatchingSubstring,
+ NormalizationForm,
+ OmitXmlDeclaration,
+ Order,
+ Otherwise,
+ Output,
+ OutputVersion,
+ Override,
+ Param,
+ PerformSort,
+ PreserveSpace,
+ Priority,
+ ProcessingInstruction,
+ Regex,
+ Required,
+ ResultDocument,
+ SchemaLocation,
+ Select,
+ Separator,
+ Sequence,
+ Sort,
+ Stable,
+ Standalone,
+ StripSpace,
+ Stylesheet,
+ Template,
+ Terminate,
+ Test,
+ Text,
+ Transform,
+ Tunnel,
+ Type,
+ UndeclarePrefixes,
+ Use,
+ UseAttributeSets,
+ UseCharacterMaps,
+ UseWhen,
+ Validation,
+ ValueOf,
+ Variable,
+ Version,
+ When,
+ WithParam,
+ XpathDefaultNamespace
+ };
+
+ static inline NodeName toToken(const QString &value);
+ static inline NodeName toToken(const QStringRef &value);
+ static NodeName toToken(const QChar *data, int length);
+ static QString toString(NodeName token);
+
+
+ private:
+ static inline NodeName classifier2(const QChar *data);
+ static inline NodeName classifier3(const QChar *data);
+ static inline NodeName classifier4(const QChar *data);
+ static inline NodeName classifier5(const QChar *data);
+ static inline NodeName classifier6(const QChar *data);
+ static inline NodeName classifier7(const QChar *data);
+ static inline NodeName classifier8(const QChar *data);
+ static inline NodeName classifier9(const QChar *data);
+ static inline NodeName classifier10(const QChar *data);
+ static inline NodeName classifier11(const QChar *data);
+ static inline NodeName classifier12(const QChar *data);
+ static inline NodeName classifier13(const QChar *data);
+ static inline NodeName classifier14(const QChar *data);
+ static inline NodeName classifier15(const QChar *data);
+ static inline NodeName classifier17(const QChar *data);
+ static inline NodeName classifier18(const QChar *data);
+ static inline NodeName classifier20(const QChar *data);
+ static inline NodeName classifier21(const QChar *data);
+ static inline NodeName classifier22(const QChar *data);
+ static inline NodeName classifier23(const QChar *data);
+ static inline NodeName classifier26(const QChar *data);
+
+ };
+
+ inline XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QString &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+ inline XSLTTokenLookup::NodeName XSLTTokenLookup::toToken(const QStringRef &value)
+ {
+ return toToken(value.constData(), value.length());
+ }
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/xmlpatterns/parser/trolltechHeader.txt b/src/xmlpatterns/parser/trolltechHeader.txt
new file mode 100644
index 0000000..8ac086a
--- /dev/null
+++ b/src/xmlpatterns/parser/trolltechHeader.txt
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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.
+
diff --git a/src/xmlpatterns/parser/winCEWorkaround.sed b/src/xmlpatterns/parser/winCEWorkaround.sed
new file mode 100644
index 0000000..46f18ae
--- /dev/null
+++ b/src/xmlpatterns/parser/winCEWorkaround.sed
@@ -0,0 +1,32 @@
+/\/\* Tokens\. \*\// i\
+\/\* These tokens are defined to nothing on Windows because they\'re\
+ \* used in their documentation parser, for use in things like:\
+ \*\
+ \* int foo(IN char\* name, OUT char\* path);\
+ \*\
+ \* Hence this un-break fix. Note that this file was auto generated. *\/\
+\#ifdef IN\
+\# undef IN\
+\#endif\
+\#ifdef INSTANCE\
+\# undef INSTANCE\
+\#endif\
+\#ifdef STRICT\
+\# undef STRICT\
+\#endif\
+\#ifdef SELF\
+\# undef SELF\
+\#endif\
+\/\* These tokens are defined in VxWorks kernel mode\
+ \*\
+ \* Hence this un-break fix. Note that this file was auto generated. *\/\
+\#ifdef ERROR\
+\# undef ERROR\
+\#endif\
+\#ifdef IMPORT\
+\# undef IMPORT\
+\#endif\
+\#ifdef MAP\
+\# undef MAP\
+\#endif\
+