src/corelib/xml/qxmlstream.g
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/corelib/xml/qxmlstream.g	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,1843 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+-- All rights reserved.
+-- Contact: Nokia Corporation (qt-info@nokia.com)
+--
+-- This file is part of the QtCore 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$
+--
+----------------------------------------------------------------------------
+
+%parser QXmlStreamReader_Table
+
+%merged_output qxmlstream_p.h
+
+%token NOTOKEN
+%token SPACE " "
+%token LANGLE "<"
+%token RANGLE ">"
+%token AMPERSAND "&"
+%token HASH "#"
+%token QUOTE "\'"
+%token DBLQUOTE "\""
+%token LBRACK "["
+%token RBRACK "]"
+%token LPAREN "("
+%token RPAREN ")"
+%token PIPE "|"
+%token EQ "="
+%token PERCENT "%"
+%token SLASH "/"
+%token COLON ":"
+%token SEMICOLON ";"
+%token COMMA ","
+%token DASH "-"
+%token PLUS "+"
+%token STAR "*"
+%token DOT "."
+%token QUESTIONMARK "?"
+%token BANG "!"
+%token LETTER "[a-zA-Z]"
+%token DIGIT "[0-9]"
+
+-- after langle_bang
+%token CDATA_START "[CDATA["
+%token DOCTYPE "DOCTYPE"
+%token ELEMENT "ELEMENT"
+%token ATTLIST "ATTLIST"
+%token ENTITY "ENTITY"
+%token NOTATION "NOTATION"
+
+-- entity decl
+%token SYSTEM "SYSTEM"
+%token PUBLIC "PUBLIC"
+%token NDATA "NDATA"
+
+-- default decl
+%token REQUIRED "REQUIRED"
+%token IMPLIED "IMPLIED"
+%token FIXED "FIXED"
+
+-- conent spec
+%token EMPTY "EMPTY"
+%token ANY "ANY"
+%token PCDATA "PCDATA"
+
+-- error
+%token ERROR
+
+-- entities
+%token PARSE_ENTITY
+%token ENTITY_DONE
+%token UNRESOLVED_ENTITY
+
+-- att type
+%token CDATA "CDATA"
+%token ID "ID"
+%token IDREF "IDREF"
+%token IDREFS "IDREFS"
+%token ENTITY "ENTITY"
+%token ENTITIES "ENTITIES"
+%token NMTOKEN "NMTOKEN"
+%token NMTOKENS "NMTOKENS"
+
+-- xml declaration
+%token XML "<?xml"
+%token VERSION "version"
+
+%nonassoc SHIFT_THERE
+%nonassoc AMPERSAND
+          BANG
+          COLON
+          COMMA
+          DASH
+          DBLQUOTE
+          DIGIT
+          DOT
+          ENTITY_DONE
+          EQ
+          HASH
+          LBRACK
+          LETTER
+          LPAREN
+          PERCENT
+          PIPE
+          PLUS
+          QUESTIONMARK
+          QUOTE
+          RANGLE
+          RBRACK
+          RPAREN
+          SEMICOLON
+          SLASH
+          SPACE
+          STAR
+
+%start document
+
+/.
+template <typename T> class QXmlStreamSimpleStack {
+    T *data;
+    int tos, cap;
+public:
+    inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+    inline ~QXmlStreamSimpleStack(){ if (data) qFree(data); }
+
+    inline void reserve(int extraCapacity) {
+        if (tos + extraCapacity + 1 > cap) {
+            cap = qMax(tos + extraCapacity + 1, cap << 1 );
+            data = reinterpret_cast<T *>(qRealloc(data, cap * sizeof(T)));
+        }
+    }
+
+    inline T &push() { reserve(1); return data[++tos]; }
+    inline T &rawPush() { return data[++tos]; }
+    inline const T &top() const { return data[tos]; }
+    inline T &top() { return data[tos]; }
+    inline T &pop() { return data[tos--]; }
+    inline T &operator[](int index) { return data[index]; }
+    inline const T &at(int index) const { return data[index]; }
+    inline int size() const { return tos + 1; }
+    inline void resize(int s) { tos = s - 1; }
+    inline bool isEmpty() const { return tos < 0; }
+    inline void clear() { tos = -1; }
+};
+
+
+class QXmlStream
+{
+    Q_DECLARE_TR_FUNCTIONS(QXmlStream)
+};
+
+class QXmlStreamPrivateTagStack {
+public:
+    struct NamespaceDeclaration
+    {
+        QStringRef prefix;
+        QStringRef namespaceUri;
+    };
+
+    struct Tag
+    {
+        QStringRef name;
+        QStringRef qualifiedName;
+        NamespaceDeclaration namespaceDeclaration;
+        int tagStackStringStorageSize;
+        int namespaceDeclarationsSize;
+    };
+
+
+    QXmlStreamPrivateTagStack();
+    QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
+    QString tagStackStringStorage;
+    int tagStackStringStorageSize;
+    bool tagsDone;
+
+    inline QStringRef addToStringStorage(const QStringRef &s) {
+        int pos = tagStackStringStorageSize;
+	int sz = s.size();
+	if (pos != tagStackStringStorage.size())
+	    tagStackStringStorage.resize(pos);
+        tagStackStringStorage.insert(pos, s.unicode(), sz);
+        tagStackStringStorageSize += sz;
+        return QStringRef(&tagStackStringStorage, pos, sz);
+    }
+    inline QStringRef addToStringStorage(const QString &s) {
+        int pos = tagStackStringStorageSize;
+	int sz = s.size();
+	if (pos != tagStackStringStorage.size())
+	    tagStackStringStorage.resize(pos);
+        tagStackStringStorage.insert(pos, s.unicode(), sz);
+        tagStackStringStorageSize += sz;
+        return QStringRef(&tagStackStringStorage, pos, sz);
+    }
+
+    QXmlStreamSimpleStack<Tag> tagStack;
+
+
+    inline Tag &tagStack_pop() {
+        Tag& tag = tagStack.pop();
+        tagStackStringStorageSize = tag.tagStackStringStorageSize;
+        namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
+        tagsDone = tagStack.isEmpty();
+        return tag;
+    }
+    inline Tag &tagStack_push() {
+        Tag &tag = tagStack.push();
+        tag.tagStackStringStorageSize = tagStackStringStorageSize;
+        tag.namespaceDeclarationsSize = namespaceDeclarations.size();
+        return tag;
+    }
+};
+
+
+class QXmlStreamEntityResolver;
+
+class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
+    QXmlStreamReader *q_ptr;
+    Q_DECLARE_PUBLIC(QXmlStreamReader)
+public:
+    QXmlStreamReaderPrivate(QXmlStreamReader *q);
+    ~QXmlStreamReaderPrivate();
+    void init();
+
+    QByteArray rawReadBuffer;
+    QByteArray dataBuffer;
+    uchar firstByte;
+    qint64 nbytesread;
+    QString readBuffer;
+    int readBufferPos;
+    QXmlStreamSimpleStack<uint> putStack;
+    struct Entity {
+        Entity(const QString& str = QString())
+            :value(str), external(false), unparsed(false), literal(false),
+             hasBeenParsed(false), isCurrentlyReferenced(false){}
+        static inline Entity createLiteral(const QString &entity)
+            { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
+        QString value;
+        uint external : 1;
+        uint unparsed : 1;
+        uint literal : 1;
+        uint hasBeenParsed : 1;
+        uint isCurrentlyReferenced : 1;
+    };
+    QHash<QString, Entity> entityHash;
+    QHash<QString, Entity> parameterEntityHash;
+    QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+    inline bool referenceEntity(Entity &entity) {
+        if (entity.isCurrentlyReferenced) {
+            raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+            return false;
+        }
+        entity.isCurrentlyReferenced = true;
+        entityReferenceStack.push() = &entity;
+        injectToken(ENTITY_DONE);
+        return true;
+    }
+
+
+    QIODevice *device;
+    bool deleteDevice;
+#ifndef QT_NO_TEXTCODEC
+    QTextCodec *codec;
+    QTextDecoder *decoder;
+#endif
+    bool atEnd;
+
+    /*!
+      \sa setType()
+     */
+    QXmlStreamReader::TokenType type;
+    QXmlStreamReader::Error error;
+    QString errorString;
+    QString unresolvedEntity;
+
+    qint64 lineNumber, lastLineStart, characterOffset;
+
+
+    void write(const QString &);
+    void write(const char *);
+
+
+    QXmlStreamAttributes attributes;
+    QStringRef namespaceForPrefix(const QStringRef &prefix);
+    void resolveTag();
+    void resolvePublicNamespaces();
+    void resolveDtd();
+    uint resolveCharRef(int symbolIndex);
+    bool checkStartDocument();
+    void startDocument();
+    void parseError();
+    void checkPublicLiteral(const QStringRef &publicId);
+
+    bool scanDtd;
+    QStringRef lastAttributeValue;
+    bool lastAttributeIsCData;
+    struct DtdAttribute {
+        QStringRef tagName;
+        QStringRef attributeQualifiedName;
+        QStringRef attributePrefix;
+        QStringRef attributeName;
+        QStringRef defaultValue;
+        bool isCDATA;
+        bool isNamespaceAttribute;
+    };
+    QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
+    struct NotationDeclaration {
+        QStringRef name;
+        QStringRef publicId;
+        QStringRef systemId;
+    };
+    QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
+    QXmlStreamNotationDeclarations publicNotationDeclarations;
+    QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
+
+    struct EntityDeclaration {
+        QStringRef name;
+        QStringRef notationName;
+        QStringRef publicId;
+        QStringRef systemId;
+        QStringRef value;
+        bool parameter;
+        bool external;
+        inline void clear() {
+            name.clear();
+            notationName.clear();
+            publicId.clear();
+            systemId.clear();
+            value.clear();
+            parameter = external = false;
+        }
+    };
+    QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
+    QXmlStreamEntityDeclarations publicEntityDeclarations;
+
+    QStringRef text;
+
+    QStringRef prefix, namespaceUri, qualifiedName, name;
+    QStringRef processingInstructionTarget, processingInstructionData;
+    QStringRef dtdName, dtdPublicId, dtdSystemId;
+    QStringRef documentVersion, documentEncoding;
+    uint isEmptyElement : 1;
+    uint isWhitespace : 1;
+    uint isCDATA : 1;
+    uint standalone : 1;
+    uint hasCheckedStartDocument : 1;
+    uint normalizeLiterals : 1;
+    uint hasSeenTag : 1;
+    uint inParseEntity : 1;
+    uint referenceToUnparsedEntityDetected : 1;
+    uint referenceToParameterEntityDetected : 1;
+    uint hasExternalDtdSubset : 1;
+    uint lockEncoding : 1;
+    uint namespaceProcessing : 1;
+
+    int resumeReduction;
+    void resume(int rule);
+
+    inline bool entitiesMustBeDeclared() const {
+        return (!inParseEntity
+                && (standalone
+                    || (!referenceToUnparsedEntityDetected
+                        && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
+                        && !hasExternalDtdSubset)));
+    }
+
+    // qlalr parser
+    int tos;
+    int stack_size;
+    struct Value {
+        int pos;
+        int len;
+        int prefix;
+        ushort c;
+    };
+
+    Value *sym_stack;
+    int *state_stack;
+    inline void reallocateStack();
+    inline Value &sym(int index) const
+    { return sym_stack[tos + index - 1]; }
+    QString textBuffer;
+    inline void clearTextBuffer() {
+        if (!scanDtd) {
+            textBuffer.resize(0);
+            textBuffer.reserve(256);
+        }
+    }
+    struct Attribute {
+        Value key;
+        Value value;
+    };
+    QXmlStreamSimpleStack<Attribute> attributeStack;
+
+    inline QStringRef symString(int index) {
+        const Value &symbol = sym(index);
+        return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+    }
+    inline QStringRef symName(int index) {
+        const Value &symbol = sym(index);
+        return QStringRef(&textBuffer, symbol.pos, symbol.len);
+    }
+    inline QStringRef symString(int index, int offset) {
+        const Value &symbol = sym(index);
+        return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix -  offset);
+    }
+    inline QStringRef symPrefix(int index) {
+        const Value &symbol = sym(index);
+        if (symbol.prefix)
+            return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+        return QStringRef();
+    }
+    inline QStringRef symString(const Value &symbol) {
+        return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+    }
+    inline QStringRef symName(const Value &symbol) {
+        return QStringRef(&textBuffer, symbol.pos, symbol.len);
+    }
+    inline QStringRef symPrefix(const Value &symbol) {
+        if (symbol.prefix)
+            return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+        return QStringRef();
+    }
+
+    inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
+
+
+    short token;
+    ushort token_char;
+
+    uint filterCarriageReturn();
+    inline uint getChar();
+    inline uint peekChar();
+    inline void putChar(uint c) { putStack.push() = c; }
+    inline void putChar(QChar c) { putStack.push() =  c.unicode(); }
+    void putString(const QString &s, int from = 0);
+    void putStringLiteral(const QString &s);
+    void putReplacement(const QString &s);
+    void putReplacementInAttributeValue(const QString &s);
+    ushort getChar_helper();
+
+    bool scanUntil(const char *str, short tokenToInject = -1);
+    bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
+    inline void injectToken(ushort tokenToInject) {
+        putChar(int(tokenToInject) << 16);
+    }
+
+    QString resolveUndeclaredEntity(const QString &name);
+    void parseEntity(const QString &value);
+    QXmlStreamReaderPrivate *entityParser;
+
+    bool scanAfterLangleBang();
+    bool scanPublicOrSystem();
+    bool scanNData();
+    bool scanAfterDefaultDecl();
+    bool scanAttType();
+
+
+    // scan optimization functions. Not strictly necessary but LALR is
+    // not very well suited for scanning fast
+    int fastScanLiteralContent();
+    int fastScanSpace();
+    int fastScanContentCharList();
+    int fastScanName(int *prefix = 0);
+    inline int fastScanNMTOKEN();
+
+
+    bool parse();
+    inline void consumeRule(int);
+
+    void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
+    void raiseWellFormedError(const QString &message);
+
+    QXmlStreamEntityResolver *entityResolver;
+
+private:
+    /*! \internal
+       Never assign to variable type directly. Instead use this function.
+
+       This prevents errors from being ignored.
+     */
+    inline void setType(const QXmlStreamReader::TokenType t)
+    {
+        if(type != QXmlStreamReader::Invalid)
+            type = t;
+    }
+};
+
+bool QXmlStreamReaderPrivate::parse()
+{
+    // cleanup currently reported token
+
+    switch (type) {
+    case QXmlStreamReader::StartElement:
+        name.clear();
+        prefix.clear();
+	qualifiedName.clear();
+        namespaceUri.clear();
+        if (publicNamespaceDeclarations.size())
+            publicNamespaceDeclarations.clear();
+        if (attributes.size())
+            attributes.resize(0);
+        if (isEmptyElement) {
+            setType(QXmlStreamReader::EndElement);
+            Tag &tag = tagStack_pop();
+            namespaceUri = tag.namespaceDeclaration.namespaceUri;
+            name = tag.name;
+	    qualifiedName = tag.qualifiedName;
+            isEmptyElement = false;
+            return true;
+        }
+        clearTextBuffer();
+        break;
+    case QXmlStreamReader::EndElement:
+        name.clear();
+        prefix.clear();
+	qualifiedName.clear();
+        namespaceUri.clear();
+        clearTextBuffer();
+        break;
+    case QXmlStreamReader::DTD:
+        publicNotationDeclarations.clear();
+        publicEntityDeclarations.clear();
+        dtdName.clear();
+        dtdPublicId.clear();
+        dtdSystemId.clear();
+        // fall through
+    case QXmlStreamReader::Comment:
+    case QXmlStreamReader::Characters:
+        isCDATA = false;
+	isWhitespace = true;
+        text.clear();
+        clearTextBuffer();
+        break;
+    case QXmlStreamReader::EntityReference:
+        text.clear();
+        name.clear();
+        clearTextBuffer();
+        break;
+    case QXmlStreamReader::ProcessingInstruction:
+        processingInstructionTarget.clear();
+        processingInstructionData.clear();
+	clearTextBuffer();
+        break;
+    case QXmlStreamReader::NoToken:
+    case QXmlStreamReader::Invalid:
+        break;
+    case QXmlStreamReader::StartDocument:
+	lockEncoding = true;
+        documentVersion.clear();
+        documentEncoding.clear();
+#ifndef QT_NO_TEXTCODEC
+	if(decoder->hasFailure()) {
+	    raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+	    readBuffer.clear();
+	    return false;
+	}
+#endif
+        // fall through
+    default:
+        clearTextBuffer();
+        ;
+    }
+
+    setType(QXmlStreamReader::NoToken);
+
+
+    // the main parse loop
+    int act, r;
+
+    if (resumeReduction) {
+        act = state_stack[tos-1];
+        r = resumeReduction;
+        resumeReduction = 0;
+        goto ResumeReduction;
+    }
+
+    act = state_stack[tos];
+
+    forever {
+        if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
+            uint cu = getChar();
+            token = NOTOKEN;
+            token_char = cu;
+            if (cu & 0xff0000) {
+                token = cu >> 16;
+            } else switch (token_char) {
+            case 0xfffe:
+            case 0xffff:
+                token = ERROR;
+                break;
+            case '\r':
+                token = SPACE;
+                if (cu == '\r') {
+                    if ((token_char = filterCarriageReturn())) {
+                        ++lineNumber;
+                        lastLineStart = characterOffset + readBufferPos;
+                        break;
+                    }
+                } else {
+                    break;
+                }
+                // fall through
+            case '\0': {
+                token = EOF_SYMBOL;
+                if (!tagsDone && !inParseEntity) {
+                    int a = t_action(act, token);
+                    if (a < 0) {
+                        raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+                        return false;
+                    }
+                }
+
+            } break;
+            case '\n':
+                ++lineNumber;
+                lastLineStart = characterOffset + readBufferPos;
+            case ' ':
+            case '\t':
+                token = SPACE;
+                break;
+            case '&':
+                token = AMPERSAND;
+                break;
+            case '#':
+                token = HASH;
+                break;
+            case '\'':
+                token = QUOTE;
+                break;
+            case '\"':
+                token = DBLQUOTE;
+                break;
+            case '<':
+                token = LANGLE;
+                break;
+            case '>':
+                token = RANGLE;
+                break;
+            case '[':
+                token = LBRACK;
+                break;
+            case ']':
+                token = RBRACK;
+                break;
+            case '(':
+                token = LPAREN;
+                break;
+            case ')':
+                token = RPAREN;
+                break;
+            case '|':
+                token = PIPE;
+                break;
+            case '=':
+                token = EQ;
+                break;
+            case '%':
+                token = PERCENT;
+                break;
+            case '/':
+                token = SLASH;
+                break;
+            case ':':
+                token = COLON;
+                break;
+            case ';':
+                token = SEMICOLON;
+                break;
+            case ',':
+                token = COMMA;
+                break;
+            case '-':
+                token = DASH;
+                break;
+            case '+':
+                token = PLUS;
+                break;
+            case '*':
+                token = STAR;
+                break;
+            case '.':
+                token = DOT;
+                break;
+            case '?':
+                token = QUESTIONMARK;
+                break;
+            case '!':
+                token = BANG;
+                break;
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                token = DIGIT;
+                break;
+            default:
+                if (cu < 0x20)
+                    token = NOTOKEN;
+                else
+                    token = LETTER;
+                break;
+            }
+        }
+
+        act = t_action (act, token);
+        if (act == ACCEPT_STATE) {
+            // reset the parser in case someone resumes (process instructions can follow a valid document)
+            tos = 0;
+            state_stack[tos++] = 0;
+            state_stack[tos] = 0;
+            return true;
+        } else if (act > 0) {
+            if (++tos == stack_size)
+                reallocateStack();
+
+            Value &val = sym_stack[tos];
+            val.c = token_char;
+            val.pos = textBuffer.size();
+            val.prefix = 0;
+            val.len = 1;
+            if (token_char)
+                textBuffer += QChar(token_char);
+
+            state_stack[tos] = act;
+            token = -1;
+
+
+        } else if (act < 0) {
+            r = - act - 1;
+
+#if defined (QLALR_DEBUG)
+            int ridx = rule_index[r];
+            printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
+            ++ridx;
+            for (int i = ridx; i < ridx + rhs[r]; ++i) {
+                int symbol = rule_info[i];
+                if (const char *name = spell[symbol])
+                    printf (" %s", name);
+                else
+                    printf (" #%d", symbol);
+            }
+            printf ("\n");
+#endif
+
+            tos -= rhs[r];
+            act = state_stack[tos++];
+        ResumeReduction:
+            switch (r) {
+./
+
+document ::= PARSE_ENTITY content;
+/.
+        case $rule_number:
+            setType(QXmlStreamReader::EndDocument);
+        break;
+./
+
+document ::= prolog;
+/.
+        case $rule_number:
+            if (type != QXmlStreamReader::Invalid) {
+                if (hasSeenTag || inParseEntity) {
+                    setType(QXmlStreamReader::EndDocument);
+                } else {
+                    raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
+                    // reset the parser
+                    tos = 0;
+                    state_stack[tos++] = 0;
+                    state_stack[tos] = 0;
+                    return false;
+                }
+            }
+        break;
+./
+
+
+prolog ::= prolog stag content etag;
+prolog ::= prolog empty_element_tag;
+prolog ::= prolog comment;
+prolog ::= prolog xml_decl;
+prolog ::= prolog processing_instruction;
+prolog ::= prolog doctype_decl;
+prolog ::= prolog SPACE;
+prolog ::=;
+
+entity_done ::= ENTITY_DONE;
+/.
+        case $rule_number:
+            entityReferenceStack.pop()->isCurrentlyReferenced = false;
+            clearSym();
+        break;
+./
+
+
+xml_decl_start ::= XML;
+/.
+        case $rule_number:
+            if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+xml_decl ::= xml_decl_start VERSION space_opt EQ space_opt literal attribute_list_opt QUESTIONMARK RANGLE;
+/.
+        case $rule_number:
+            setType(QXmlStreamReader::StartDocument);
+            documentVersion = symString(6);
+            startDocument();
+        break;
+./
+
+external_id ::= SYSTEM literal;
+/.
+        case $rule_number:
+            hasExternalDtdSubset = true;
+            dtdSystemId = symString(2);
+        break;
+./
+external_id ::= PUBLIC public_literal space literal;
+/.
+        case $rule_number:
+            checkPublicLiteral(symString(2));
+            dtdPublicId = symString(2);
+            dtdSystemId = symString(4);
+            hasExternalDtdSubset = true;
+        break;
+./
+external_id ::=;
+
+doctype_decl_start ::= langle_bang DOCTYPE qname space;
+/.
+        case $rule_number:
+            if (!scanPublicOrSystem() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            dtdName = symString(3);
+        break;
+./
+
+doctype_decl ::= langle_bang DOCTYPE qname RANGLE;
+/.
+        case $rule_number:./
+doctype_decl ::= langle_bang DOCTYPE qname markup space_opt RANGLE;
+/.
+        case $rule_number:
+            dtdName = symString(3);
+            // fall through
+./
+doctype_decl ::= doctype_decl_start external_id space_opt markup space_opt RANGLE;
+/.
+        case $rule_number:./
+doctype_decl ::= doctype_decl_start external_id space_opt RANGLE;
+/.
+        case $rule_number:
+            setType(QXmlStreamReader::DTD);
+            text = &textBuffer;
+        break;
+./
+
+markup_start ::= LBRACK;
+/.
+        case $rule_number:
+            scanDtd = true;
+        break;
+./
+
+markup ::= markup_start markup_list RBRACK;
+/.
+        case $rule_number:
+            scanDtd = false;
+        break;
+./
+
+
+markup_list ::= markup_decl | space | pereference;
+markup_list ::= markup_list markup_decl | markup_list space | markup_list pereference;
+
+markup_decl ::= element_decl | attlist_decl | entity_decl | entity_done | notation_decl | processing_instruction | comment;
+
+
+element_decl_start ::= langle_bang ELEMENT qname space;
+/.
+        case $rule_number:
+            if (!scanString(spell[EMPTY], EMPTY, false)
+                && !scanString(spell[ANY], ANY, false)
+                && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+element_decl ::= element_decl_start content_spec space_opt RANGLE;
+
+
+content_spec ::= EMPTY | ANY | mixed | children;
+
+pcdata_start ::= HASH;
+/.
+        case $rule_number:
+            if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+pcdata ::= pcdata_start PCDATA;
+
+questionmark_or_star_or_plus_opt ::= QUESTIONMARK | STAR | PLUS;
+questionmark_or_star_or_plus_opt ::=;
+
+cp ::= qname questionmark_or_star_or_plus_opt | choice_or_seq questionmark_or_star_or_plus_opt;
+
+cp_pipe_or_comma_list ::= cp space_opt;
+cp_pipe_or_comma_list ::= cp space_opt PIPE space_opt cp_pipe_list space_opt;
+cp_pipe_or_comma_list ::= cp space_opt COMMA space_opt cp_comma_list space_opt;
+cp_pipe_list ::= cp | cp_pipe_list space_opt PIPE space_opt cp;
+cp_comma_list ::= cp | cp_comma_list space_opt COMMA space_opt cp;
+
+
+name_pipe_list ::= PIPE space_opt qname;
+name_pipe_list ::= name_pipe_list space_opt PIPE space_opt qname;
+
+star_opt ::= | STAR;
+
+mixed ::= LPAREN space_opt pcdata space_opt RPAREN star_opt;
+mixed ::= LPAREN space_opt pcdata space_opt name_pipe_list space_opt RPAREN STAR;
+
+choice_or_seq ::= LPAREN space_opt cp_pipe_or_comma_list RPAREN;
+
+children ::= choice_or_seq questionmark_or_star_or_plus_opt;
+
+
+nmtoken_pipe_list ::= nmtoken;
+nmtoken_pipe_list ::= nmtoken_pipe_list space_opt PIPE space_opt nmtoken;
+
+
+att_type ::= CDATA;
+/.
+        case $rule_number: {
+            lastAttributeIsCData = true;
+        } break;
+./
+att_type ::= ID | IDREF | IDREFS | ENTITY | ENTITIES | NMTOKEN | NMTOKENS;
+att_type ::= LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+att_type ::= NOTATION LPAREN space_opt nmtoken_pipe_list space_opt RPAREN space;
+
+
+default_declhash ::= HASH;
+/.
+        case $rule_number:
+            if (!scanAfterDefaultDecl() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+default_decl ::= default_declhash REQUIRED;
+default_decl ::= default_declhash IMPLIED;
+default_decl ::= attribute_value;
+default_decl ::= default_declhash FIXED space attribute_value;
+attdef_start ::= space qname space;
+/.
+        case $rule_number:
+                sym(1) = sym(2);
+                lastAttributeValue.clear();
+                lastAttributeIsCData = false;
+                if (!scanAttType() && atEnd) {
+                    resume($rule_number);
+                    return false;
+                }
+        break;
+./
+
+attdef ::= attdef_start att_type default_decl;
+/.
+        case $rule_number: {
+            DtdAttribute &dtdAttribute = dtdAttributes.push();
+            dtdAttribute.tagName.clear();
+            dtdAttribute.isCDATA = lastAttributeIsCData;
+            dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
+            dtdAttribute.attributeName = addToStringStorage(symString(1));
+            dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
+            dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
+                                                 || (dtdAttribute.attributePrefix.isEmpty()
+                                                     && dtdAttribute.attributeName == QLatin1String("xmlns")));
+            if (lastAttributeValue.isNull()) {
+                dtdAttribute.defaultValue.clear();
+            } else {
+                if (dtdAttribute.isCDATA)
+                    dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
+                else
+                    dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
+
+            }
+        } break;
+./
+
+attdef_list ::= attdef;
+attdef_list ::= attdef_list attdef;
+
+attlist_decl ::= langle_bang ATTLIST qname space_opt RANGLE;
+attlist_decl ::= langle_bang ATTLIST qname attdef_list space_opt RANGLE;
+/.
+        case $rule_number: {
+            if (referenceToUnparsedEntityDetected && !standalone)
+                break;
+            int n = dtdAttributes.size();
+            QStringRef tagName = addToStringStorage(symName(3));
+            while (n--) {
+                DtdAttribute &dtdAttribute = dtdAttributes[n];
+                if (!dtdAttribute.tagName.isNull())
+                    break;
+                dtdAttribute.tagName = tagName;
+                for (int i = 0; i < n; ++i) {
+                    if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
+                        && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
+                        dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
+                        break;
+                    }
+                }
+            }
+        } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY name space;
+/.
+        case $rule_number: {
+            if (!scanPublicOrSystem() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            EntityDeclaration &entityDeclaration = entityDeclarations.push();
+            entityDeclaration.clear();
+            entityDeclaration.name = symString(3);
+        } break;
+./
+
+entity_decl_start ::= langle_bang ENTITY PERCENT space name space;
+/.
+        case $rule_number: {
+            if (!scanPublicOrSystem() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            EntityDeclaration &entityDeclaration = entityDeclarations.push();
+            entityDeclaration.clear();
+            entityDeclaration.name = symString(5);
+            entityDeclaration.parameter = true;
+        } break;
+./
+
+entity_decl_external ::= entity_decl_start SYSTEM literal;
+/.
+        case $rule_number: {
+            if (!scanNData() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            EntityDeclaration &entityDeclaration = entityDeclarations.top();
+            entityDeclaration.systemId = symString(3);
+            entityDeclaration.external = true;
+        } break;
+./
+
+entity_decl_external ::= entity_decl_start PUBLIC public_literal space literal;
+/.
+        case $rule_number: {
+            if (!scanNData() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            EntityDeclaration &entityDeclaration = entityDeclarations.top();
+            checkPublicLiteral((entityDeclaration.publicId = symString(3)));
+            entityDeclaration.systemId = symString(5);
+            entityDeclaration.external = true;
+        } break;
+./
+
+entity_decl ::= entity_decl_external NDATA name space_opt RANGLE;
+/.
+        case $rule_number: {
+            EntityDeclaration &entityDeclaration = entityDeclarations.top();
+            entityDeclaration.notationName = symString(3);
+            if (entityDeclaration.parameter)
+                raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
+        }
+        //fall through
+./
+
+entity_decl ::= entity_decl_external space_opt RANGLE;
+/.
+        case $rule_number:./
+
+entity_decl ::= entity_decl_start entity_value space_opt RANGLE;
+/.
+        case $rule_number: {
+            if (referenceToUnparsedEntityDetected && !standalone) {
+                entityDeclarations.pop();
+                break;
+            }
+            EntityDeclaration &entityDeclaration = entityDeclarations.top();
+            if (!entityDeclaration.external)
+                entityDeclaration.value = symString(2);
+            QString entityName = entityDeclaration.name.toString();
+            QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+            if (!hash.contains(entityName)) {
+                Entity entity(entityDeclaration.value.toString());
+                entity.unparsed = (!entityDeclaration.notationName.isNull());
+                entity.external = entityDeclaration.external;
+                hash.insert(entityName, entity);
+            }
+        } break;
+./
+
+
+processing_instruction ::= LANGLE QUESTIONMARK name space;
+/.
+        case $rule_number: {
+            setType(QXmlStreamReader::ProcessingInstruction);
+            int pos = sym(4).pos + sym(4).len;
+            processingInstructionTarget = symString(3);
+            if (scanUntil("?>")) {
+                processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
+                const QString piTarget(processingInstructionTarget.toString());
+                if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+                    raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
+                }
+                else if(!QXmlUtils::isNCName(piTarget))
+                    raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
+            } else if (type != QXmlStreamReader::Invalid){
+                resume($rule_number);
+                return false;
+            }
+        } break;
+./
+
+processing_instruction ::= LANGLE QUESTIONMARK name QUESTIONMARK RANGLE;
+/.
+        case $rule_number:
+            setType(QXmlStreamReader::ProcessingInstruction);
+            processingInstructionTarget = symString(3);
+            if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
+                raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
+        break;
+./
+
+
+langle_bang ::= LANGLE BANG;
+/.
+        case $rule_number:
+            if (!scanAfterLangleBang() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+comment_start ::= langle_bang DASH DASH;
+/.
+        case $rule_number:
+            if (!scanUntil("--")) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+comment ::= comment_start RANGLE;
+/.
+        case $rule_number: {
+            setType(QXmlStreamReader::Comment);
+            int pos = sym(1).pos + 4;
+            text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+        } break;
+./
+
+
+cdata ::= langle_bang CDATA_START;
+/.
+        case $rule_number: {
+            setType(QXmlStreamReader::Characters);
+            isCDATA = true;
+	    isWhitespace = false;
+            int pos = sym(2).pos;
+            if (scanUntil("]]>", -1)) {
+                text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+            } else {
+                resume($rule_number);
+                return false;
+            }
+        } break;
+./
+
+notation_decl_start ::= langle_bang NOTATION name space;
+/.
+        case $rule_number: {
+            if (!scanPublicOrSystem() && atEnd) {
+                resume($rule_number);
+                return false;
+            }
+            NotationDeclaration &notationDeclaration = notationDeclarations.push();
+            notationDeclaration.name = symString(3);
+        } break;
+./
+
+notation_decl ::= notation_decl_start SYSTEM literal space_opt RANGLE;
+/.
+        case $rule_number: {
+            NotationDeclaration &notationDeclaration = notationDeclarations.top();
+            notationDeclaration.systemId = symString(3);
+            notationDeclaration.publicId.clear();
+        } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space_opt RANGLE;
+/.
+        case $rule_number: {
+            NotationDeclaration &notationDeclaration = notationDeclarations.top();
+            notationDeclaration.systemId.clear();
+            checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+        } break;
+./
+
+notation_decl ::= notation_decl_start PUBLIC public_literal space literal space_opt RANGLE;
+/.
+        case $rule_number: {
+            NotationDeclaration &notationDeclaration = notationDeclarations.top();
+            checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+            notationDeclaration.systemId = symString(5);
+        } break;
+./
+
+
+
+content_char ::= RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG | QUOTE | DBLQUOTE | LETTER | DIGIT;
+
+scan_content_char ::= content_char;
+/.
+        case $rule_number:
+            isWhitespace = false;
+            // fall through
+./
+
+scan_content_char ::= SPACE;
+/.
+        case $rule_number:
+            sym(1).len += fastScanContentCharList();
+            if (atEnd && !inParseEntity) {
+                resume($rule_number);
+                return false;
+            }
+	break;
+./
+
+content_char_list ::= content_char_list char_ref;
+content_char_list ::= content_char_list entity_ref;
+content_char_list ::= content_char_list entity_done;
+content_char_list ::= content_char_list scan_content_char;
+content_char_list ::= char_ref;
+content_char_list ::= entity_ref;
+content_char_list ::= entity_done;
+content_char_list ::= scan_content_char;
+
+
+character_content ::= content_char_list %prec SHIFT_THERE;
+/.
+        case $rule_number:
+	    if (!textBuffer.isEmpty()) {
+                setType(QXmlStreamReader::Characters);
+                text = &textBuffer;
+	    }
+	break;
+./
+
+literal ::= QUOTE QUOTE;
+/.
+        case $rule_number:./
+literal ::= DBLQUOTE DBLQUOTE;
+/.
+        case $rule_number:
+            clearSym();
+        break;
+./
+literal ::= QUOTE literal_content_with_dblquote QUOTE;
+/.
+        case $rule_number:./
+literal ::= DBLQUOTE literal_content_with_quote DBLQUOTE;
+/.
+        case $rule_number:
+            sym(1) = sym(2);
+        break;
+./
+
+literal_content_with_dblquote ::= literal_content_with_dblquote literal_content;
+/.
+        case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote literal_content;
+/.
+        case $rule_number:./
+literal_content_with_dblquote ::= literal_content_with_dblquote DBLQUOTE;
+/.
+        case $rule_number:./
+literal_content_with_quote ::= literal_content_with_quote QUOTE;
+/.
+        case $rule_number:
+            sym(1).len += sym(2).len;
+        break;
+./
+literal_content_with_dblquote ::= literal_content;
+literal_content_with_quote ::= literal_content;
+literal_content_with_dblquote ::= DBLQUOTE;
+literal_content_with_quote ::= QUOTE;
+
+literal_content_start ::= LETTER | DIGIT | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | PERCENT | SLASH | COLON | SEMICOLON | COMMA | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+
+literal_content_start ::= SPACE;
+/.
+        case $rule_number:
+	    if (normalizeLiterals)
+                textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
+        break;
+./
+
+literal_content ::= literal_content_start;
+/.
+        case $rule_number:
+            sym(1).len += fastScanLiteralContent();
+            if (atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+
+public_literal ::= literal;
+/.
+        case $rule_number: {
+            if (!QXmlUtils::isPublicID(symString(1).toString())) {
+                raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
+                resume($rule_number);
+                return false;
+            }
+        } break;
+./
+
+entity_value ::= QUOTE QUOTE;
+/.
+        case $rule_number:./
+entity_value ::= DBLQUOTE DBLQUOTE;
+/.
+        case $rule_number:
+            clearSym();
+        break;
+./
+
+entity_value ::= QUOTE entity_value_content_with_dblquote QUOTE;
+/.
+        case $rule_number:./
+entity_value ::= DBLQUOTE entity_value_content_with_quote DBLQUOTE;
+/.
+        case $rule_number:
+	    sym(1) = sym(2);
+        break;
+./
+
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote entity_value_content;
+/.
+        case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote entity_value_content;
+/.
+        case $rule_number:./
+entity_value_content_with_dblquote ::= entity_value_content_with_dblquote DBLQUOTE;
+/.
+        case $rule_number:./
+entity_value_content_with_quote ::= entity_value_content_with_quote QUOTE;
+/.
+        case $rule_number:
+            sym(1).len += sym(2).len;
+        break;
+./
+entity_value_content_with_dblquote ::= entity_value_content;
+entity_value_content_with_quote ::= entity_value_content;
+entity_value_content_with_dblquote ::= DBLQUOTE;
+entity_value_content_with_quote ::= QUOTE;
+
+entity_value_content ::= LETTER | DIGIT | LANGLE | RANGLE | HASH | LBRACK | RBRACK | LPAREN | RPAREN | PIPE | EQ | SLASH | COLON | SEMICOLON | COMMA | SPACE | DASH | PLUS | STAR | DOT | QUESTIONMARK | BANG;
+entity_value_content ::= char_ref | entity_ref_in_entity_value | entity_done;
+
+
+attribute_value ::= QUOTE QUOTE;
+/.
+        case $rule_number:./
+attribute_value ::= DBLQUOTE DBLQUOTE;
+/.
+        case $rule_number:
+            clearSym();
+        break;
+./
+attribute_value ::= QUOTE attribute_value_content_with_dblquote QUOTE;
+/.
+        case $rule_number:./
+attribute_value ::= DBLQUOTE attribute_value_content_with_quote DBLQUOTE;
+/.
+        case $rule_number:
+            sym(1) = sym(2);
+            lastAttributeValue = symString(1);
+        break;
+./
+
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote attribute_value_content;
+/.
+        case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote attribute_value_content;
+/.
+        case $rule_number:./
+attribute_value_content_with_dblquote ::= attribute_value_content_with_dblquote DBLQUOTE;
+/.
+        case $rule_number:./
+attribute_value_content_with_quote ::= attribute_value_content_with_quote QUOTE;
+/.
+        case $rule_number:
+            sym(1).len += sym(2).len;
+        break;
+./
+attribute_value_content_with_dblquote ::= attribute_value_content | DBLQUOTE;
+attribute_value_content_with_quote ::= attribute_value_content | QUOTE;
+
+attribute_value_content ::= literal_content | char_ref | entity_ref_in_attribute_value | entity_done;
+
+attribute ::= qname space_opt EQ space_opt attribute_value;
+/.
+        case $rule_number: {
+            QStringRef prefix = symPrefix(1);
+            if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
+                NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+                namespaceDeclaration.prefix.clear();
+
+                const QStringRef ns(symString(5));
+                if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+                   ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+                    raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+                else
+                    namespaceDeclaration.namespaceUri = addToStringStorage(ns);
+            } else {
+                Attribute &attribute = attributeStack.push();
+                attribute.key = sym(1);
+                attribute.value = sym(5);
+
+                QStringRef attributeQualifiedName = symName(1);
+                bool normalize = false;
+                for (int a = 0; a < dtdAttributes.size(); ++a) {
+                    DtdAttribute &dtdAttribute = dtdAttributes[a];
+                    if (!dtdAttribute.isCDATA
+                        && dtdAttribute.tagName == qualifiedName
+                        && dtdAttribute.attributeQualifiedName == attributeQualifiedName
+                        ) {
+                        normalize = true;
+                        break;
+                    }
+                }
+                if (normalize) {
+                    // normalize attribute value (simplify and trim)
+                    int pos = textBuffer.size();
+                    int n = 0;
+                    bool wasSpace = true;
+                    for (int i = 0; i < attribute.value.len; ++i) {
+                        QChar c = textBuffer.at(attribute.value.pos + i);
+                        if (c.unicode() == ' ') {
+                            if (wasSpace)
+                                continue;
+                            wasSpace = true;
+                        } else {
+                            wasSpace = false;
+                        }
+                        textBuffer += textBuffer.at(attribute.value.pos + i);
+                        ++n;
+                    }
+                    if (wasSpace)
+                        while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
+                            --n;
+                    attribute.value.pos = pos;
+                    attribute.value.len = n;
+                }
+                if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
+                    NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+                    QStringRef namespacePrefix = symString(attribute.key);
+                    QStringRef namespaceUri = symString(attribute.value);
+                    attributeStack.pop();
+                    if (((namespacePrefix == QLatin1String("xml"))
+                         ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+                        || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+                        || namespaceUri.isEmpty()
+                        || namespacePrefix == QLatin1String("xmlns"))
+                        raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+                    namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
+                    namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+                }
+            }
+        } break;
+./
+
+
+
+attribute_list_opt ::= | space | space attribute_list space_opt;
+attribute_list ::= attribute | attribute_list space attribute;
+
+stag_start ::= LANGLE qname;
+/.
+        case $rule_number: {
+            normalizeLiterals = true;
+            Tag &tag = tagStack_push();
+            prefix = tag.namespaceDeclaration.prefix  = addToStringStorage(symPrefix(2));
+            name = tag.name = addToStringStorage(symString(2));
+            qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
+            if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
+                raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
+        } break;
+./
+
+
+empty_element_tag ::= stag_start attribute_list_opt SLASH RANGLE;
+/.
+        case $rule_number:
+            isEmptyElement = true;
+        // fall through
+./
+
+
+stag ::= stag_start attribute_list_opt RANGLE;
+/.
+        case $rule_number:
+            setType(QXmlStreamReader::StartElement);
+            resolveTag();
+            if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
+                raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+            hasSeenTag = true;
+        break;
+./
+
+
+etag ::= LANGLE SLASH qname space_opt RANGLE;
+/.
+        case $rule_number: {
+            setType(QXmlStreamReader::EndElement);
+            Tag &tag = tagStack_pop();
+
+            namespaceUri = tag.namespaceDeclaration.namespaceUri;
+            name = tag.name;
+            qualifiedName = tag.qualifiedName;
+            if (qualifiedName != symName(3))
+                raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
+        } break;
+./
+
+
+unresolved_entity ::= UNRESOLVED_ENTITY;
+/.
+        case $rule_number:
+            if (entitiesMustBeDeclared()) {
+                raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
+                break;
+            }
+            setType(QXmlStreamReader::EntityReference);
+            name = &unresolvedEntity;
+	break;
+./
+
+entity_ref ::= AMPERSAND name SEMICOLON;
+/.
+        case $rule_number: {
+            sym(1).len += sym(2).len + 1;
+            QString reference = symString(2).toString();
+            if (entityHash.contains(reference)) {
+                Entity &entity = entityHash[reference];
+                if (entity.unparsed) {
+                    raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
+                } else {
+                    if (!entity.hasBeenParsed) {
+                        parseEntity(entity.value);
+                        entity.hasBeenParsed = true;
+                    }
+                    if (entity.literal)
+                        putStringLiteral(entity.value);
+                    else if (referenceEntity(entity))
+                        putReplacement(entity.value);
+                    textBuffer.chop(2 + sym(2).len);
+                    clearSym();
+                }
+                break;
+            }
+
+            if (entityResolver) {
+                QString replacementText = resolveUndeclaredEntity(reference);
+                if (!replacementText.isNull()) {
+                    putReplacement(replacementText);
+                    textBuffer.chop(2 + sym(2).len);
+                    clearSym();
+                    break;
+                }
+            }
+
+	    injectToken(UNRESOLVED_ENTITY);
+	    unresolvedEntity = symString(2).toString();
+	    textBuffer.chop(2 + sym(2).len);
+	    clearSym();
+
+        } break;
+./
+
+pereference ::= PERCENT name SEMICOLON;
+/.
+        case $rule_number: {
+            sym(1).len += sym(2).len + 1;
+            QString reference = symString(2).toString();
+            if (parameterEntityHash.contains(reference)) {
+                referenceToParameterEntityDetected = true;
+                Entity &entity = parameterEntityHash[reference];
+                if (entity.unparsed || entity.external) {
+                    referenceToUnparsedEntityDetected = true;
+                } else {
+                    if (referenceEntity(entity))
+                        putString(entity.value);
+                    textBuffer.chop(2 + sym(2).len);
+                    clearSym();
+                }
+            } else if (entitiesMustBeDeclared()) {
+                raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
+            }
+        } break;
+./
+
+
+
+entity_ref_in_entity_value ::= AMPERSAND name SEMICOLON;
+/.
+        case $rule_number:
+            sym(1).len += sym(2).len + 1;
+        break;
+./
+
+entity_ref_in_attribute_value ::= AMPERSAND name SEMICOLON;
+/.
+        case $rule_number: {
+            sym(1).len += sym(2).len + 1;
+            QString reference = symString(2).toString();
+            if (entityHash.contains(reference)) {
+                Entity &entity = entityHash[reference];
+                if (entity.unparsed || entity.value.isNull()) {
+                    raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
+                    break;
+                }
+                if (!entity.hasBeenParsed) {
+                    parseEntity(entity.value);
+                    entity.hasBeenParsed = true;
+                }
+                if (entity.literal)
+                    putStringLiteral(entity.value);
+                else if (referenceEntity(entity))
+                    putReplacementInAttributeValue(entity.value);
+                textBuffer.chop(2 + sym(2).len);
+                clearSym();
+                break;
+            }
+
+            if (entityResolver) {
+                QString replacementText = resolveUndeclaredEntity(reference);
+                if (!replacementText.isNull()) {
+                    putReplacement(replacementText);
+                    textBuffer.chop(2 + sym(2).len);
+                    clearSym();
+                    break;
+                }
+            }
+            if (entitiesMustBeDeclared()) {
+                raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
+            }
+        } break;
+./
+
+char_ref ::= AMPERSAND HASH char_ref_value SEMICOLON;
+/.
+        case $rule_number: {
+            if (uint s = resolveCharRef(3)) {
+                if (s >= 0xffff)
+                    putStringLiteral(QString::fromUcs4(&s, 1));
+                else
+                    putChar((LETTER << 16) | s);
+
+                textBuffer.chop(3 + sym(3).len);
+                clearSym();
+            } else {
+                raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
+            }
+        } break;
+./
+
+
+char_ref_value ::= LETTER | DIGIT;
+char_ref_value ::= char_ref_value LETTER;
+/.
+        case $rule_number:./
+char_ref_value ::= char_ref_value DIGIT;
+/.
+        case $rule_number:
+            sym(1).len += sym(2).len;
+        break;
+./
+
+
+content ::= content character_content;
+content ::= content stag content etag;
+content ::= content empty_element_tag;
+content ::= content comment;
+content ::= content cdata;
+content ::= content xml_decl;
+content ::= content processing_instruction;
+content ::= content doctype_decl;
+content ::= content unresolved_entity;
+content ::=  ;
+
+
+space ::=  SPACE;
+/.
+        case $rule_number:
+            sym(1).len += fastScanSpace();
+            if (atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+
+space_opt ::=;
+space_opt ::= space;
+
+qname ::= LETTER;
+/.
+        case $rule_number: {
+            sym(1).len += fastScanName(&sym(1).prefix);
+            if (atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        } break;
+./
+
+name ::= LETTER;
+/.
+        case $rule_number:
+            sym(1).len += fastScanName();
+            if (atEnd) {
+                resume($rule_number);
+                return false;
+            }
+        break;
+./
+
+nmtoken ::= LETTER;
+/.
+        case $rule_number:./
+nmtoken ::= DIGIT;
+/.
+        case $rule_number:./
+nmtoken ::= DOT;
+/.
+        case $rule_number:./
+nmtoken ::= DASH;
+/.
+        case $rule_number:./
+nmtoken ::= COLON;
+/.
+        case $rule_number:
+            sym(1).len += fastScanNMTOKEN();
+            if (atEnd) {
+                resume($rule_number);
+                return false;
+            }
+
+        break;
+./
+
+
+/.
+    default:
+        ;
+    } // switch
+            act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
+            if (type != QXmlStreamReader::NoToken)
+                return true;
+        } else {
+            parseError();
+            break;
+        }
+    }
+    return false;
+}
+./