OSDN Git Service

QmlJS: Merge parser updates from Qt5.
authorChristian Kamm <christian.d.kamm@nokia.com>
Tue, 13 Sep 2011 06:42:52 +0000 (08:42 +0200)
committerChristian Kamm <christian.d.kamm@nokia.com>
Wed, 14 Sep 2011 09:48:11 +0000 (11:48 +0200)
Change-Id: Ibed38abca8f7e7bae7d424751a18c83f4c9e9bc5
Reviewed-on: http://codereview.qt-project.org/4732
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
19 files changed:
src/libs/qmljs/parser/cmd.sed
src/libs/qmljs/parser/gen-parser.sh
src/libs/qmljs/parser/parser.pri
src/libs/qmljs/parser/qmldirparser.cpp
src/libs/qmljs/parser/qmldirparser_p.h
src/libs/qmljs/parser/qmljs.g
src/libs/qmljs/parser/qmljsast_p.h
src/libs/qmljs/parser/qmljsengine_p.cpp
src/libs/qmljs/parser/qmljsengine_p.h
src/libs/qmljs/parser/qmljsgrammar.cpp
src/libs/qmljs/parser/qmljsgrammar_p.h
src/libs/qmljs/parser/qmljskeywords_p.h [new file with mode: 0644]
src/libs/qmljs/parser/qmljslexer.cpp
src/libs/qmljs/parser/qmljslexer_p.h
src/libs/qmljs/parser/qmljsmemorypool_p.h
src/libs/qmljs/parser/qmljsnodepool_p.h [deleted file]
src/libs/qmljs/parser/qmljsparser.cpp
src/libs/qmljs/parser/qmljsparser_p.h
src/libs/qmljs/parser/qmlutils_p.h [new file with mode: 0644]

index d763726..c5ba8b0 100644 (file)
@@ -7,6 +7,7 @@ s/Q_DECLARATIVE_EXPORT //g
 # adjust pri file
 s/    \$\$PWD\/qmljsglobal_p.h/    $$PWD\/qmljsglobal_p.h \\\
     $$PWD\/qmldirparser_p.h \\\
+    $$PWD\/qmlutils_p.h \\\
     $$PWD\/qmlerror.h/
 s/    \$\$PWD\/qmljsparser.cpp/    $$PWD\/qmljsparser.cpp \\\
     $$PWD\/qmldirparser.cpp \\\
index 1565e26..1995ad9 100755 (executable)
@@ -10,8 +10,14 @@ for i in $QTDIR/src/declarative/qml/qdeclarative{error.{h,cpp},dirparser{_p.h,.c
     sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qdeclarative/qml/)
 done
 
+for i in $QTDIR/src/declarative/qml/ftw/qdeclarativeutils_p.h; do
+    sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qdeclarative/qml/)
+done
+
 # export QmlDirParser
 perl -p -0777 -i -e 's/QT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QmlDirParser/#include "qmljsglobal_p.h"\n\nQT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QML_PARSER_EXPORT QmlDirParser/' qmldirparser_p.h
+# replace qmlglobal_p.h include with needed declaration
+perl -p -0777 -i -e 's/#include \<qmlglobal_p.h\>/bool Qml_isFileCaseCorrect(const QString &) { return true; }/' qmldirparser.cpp
 
 ./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h}
 
index 849f306..289275d 100644 (file)
@@ -8,11 +8,12 @@ HEADERS += \
     $$PWD/qmljsgrammar_p.h \
     $$PWD/qmljslexer_p.h \
     $$PWD/qmljsmemorypool_p.h \
-    $$PWD/qmljsnodepool_p.h \
     $$PWD/qmljsparser_p.h \
     $$PWD/qmljsglobal_p.h \
     $$PWD/qmldirparser_p.h \
-    $$PWD/qmlerror.h
+    $$PWD/qmlutils_p.h \
+    $$PWD/qmlerror.h \
+    $$PWD/qmljskeywords_p.h
 
 SOURCES += \
     $$PWD/qmljsast.cpp \
index 5bb1061..3914ebc 100644 (file)
 
 #include "qmldirparser_p.h"
 #include "qmlerror.h"
+bool Qml_isFileCaseCorrect(const QString &) { return true; }
+#include <qmlutils_p.h>
 
 #include <QtCore/QTextStream>
+#include <QtCore/QFile>
 #include <QtCore/QtDebug>
 
 QT_BEGIN_NAMESPACE
@@ -57,6 +60,16 @@ void QmlDirParser::setUrl(const QUrl &url)
     _url = url;
 }
 
+QString QmlDirParser::fileSource() const
+{
+    return _filePathSouce;
+}
+
+void QmlDirParser::setFileSource(const QString &filePath)
+{
+    _filePathSouce = filePath;
+}
+
 QString QmlDirParser::source() const
 {
     return _source;
@@ -83,6 +96,23 @@ bool QmlDirParser::parse()
     _plugins.clear();
     _components.clear();
 
+    if (_source.isEmpty() && !_filePathSouce.isEmpty()) {
+        QFile file(_filePathSouce);
+        if (!Qml_isFileCaseCorrect(_filePathSouce)) {
+            QmlError error;
+            error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce));
+            _errors.prepend(error);
+            return false;
+        } else if (file.open(QFile::ReadOnly)) {
+            _source = QString::fromUtf8(file.readAll());
+        } else {
+            QmlError error;
+            error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce));
+            _errors.prepend(error);
+            return false;
+        }
+    }
+
     QTextStream stream(&_source);
     int lineNumber = 0;
 
@@ -102,9 +132,9 @@ bool QmlDirParser::parse()
         while (index != length) {
             const QChar ch = line.at(index);
 
-            if (ch.isSpace()) {
+            if (QmlUtils::isSpace(ch)) {
                 do { ++index; }
-                while (index != length && line.at(index).isSpace());
+                while (index != length && QmlUtils::isSpace(line.at(index)));
 
             } else if (ch == QLatin1Char('#')) {
                 // recognized a comment
@@ -114,7 +144,7 @@ bool QmlDirParser::parse()
                 const int start = index;
 
                 do { ++index; }
-                while (index != length && !line.at(index).isSpace());
+                while (index != length && !QmlUtils::isSpace(line.at(index)));
 
                 const QString lexeme = line.mid(start, index - start);
 
@@ -148,7 +178,7 @@ bool QmlDirParser::parse()
                             QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
                 continue;
             }
-            Component entry(sections[1], sections[2], -1, -1);
+            Component entry(sections[1].toUtf8(), sections[2], -1, -1);
             entry.internal = true;
             _components.append(entry);
         } else if (sections[0] == QLatin1String("typeinfo")) {
@@ -164,7 +194,7 @@ bool QmlDirParser::parse()
 
         } else if (sectionCount == 2) {
             // No version specified (should only be used for relative qmldir files)
-            const Component entry(sections[0], sections[1], -1, -1);
+            const Component entry(sections[0].toUtf8(), sections[1], -1, -1);
             _components.append(entry);
         } else if (sectionCount == 3) {
             const QString &version = sections[1];
@@ -182,7 +212,7 @@ bool QmlDirParser::parse()
                     const int minorVersion = version.mid(dotIndex + 1).toInt(&validVersionNumber);
 
                     if (validVersionNumber) {
-                        const Component entry(sections[0], sections[2], majorVersion, minorVersion);
+                        const Component entry(sections[0].toUtf8(), sections[2], majorVersion, minorVersion);
 
                         _components.append(entry);
                     }
@@ -215,9 +245,16 @@ bool QmlDirParser::hasError() const
     return false;
 }
 
-QList<QmlError> QmlDirParser::errors() const
+QList<QmlError> QmlDirParser::errors(const QString &uri) const
 {
-    return _errors;
+    QList<QmlError> errors = _errors;
+    for (int i = 0; i < errors.size(); ++i) {
+        QmlError &e = errors[i];
+        QString description = e.description();
+        description.replace(QLatin1String("$$URI$$"), uri);
+        e.setDescription(description);
+    }
+    return errors;
 }
 
 QList<QmlDirParser::Plugin> QmlDirParser::plugins() const
index bdae66f..0d7ef51 100644 (file)
@@ -63,6 +63,9 @@ public:
     QUrl url() const;
     void setUrl(const QUrl &url);
 
+    QString fileSource() const;
+    void setFileSource(const QString &filePath);
+
     QString source() const;
     void setSource(const QString &source);
 
@@ -70,7 +73,7 @@ public:
     bool parse();
 
     bool hasError() const;
-    QList<QmlError> errors() const;
+    QList<QmlError> errors(const QString &uri) const;
 
     struct Plugin
     {
@@ -88,11 +91,11 @@ public:
         Component()
             : majorVersion(0), minorVersion(0), internal(false) {}
 
-        Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
+        Component(const QByteArray &typeName, const QString &fileName, int majorVersion, int minorVersion)
             : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
             internal(false) {}
 
-        QString typeName;
+        QByteArray typeName;
         QString fileName;
         int majorVersion;
         int minorVersion;
@@ -122,6 +125,7 @@ private:
     QList<QmlError> _errors;
     QUrl _url;
     QString _source;
+    QString _filePathSouce;
     QList<Component> _components;
     QList<Plugin> _plugins;
 #ifdef QT_CREATOR
index 10dd418..1542c2d 100644 (file)
@@ -38,7 +38,7 @@
 
 %token T_AND "&"                T_AND_AND "&&"              T_AND_EQ "&="
 %token T_BREAK "break"          T_CASE "case"               T_CATCH "catch"
-%token T_COLON ":"              T_COMMA ";"                 T_CONTINUE "continue"
+%token T_COLON ":"              T_COMMA ","                 T_CONTINUE "continue"
 %token T_DEFAULT "default"      T_DELETE "delete"           T_DIVIDE_ "/"
 %token T_DIVIDE_EQ "/="         T_DO "do"                   T_DOT "."
 %token T_ELSE "else"            T_EQ "="                    T_EQ_EQ "=="
@@ -76,6 +76,8 @@
 %token T_AS "as"
 %token T_ON "on"
 
+%token T_ERROR
+
 --- feed tokens
 %token T_FEED_UI_PROGRAM
 %token T_FEED_UI_OBJECT_MEMBER
 #include "qmljsengine_p.h"
 #include "qmljslexer_p.h"
 #include "qmljsast_p.h"
-#include "qmljsnodepool_p.h"
+#include "qmljsmemorypool_p.h"
 
 ./
 
@@ -199,7 +201,6 @@ QT_QML_BEGIN_NAMESPACE
 namespace QmlJS {
 
 class Engine;
-class NameId;
 
 class QML_PARSER_EXPORT Parser: protected $table
 {
@@ -207,7 +208,6 @@ public:
     union Value {
       int ival;
       double dval;
-      NameId *sval;
       AST::ArgumentList *ArgumentList;
       AST::CaseBlock *CaseBlock;
       AST::CaseClause *CaseClause;
@@ -323,6 +323,9 @@ protected:
     inline Value &sym(int index)
     { return sym_stack [tos + index - 1]; }
 
+    inline QStringRef &stringRef(int index)
+    { return string_stack [tos + index - 1]; }
+
     inline AST::SourceLocation &loc(int index)
     { return location_stack [tos + index - 1]; }
 
@@ -330,11 +333,13 @@ protected:
 
 protected:
     Engine *driver;
+    MemoryPool *pool;
     int tos;
     int stack_size;
     Value *sym_stack;
     int *state_stack;
     AST::SourceLocation *location_stack;
+    QStringRef *string_stack;
 
     AST::Node *program;
 
@@ -345,9 +350,11 @@ protected:
        int token;
        double dval;
        AST::SourceLocation loc;
+       QStringRef spell;
     };
 
     double yylval;
+    QStringRef yytokenspell;
     AST::SourceLocation yylloc;
     AST::SourceLocation yyprevlloc;
 
@@ -388,6 +395,7 @@ void Parser::reallocateStack()
     sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
     state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
     location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
+    string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef)));
 }
 
 inline static bool automatic(Engine *driver, int token)
@@ -400,11 +408,13 @@ inline static bool automatic(Engine *driver, int token)
 
 Parser::Parser(Engine *engine):
     driver(engine),
+    pool(engine->pool()),
     tos(0),
     stack_size(0),
     sym_stack(0),
     state_stack(0),
     location_stack(0),
+    string_stack(0),
     first_token(0),
     last_token(0)
 {
@@ -416,6 +426,7 @@ Parser::~Parser()
         qFree(sym_stack);
         qFree(state_stack);
         qFree(location_stack);
+        qFree(string_stack);
     }
 }
 
@@ -424,14 +435,14 @@ static inline AST::SourceLocation location(Lexer *lexer)
     AST::SourceLocation loc;
     loc.offset = lexer->tokenOffset();
     loc.length = lexer->tokenLength();
-    loc.startLine = lexer->startLineNo();
-    loc.startColumn = lexer->startColumnNo();
+    loc.startLine = lexer->tokenStartLine();
+    loc.startColumn = lexer->tokenStartColumn();
     return loc;
 }
 
 AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
 {
-    QVarLengthArray<NameId *, 4> nameIds;
+    QVarLengthArray<QStringRef, 4> nameIds;
     QVarLengthArray<AST::SourceLocation, 4> locations;
 
     AST::ExpressionNode *it = expr;
@@ -442,12 +453,12 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
     }
 
     if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) {
-        AST::UiQualifiedId *q = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), idExpr->name);
+        AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name);
         q->identifierToken = idExpr->identifierToken;
 
         AST::UiQualifiedId *currentId = q;
         for (int i = nameIds.size() - 1; i != -1; --i) {
-            currentId = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), currentId, nameIds[i]);
+            currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]);
             currentId->identifierToken = locations[i];
         }
 
@@ -483,11 +494,13 @@ bool Parser::parse(int startToken)
 
             if (first_token == last_token) {
                 yytoken = lexer->lex();
-                yylval = lexer->dval();
+                yylval = lexer->tokenValue();
+                yytokenspell = lexer->tokenSpell();
                 yylloc = location(lexer);
             } else {
                 yytoken = first_token->token;
                 yylval = first_token->dval;
+                yytokenspell = first_token->spell;
                 yylloc = first_token->loc;
                 ++first_token;
             }
@@ -498,6 +511,7 @@ bool Parser::parse(int startToken)
             if (action != ACCEPT_STATE) {
                 yytoken = -1;
                 sym(1).dval = yylval;
+                stringRef(1) = yytokenspell;
                 loc(1) = yylloc;
             } else {
               --tos;
@@ -565,7 +579,7 @@ case $rule_number: {
 UiProgram: UiImportListOpt UiRootMember ;
 /.
 case $rule_number: {
-  sym(1).UiProgram = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiImportList,
+  sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiImportList,
         sym(2).UiObjectMemberList->finish());
 } break;
 ./
@@ -581,15 +595,14 @@ case $rule_number: {
 UiImportList: UiImport ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(), sym(1).UiImport);
+    sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImport);
 } break;
 ./
 
 UiImportList: UiImportList UiImport ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(),
-        sym(1).UiImportList, sym(2).UiImport);
+    sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImportList, sym(2).UiImport);
 } break;
 ./
 
@@ -619,7 +632,7 @@ case $rule_number: {
     sym(1).UiImport->versionToken = loc(2);
     sym(1).UiImport->asToken = loc(3);
     sym(1).UiImport->importIdToken = loc(4);
-    sym(1).UiImport->importId = sym(4).sval;
+    sym(1).UiImport->importId = stringRef(4);
     sym(1).UiImport->semicolonToken = loc(5);
 } break;
 ./
@@ -630,7 +643,7 @@ UiImport: UiImportHead T_AS JsIdentifier T_SEMICOLON ;
 case $rule_number: {
     sym(1).UiImport->asToken = loc(2);
     sym(1).UiImport->importIdToken = loc(3);
-    sym(1).UiImport->importId = sym(3).sval;
+    sym(1).UiImport->importId = stringRef(3);
     sym(1).UiImport->semicolonToken = loc(4);
 } break;
 ./
@@ -642,10 +655,10 @@ case $rule_number: {
     AST::UiImport *node = 0;
 
     if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
-        node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
+        node = new (pool) AST::UiImport(importIdLiteral->value);
         node->fileNameToken = loc(2);
     } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
-        node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
+        node = new (pool) AST::UiImport(qualifiedId);
         node->fileNameToken = loc(2);
     }
 
@@ -672,21 +685,21 @@ case $rule_number: {
 UiRootMember: UiObjectDefinition ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
 } break;
 ./
 
 UiObjectMemberList: UiObjectMember ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
 } break;
 ./
 
 UiObjectMemberList: UiObjectMemberList UiObjectMember ;
 /.
 case $rule_number: {
-    AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
+    AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
         sym(1).UiObjectMemberList, sym(2).UiObjectMember);
     sym(1).Node = node;
 } break;
@@ -695,14 +708,14 @@ case $rule_number: {
 UiArrayMemberList: UiObjectDefinition ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
 } break;
 ./
 
 UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ;
 /.
 case $rule_number: {
-    AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+    AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
         sym(1).UiArrayMemberList, sym(3).UiObjectMember);
     node->commaToken = loc(2);
     sym(1).Node = node;
@@ -712,7 +725,7 @@ case $rule_number: {
 UiObjectInitializer: T_LBRACE T_RBRACE ;
 /.
 case $rule_number: {
-    AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), (AST::UiObjectMemberList*)0);
+    AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
     node->lbraceToken = loc(1);
     node->rbraceToken = loc(2);
     sym(1).Node = node;
@@ -722,7 +735,7 @@ case $rule_number: {
 UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ;
 /.
 case $rule_number: {
-    AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish());
+    AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
     node->lbraceToken = loc(1);
     node->rbraceToken = loc(3);
     sym(1).Node = node;
@@ -732,7 +745,7 @@ case $rule_number: {
 UiObjectDefinition: UiQualifiedId UiObjectInitializer ;
 /.
 case $rule_number: {
-    AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).UiQualifiedId,
+    AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
         sym(2).UiObjectInitializer);
     sym(1).Node = node;
 }   break;
@@ -743,7 +756,7 @@ UiObjectMember: UiObjectDefinition ;
 UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
 /.
 case $rule_number: {
-    AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+    AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
         sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
     node->colonToken = loc(2);
     node->lbracketToken = loc(3);
@@ -755,7 +768,7 @@ case $rule_number: {
 UiObjectMember: UiQualifiedId             T_COLON UiQualifiedId  UiObjectInitializer ;
 /.
 case $rule_number: {
-    AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
       sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
     node->colonToken = loc(2);
     sym(1).Node = node;
@@ -765,7 +778,7 @@ case $rule_number: {
 UiObjectMember: UiQualifiedId             T_ON UiQualifiedId  UiObjectInitializer ;
 /.
 case $rule_number: {
-    AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
       sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
     node->colonToken = loc(2);
     node->hasOnToken = true;
@@ -782,7 +795,7 @@ UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ;
 /.
 case $rule_number:
 {
-    AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
+    AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
         sym(1).UiQualifiedId, sym(3).Statement);
     node->colonToken = loc(2);
     sym(1).Node = node;
@@ -790,17 +803,7 @@ case $rule_number:
 ./
 
 UiPropertyType: T_VAR ;
-/.
-case $rule_number:
-./
 UiPropertyType: T_RESERVED_WORD ;
-/.
-case $rule_number: {
-    sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-    break;
-}
-./
-
 UiPropertyType: T_IDENTIFIER ;
 
 UiParameterListOpt: ;
@@ -820,7 +823,7 @@ case $rule_number: {
 UiParameterList: UiPropertyType JsIdentifier ;
 /.
 case $rule_number: {
-  AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).sval, sym(2).sval);
+  AST::UiParameterList *node = new (pool) AST::UiParameterList(stringRef(1), stringRef(2));
   node->identifierToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -829,7 +832,7 @@ case $rule_number: {
 UiParameterList: UiParameterList T_COMMA UiPropertyType JsIdentifier ;
 /.
 case $rule_number: {
-  AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).UiParameterList, sym(3).sval, sym(4).sval);
+  AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, stringRef(3), stringRef(4));
   node->commaToken = loc(2);
   node->identifierToken = loc(4);
   sym(1).Node = node;
@@ -840,7 +843,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUT
 UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
     node->type = AST::UiPublicMember::Signal;
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -855,7 +858,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON ;
 UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
     node->type = AST::UiPublicMember::Signal;
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -869,8 +872,8 @@ UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_
 UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
-    node->typeModifier = sym(2).sval;
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+    node->typeModifier = stringRef(2);
     node->propertyToken = loc(1);
     node->typeModifierToken = loc(2);
     node->typeToken = loc(4);
@@ -884,7 +887,7 @@ UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ;
 UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
     node->identifierToken = loc(3);
@@ -897,7 +900,7 @@ UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEM
 UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
     node->isDefaultMember = true;
     node->defaultToken = loc(1);
     node->propertyToken = loc(2);
@@ -911,7 +914,7 @@ case $rule_number: {
 UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3),
         sym(5).Statement);
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -924,7 +927,7 @@ case $rule_number: {
 UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
         sym(6).Statement);
     node->isReadonlyMember = true;
     node->readonlyToken = loc(1);
@@ -939,7 +942,7 @@ case $rule_number: {
 UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
         sym(6).Statement);
     node->isDefaultMember = true;
     node->defaultToken = loc(1);
@@ -954,19 +957,19 @@ case $rule_number: {
 UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
-    node->typeModifier = sym(2).sval;
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+    node->typeModifier = stringRef(2);
     node->propertyToken = loc(1);
     node->typeModifierToken = loc(2);
     node->typeToken = loc(4);
     node->identifierToken = loc(6);
     node->semicolonToken = loc(7); // insert a fake ';' before ':'
 
-    AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(6).sval);
+    AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
     propertyName->identifierToken = loc(6);
     propertyName->next = 0;
 
-    AST::UiArrayBinding *binding = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+    AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
         propertyName, sym(9).UiArrayMemberList->finish());
     binding->colonToken = loc(7);
     binding->lbracketToken = loc(8);
@@ -981,17 +984,17 @@ case $rule_number: {
 UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
 /.
 case $rule_number: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
     node->identifierToken = loc(3);
     node->semicolonToken = loc(4); // insert a fake ';' before ':'
 
-    AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(3).sval);
+    AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
     propertyName->identifierToken = loc(3);
     propertyName->next = 0;
 
-    AST::UiObjectBinding *binding = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
       propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
     binding->colonToken = loc(4);
 
@@ -1004,54 +1007,23 @@ case $rule_number: {
 UiObjectMember: FunctionDeclaration ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+    sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
 }   break;
 ./
 
 UiObjectMember: VariableStatement ;
 /.
 case $rule_number: {
-    sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+    sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
 }   break;
 ./
 
 JsIdentifier: T_IDENTIFIER;
 
 JsIdentifier: T_PROPERTY ;
-/.
-case $rule_number: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_PROPERTY]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-./
-
 JsIdentifier: T_SIGNAL ;
-/.
-case $rule_number: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_SIGNAL]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-./
-
 JsIdentifier: T_READONLY ;
-/.
-case $rule_number: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_READONLY]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-./
-
 JsIdentifier: T_ON ;
-/.
-case $rule_number: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_ON]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-./
 
 --------------------------------------------------------------------------------------------------------
 -- Expressions
@@ -1060,7 +1032,7 @@ case $rule_number: {
 PrimaryExpression: T_THIS ;
 /.
 case $rule_number: {
-  AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool());
+  AST::ThisExpression *node = new (pool) AST::ThisExpression();
   node->thisToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1069,7 +1041,7 @@ case $rule_number: {
 PrimaryExpression: JsIdentifier ;
 /.
 case $rule_number: {
-  AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1078,7 +1050,7 @@ case $rule_number: {
 PrimaryExpression: T_NULL ;
 /.
 case $rule_number: {
-  AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool());
+  AST::NullExpression *node = new (pool) AST::NullExpression();
   node->nullToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1087,7 +1059,7 @@ case $rule_number: {
 PrimaryExpression: T_TRUE ;
 /.
 case $rule_number: {
-  AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool());
+  AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
   node->trueToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1096,7 +1068,7 @@ case $rule_number: {
 PrimaryExpression: T_FALSE ;
 /.
 case $rule_number: {
-  AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool());
+  AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
   node->falseToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1105,7 +1077,7 @@ case $rule_number: {
 PrimaryExpression: T_NUMERIC_LITERAL ;
 /.
 case $rule_number: {
-  AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
+  AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1117,7 +1089,7 @@ PrimaryExpression: T_MULTILINE_STRING_LITERAL ;
 PrimaryExpression: T_STRING_LITERAL ;
 /.
 case $rule_number: {
-  AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval);
+  AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1137,7 +1109,8 @@ case $rule_number: {
 
   loc(1).length = lexer->tokenLength();
 
-  AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+  AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+    driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1157,7 +1130,8 @@ case $rule_number: {
 
   loc(1).length = lexer->tokenLength();
 
-  AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+  AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+    driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1166,7 +1140,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACKET T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), (AST::Elision *) 0);
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(2);
   sym(1).Node = node;
@@ -1176,7 +1150,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACKET Elision T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision->finish());
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(3);
   sym(1).Node = node;
@@ -1186,7 +1160,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(3);
   sym(1).Node = node;
@@ -1196,7 +1170,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACKET ElementList T_COMMA T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
     (AST::Elision *) 0);
   node->lbracketToken = loc(1);
   node->commaToken = loc(3);
@@ -1208,7 +1182,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACKET ElementList T_COMMA Elision T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
     sym(4).Elision->finish());
   node->lbracketToken = loc(1);
   node->commaToken = loc(3);
@@ -1220,7 +1194,7 @@ case $rule_number: {
 -- PrimaryExpression: T_LBRACE T_RBRACE ;
 -- /.
 -- case $rule_number: {
---   sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+--   sym(1).Node = new (pool) AST::ObjectLiteral();
 -- } break;
 -- ./
 
@@ -1229,10 +1203,10 @@ PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
 case $rule_number: {
   AST::ObjectLiteral *node = 0;
   if (sym(2).Node)
-    node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+    node = new (pool) AST::ObjectLiteral(
         sym(2).PropertyNameAndValueList->finish ());
   else
-    node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+    node = new (pool) AST::ObjectLiteral();
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
@@ -1242,7 +1216,7 @@ case $rule_number: {
 PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ;
 /.
 case $rule_number: {
-  AST::ObjectLiteral *node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+  AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
     sym(2).PropertyNameAndValueList->finish ());
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(4);
@@ -1253,7 +1227,7 @@ case $rule_number: {
 PrimaryExpression: T_LPAREN Expression T_RPAREN ;
 /.
 case $rule_number: {
-  AST::NestedExpression *node = makeAstNode<AST::NestedExpression>(driver->nodePool(), sym(2).Expression);
+  AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
   node->lparenToken = loc(1);
   node->rparenToken = loc(3);
   sym(1).Node = node;
@@ -1286,21 +1260,21 @@ case $rule_number: {
 ElementList: AssignmentExpression ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression);
+  sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
 } break;
 ./
 
 ElementList: Elision AssignmentExpression ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression);
+  sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
 } break;
 ./
 
 ElementList: ElementList T_COMMA AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList,
+  AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
     (AST::Elision *) 0, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
@@ -1310,7 +1284,7 @@ case $rule_number: {
 ElementList: ElementList T_COMMA Elision AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(),
+  AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
     sym(4).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
@@ -1320,7 +1294,7 @@ case $rule_number: {
 Elision: T_COMMA ;
 /.
 case $rule_number: {
-  AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool());
+  AST::Elision *node = new (pool) AST::Elision();
   node->commaToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1329,7 +1303,7 @@ case $rule_number: {
 Elision: Elision T_COMMA ;
 /.
 case $rule_number: {
-  AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision);
+  AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1338,7 +1312,7 @@ case $rule_number: {
 PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+  AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
       sym(1).PropertyName, sym(3).Expression);
   node->colonToken = loc(2);
   sym(1).Node = node;
@@ -1348,7 +1322,7 @@ case $rule_number: {
 PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+  AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
       sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
   node->commaToken = loc(2);
   node->colonToken = loc(4);
@@ -1359,7 +1333,7 @@ case $rule_number: {
 PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
 /.
 case $rule_number: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1371,7 +1345,7 @@ PropertyName: T_SIGNAL ;
 PropertyName: T_PROPERTY ;
 /.
 case $rule_number: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()));
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1380,7 +1354,7 @@ case $rule_number: {
 PropertyName: T_STRING_LITERAL ;
 /.
 case $rule_number: {
-  AST::StringLiteralPropertyName *node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1389,7 +1363,7 @@ case $rule_number: {
 PropertyName: T_NUMERIC_LITERAL ;
 /.
 case $rule_number: {
-  AST::NumericLiteralPropertyName *node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
+  AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1398,139 +1372,43 @@ case $rule_number: {
 PropertyName: ReservedIdentifier ;
 /.
 case $rule_number: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 ./
 
 ReservedIdentifier: T_BREAK ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_CASE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_CATCH ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_CONTINUE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_DEFAULT ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_DELETE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_DO ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_ELSE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_FALSE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_FINALLY ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_FOR ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_FUNCTION ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_IF ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_IN ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_INSTANCEOF ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_NEW ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_NULL ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_RETURN ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_SWITCH ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_THIS ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_THROW ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_TRUE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_TRY ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_TYPEOF ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_VAR ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_VOID ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_WHILE ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_CONST ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_DEBUGGER ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_RESERVED_WORD ;
-/.
-case $rule_number:
-./
 ReservedIdentifier: T_WITH ;
-/.
-case $rule_number:
-{
-  sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-} break;
-./
 
 PropertyIdentifier: JsIdentifier ;
 PropertyIdentifier: ReservedIdentifier ;
@@ -1541,7 +1419,7 @@ MemberExpression: FunctionExpression ;
 MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
   node->lbracketToken = loc(2);
   node->rbracketToken = loc(4);
   sym(1).Node = node;
@@ -1551,7 +1429,7 @@ case $rule_number: {
 MemberExpression: MemberExpression T_DOT PropertyIdentifier ;
 /.
 case $rule_number: {
-  AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+  AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
   node->dotToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
@@ -1561,7 +1439,7 @@ case $rule_number: {
 MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
 /.
 case $rule_number: {
-  AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList);
+  AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
   node->newToken = loc(1);
   node->lparenToken = loc(3);
   node->rparenToken = loc(5);
@@ -1574,7 +1452,7 @@ NewExpression: MemberExpression ;
 NewExpression: T_NEW NewExpression ;
 /.
 case $rule_number: {
-  AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression);
+  AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
   node->newToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1583,7 +1461,7 @@ case $rule_number: {
 CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
 /.
 case $rule_number: {
-  AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+  AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
   sym(1).Node = node;
@@ -1593,7 +1471,7 @@ case $rule_number: {
 CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ;
 /.
 case $rule_number: {
-  AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+  AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
   sym(1).Node = node;
@@ -1603,7 +1481,7 @@ case $rule_number: {
 CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ;
 /.
 case $rule_number: {
-  AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
   node->lbracketToken = loc(2);
   node->rbracketToken = loc(4);
   sym(1).Node = node;
@@ -1613,7 +1491,7 @@ case $rule_number: {
 CallExpression: CallExpression T_DOT PropertyIdentifier ;
 /.
 case $rule_number: {
-  AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+  AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
   node->dotToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
@@ -1637,14 +1515,14 @@ case $rule_number: {
 ArgumentList: AssignmentExpression ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
+  sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
 } break;
 ./
 
 ArgumentList: ArgumentList T_COMMA AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
+  AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1657,7 +1535,7 @@ PostfixExpression: LeftHandSideExpression ;
 PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ;
 /.
 case $rule_number: {
-  AST::PostIncrementExpression *node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
+  AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
   node->incrementToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1666,7 +1544,7 @@ case $rule_number: {
 PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ;
 /.
 case $rule_number: {
-  AST::PostDecrementExpression *node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
+  AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
   node->decrementToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1677,7 +1555,7 @@ UnaryExpression: PostfixExpression ;
 UnaryExpression: T_DELETE UnaryExpression ;
 /.
 case $rule_number: {
-  AST::DeleteExpression *node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
+  AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
   node->deleteToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1686,7 +1564,7 @@ case $rule_number: {
 UnaryExpression: T_VOID UnaryExpression ;
 /.
 case $rule_number: {
-  AST::VoidExpression *node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
+  AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
   node->voidToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1695,7 +1573,7 @@ case $rule_number: {
 UnaryExpression: T_TYPEOF UnaryExpression ;
 /.
 case $rule_number: {
-  AST::TypeOfExpression *node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
+  AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
   node->typeofToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1704,7 +1582,7 @@ case $rule_number: {
 UnaryExpression: T_PLUS_PLUS UnaryExpression ;
 /.
 case $rule_number: {
-  AST::PreIncrementExpression *node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
+  AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
   node->incrementToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1713,7 +1591,7 @@ case $rule_number: {
 UnaryExpression: T_MINUS_MINUS UnaryExpression ;
 /.
 case $rule_number: {
-  AST::PreDecrementExpression *node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
+  AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
   node->decrementToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1722,7 +1600,7 @@ case $rule_number: {
 UnaryExpression: T_PLUS UnaryExpression ;
 /.
 case $rule_number: {
-  AST::UnaryPlusExpression *node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
+  AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
   node->plusToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1731,7 +1609,7 @@ case $rule_number: {
 UnaryExpression: T_MINUS UnaryExpression ;
 /.
 case $rule_number: {
-  AST::UnaryMinusExpression *node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
+  AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
   node->minusToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1740,7 +1618,7 @@ case $rule_number: {
 UnaryExpression: T_TILDE UnaryExpression ;
 /.
 case $rule_number: {
-  AST::TildeExpression *node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
+  AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
   node->tildeToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1749,7 +1627,7 @@ case $rule_number: {
 UnaryExpression: T_NOT UnaryExpression ;
 /.
 case $rule_number: {
-  AST::NotExpression *node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression);
+  AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
   node->notToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1760,7 +1638,7 @@ MultiplicativeExpression: UnaryExpression ;
 MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Mul, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1770,7 +1648,7 @@ case $rule_number: {
 MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Div, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1780,7 +1658,7 @@ case $rule_number: {
 MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Mod, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1792,7 +1670,7 @@ AdditiveExpression: MultiplicativeExpression ;
 AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Add, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1802,7 +1680,7 @@ case $rule_number: {
 AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Sub, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1814,7 +1692,7 @@ ShiftExpression: AdditiveExpression ;
 ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::LShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1824,7 +1702,7 @@ case $rule_number: {
 ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::RShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1834,7 +1712,7 @@ case $rule_number: {
 ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::URShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1846,7 +1724,7 @@ RelationalExpression: ShiftExpression ;
 RelationalExpression: RelationalExpression T_LT ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Lt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1856,7 +1734,7 @@ case $rule_number: {
 RelationalExpression: RelationalExpression T_GT ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Gt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1866,7 +1744,7 @@ case $rule_number: {
 RelationalExpression: RelationalExpression T_LE ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Le, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1876,7 +1754,7 @@ case $rule_number: {
 RelationalExpression: RelationalExpression T_GE ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Ge, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1886,7 +1764,7 @@ case $rule_number: {
 RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::InstanceOf, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1896,7 +1774,7 @@ case $rule_number: {
 RelationalExpression: RelationalExpression T_IN ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::In, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1908,7 +1786,7 @@ RelationalExpressionNotIn: ShiftExpression ;
 RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Lt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1918,7 +1796,7 @@ case $rule_number: {
 RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Gt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1928,7 +1806,7 @@ case $rule_number: {
 RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Le, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1938,7 +1816,7 @@ case $rule_number: {
 RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
    QSOperator::Ge, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1948,7 +1826,7 @@ case $rule_number: {
 RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::InstanceOf, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1960,7 +1838,7 @@ EqualityExpression: RelationalExpression ;
 EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Equal, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1970,7 +1848,7 @@ case $rule_number: {
 EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::NotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1980,7 +1858,7 @@ case $rule_number: {
 EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1990,7 +1868,7 @@ case $rule_number: {
 EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictNotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2002,7 +1880,7 @@ EqualityExpressionNotIn: RelationalExpressionNotIn ;
 EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Equal, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2012,7 +1890,7 @@ case $rule_number: {
 EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::NotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2022,7 +1900,7 @@ case $rule_number: {
 EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2032,7 +1910,7 @@ case $rule_number: {
 EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictNotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2044,7 +1922,7 @@ BitwiseANDExpression: EqualityExpression ;
 BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitAnd, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2056,7 +1934,7 @@ BitwiseANDExpressionNotIn: EqualityExpressionNotIn ;
 BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitAnd, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2068,7 +1946,7 @@ BitwiseXORExpression: BitwiseANDExpression ;
 BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitXor, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2080,7 +1958,7 @@ BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ;
 BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitXor, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2092,7 +1970,7 @@ BitwiseORExpression: BitwiseXORExpression ;
 BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitOr, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2104,7 +1982,7 @@ BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ;
 BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitOr, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2116,7 +1994,7 @@ LogicalANDExpression: BitwiseORExpression ;
 LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::And, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2128,7 +2006,7 @@ LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ;
 LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::And, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2140,7 +2018,7 @@ LogicalORExpression: LogicalANDExpression ;
 LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Or, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2152,7 +2030,7 @@ LogicalORExpressionNotIn: LogicalANDExpressionNotIn ;
 LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Or, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2164,7 +2042,7 @@ ConditionalExpression: LogicalORExpression ;
 ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+  AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
     sym(3).Expression, sym(5).Expression);
   node->questionToken = loc(2);
   node->colonToken = loc(4);
@@ -2177,7 +2055,7 @@ ConditionalExpressionNotIn: LogicalORExpressionNotIn ;
 ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+  AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
     sym(3).Expression, sym(5).Expression);
   node->questionToken = loc(2);
   node->colonToken = loc(4);
@@ -2190,7 +2068,7 @@ AssignmentExpression: ConditionalExpression ;
 AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     sym(2).ival, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2202,7 +2080,7 @@ AssignmentExpressionNotIn: ConditionalExpressionNotIn ;
 AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     sym(2).ival, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -2298,7 +2176,7 @@ Expression: AssignmentExpression ;
 Expression: Expression T_COMMA AssignmentExpression ;
 /.
 case $rule_number: {
-  AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -2318,7 +2196,7 @@ ExpressionNotIn: AssignmentExpressionNotIn ;
 ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ;
 /.
 case $rule_number: {
-  AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -2353,7 +2231,7 @@ Statement: DebuggerStatement ;
 Block: T_LBRACE StatementListOpt T_RBRACE ;
 /.
 case $rule_number: {
-  AST::Block *node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList);
+  AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
@@ -2363,14 +2241,14 @@ case $rule_number: {
 StatementList: Statement ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement);
+  sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
 } break;
 ./
 
 StatementList: StatementList Statement ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
+  sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
 } break;
 ./
 
@@ -2392,7 +2270,7 @@ VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_S
 VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(),
+  AST::VariableStatement *node = new (pool) AST::VariableStatement(
      sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
   node->declarationKindToken = loc(1);
   node->semicolonToken = loc(3);
@@ -2417,14 +2295,14 @@ case $rule_number: {
 VariableDeclarationList: VariableDeclaration ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
 } break;
 ./
 
 VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ;
 /.
 case $rule_number: {
-  AST::VariableDeclarationList *node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(),
+  AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
     sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
   node->commaToken = loc(2);
   sym(1).Node = node;
@@ -2434,21 +2312,21 @@ case $rule_number: {
 VariableDeclarationListNotIn: VariableDeclarationNotIn ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
 } break;
 ./
 
 VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
 } break;
 ./
 
 VariableDeclaration: JsIdentifier InitialiserOpt ;
 /.
 case $rule_number: {
-  AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+  AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2457,7 +2335,7 @@ case $rule_number: {
 VariableDeclarationNotIn: JsIdentifier InitialiserNotInOpt ;
 /.
 case $rule_number: {
-  AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+  AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2500,7 +2378,7 @@ InitialiserNotInOpt: InitialiserNotIn ;
 EmptyStatement: T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::EmptyStatement *node = makeAstNode<AST::EmptyStatement> (driver->nodePool());
+  AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
   node->semicolonToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2510,7 +2388,7 @@ ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ;  -- automatic semicolon
 ExpressionStatement: Expression T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
+  AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -2519,7 +2397,7 @@ case $rule_number: {
 IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ;
 /.
 case $rule_number: {
-  AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
+  AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
   node->ifToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -2531,7 +2409,7 @@ case $rule_number: {
 IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
   node->ifToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -2544,7 +2422,7 @@ IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMA
 IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::DoWhileStatement *node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
+  AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
   node->doToken = loc(1);
   node->whileToken = loc(3);
   node->lparenToken = loc(4);
@@ -2557,7 +2435,7 @@ case $rule_number: {
 IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::WhileStatement *node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
   node->whileToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -2568,7 +2446,7 @@ case $rule_number: {
 IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::ForStatement *node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression,
+  AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
     sym(5).Expression, sym(7).Expression, sym(9).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -2582,7 +2460,7 @@ case $rule_number: {
 IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::LocalForStatement *node = makeAstNode<AST::LocalForStatement> (driver->nodePool(),
+  AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
      sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
      sym(8).Expression, sym(10).Statement);
   node->forToken = loc(1);
@@ -2598,7 +2476,7 @@ case $rule_number: {
 IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST:: ForEachStatement *node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression,
+  AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
     sym(5).Expression, sym(7).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -2611,7 +2489,7 @@ case $rule_number: {
 IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::LocalForEachStatement *node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(),
+  AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
     sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -2626,7 +2504,7 @@ ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ;  -- automatic semicolon
 ContinueStatement: T_CONTINUE T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool());
+  AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
   node->continueToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
@@ -2637,7 +2515,7 @@ ContinueStatement: T_CONTINUE JsIdentifier T_AUTOMATIC_SEMICOLON ;  -- automatic
 ContinueStatement: T_CONTINUE JsIdentifier T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
+  AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
   node->continueToken = loc(1);
   node->identifierToken = loc(2);
   node->semicolonToken = loc(3);
@@ -2649,7 +2527,7 @@ BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ;  -- automatic semicolon
 BreakStatement: T_BREAK T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool());
+  AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
   node->breakToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
@@ -2660,7 +2538,7 @@ BreakStatement: T_BREAK JsIdentifier T_AUTOMATIC_SEMICOLON ;  -- automatic semic
 BreakStatement: T_BREAK JsIdentifier T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval);
+  AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
   node->breakToken = loc(1);
   node->identifierToken = loc(2);
   node->semicolonToken = loc(3);
@@ -2672,7 +2550,7 @@ ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ;  -- automatic se
 ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::ReturnStatement *node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
+  AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
   node->returnToken = loc(1);
   node->semicolonToken = loc(3);
   sym(1).Node = node;
@@ -2682,7 +2560,7 @@ case $rule_number: {
 WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ;
 /.
 case $rule_number: {
-  AST::WithStatement *node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
   node->withToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -2693,7 +2571,7 @@ case $rule_number: {
 SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ;
 /.
 case $rule_number: {
-  AST::SwitchStatement *node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
+  AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
   node->switchToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -2704,7 +2582,7 @@ case $rule_number: {
 CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ;
 /.
 case $rule_number: {
-  AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
+  AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
@@ -2714,7 +2592,7 @@ case $rule_number: {
 CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ;
 /.
 case $rule_number: {
-  AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
+  AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(5);
   sym(1).Node = node;
@@ -2724,14 +2602,14 @@ case $rule_number: {
 CaseClauses: CaseClause ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
+  sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
 } break;
 ./
 
 CaseClauses: CaseClauses CaseClause ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
+  sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
 } break;
 ./
 
@@ -2752,7 +2630,7 @@ case $rule_number: {
 CaseClause: T_CASE Expression T_COLON StatementListOpt ;
 /.
 case $rule_number: {
-  AST::CaseClause *node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
+  AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
   node->caseToken = loc(1);
   node->colonToken = loc(3);
   sym(1).Node = node;
@@ -2762,7 +2640,7 @@ case $rule_number: {
 DefaultClause: T_DEFAULT T_COLON StatementListOpt ;
 /.
 case $rule_number: {
-  AST::DefaultClause *node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
+  AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
   node->defaultToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
@@ -2775,7 +2653,7 @@ LabelledStatement: T_SIGNAL T_COLON Statement ;
 LabelledStatement: T_PROPERTY T_COLON Statement ;
 /.
 case $rule_number: {
-  AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement);
+  AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
   node->identifierToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
@@ -2785,7 +2663,7 @@ case $rule_number: {
 LabelledStatement: T_IDENTIFIER T_COLON Statement ;
 /.
 case $rule_number: {
-  AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
+  AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
   node->identifierToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
@@ -2796,7 +2674,7 @@ ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ;  -- automatic semicol
 ThrowStatement: T_THROW Expression T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::ThrowStatement *node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
+  AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
   node->throwToken = loc(1);
   node->semicolonToken = loc(3);
   sym(1).Node = node;
@@ -2806,7 +2684,7 @@ case $rule_number: {
 TryStatement: T_TRY Block Catch ;
 /.
 case $rule_number: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2815,7 +2693,7 @@ case $rule_number: {
 TryStatement: T_TRY Block Finally ;
 /.
 case $rule_number: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2824,7 +2702,7 @@ case $rule_number: {
 TryStatement: T_TRY Block Catch Finally ;
 /.
 case $rule_number: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2833,7 +2711,7 @@ case $rule_number: {
 Catch: T_CATCH T_LPAREN JsIdentifier T_RPAREN Block ;
 /.
 case $rule_number: {
-  AST::Catch *node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Block);
+  AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
   node->catchToken = loc(1);
   node->lparenToken = loc(2);
   node->identifierToken = loc(3);
@@ -2845,7 +2723,7 @@ case $rule_number: {
 Finally: T_FINALLY Block ;
 /.
 case $rule_number: {
-  AST::Finally *node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Block);
+  AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
   node->finallyToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2855,7 +2733,7 @@ DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
 DebuggerStatement: T_DEBUGGER T_SEMICOLON ;
 /.
 case $rule_number: {
-  AST::DebuggerStatement *node = makeAstNode<AST::DebuggerStatement> (driver->nodePool());
+  AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
   node->debuggerToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
@@ -2865,7 +2743,7 @@ case $rule_number: {
 FunctionDeclaration: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
 /.
 case $rule_number: {
-  AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+  AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
   node->functionToken = loc(1);
   node->identifierToken = loc(2);
   node->lparenToken = loc(3);
@@ -2879,9 +2757,9 @@ case $rule_number: {
 FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
 /.
 case $rule_number: {
-  AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+  AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
   node->functionToken = loc(1);
-  if (sym(2).sval)
+  if (! stringRef(2).isNull())
       node->identifierToken = loc(2);
   node->lparenToken = loc(3);
   node->rparenToken = loc(5);
@@ -2894,7 +2772,7 @@ case $rule_number: {
 FormalParameterList: JsIdentifier ;
 /.
 case $rule_number: {
-  AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
+  AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -2903,7 +2781,7 @@ case $rule_number: {
 FormalParameterList: FormalParameterList T_COMMA JsIdentifier ;
 /.
 case $rule_number: {
-  AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
+  AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
   node->commaToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
@@ -2936,49 +2814,49 @@ FunctionBodyOpt: FunctionBody ;
 FunctionBody: SourceElements ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
+  sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
 } break;
 ./
 
 Program: SourceElements ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
+  sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
 } break;
 ./
 
 SourceElements: SourceElement ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
+  sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
 } break;
 ./
 
 SourceElements: SourceElements SourceElement ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
+  sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
 } break;
 ./
 
 SourceElement: Statement ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
+  sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
 } break;
 ./
 
 SourceElement: FunctionDeclaration ;
 /.
 case $rule_number: {
-  sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
+  sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
 } break;
 ./
 
 IdentifierOpt: ;
 /.
 case $rule_number: {
-  sym(1).sval = 0;
+  stringRef(1) = QStringRef();
 } break;
 ./
 
@@ -3007,6 +2885,7 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
             SavedToken &tk = token_buffer[0];
             tk.token = yytoken;
             tk.dval = yylval;
+            tk.spell = yytokenspell;
             tk.loc = yylloc;
 
             yylloc = yyprevlloc;
@@ -3032,11 +2911,13 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
 
         token_buffer[0].token = yytoken;
         token_buffer[0].dval = yylval;
+        token_buffer[0].spell = yytokenspell;
         token_buffer[0].loc = yylloc;
 
-        token_buffer[1].token = yytoken = lexer->lex();
-        token_buffer[1].dval  = yylval  = lexer->dval();
-        token_buffer[1].loc   = yylloc  = location(lexer);
+        token_buffer[1].token = yytoken       = lexer->lex();
+        token_buffer[1].dval  = yylval        = lexer->tokenValue();
+        token_buffer[1].spell = yytokenspell  = lexer->tokenSpell();
+        token_buffer[1].loc   = yylloc        = location(lexer);
 
         if (t_action(errorState, yytoken)) {
             QString msg;
index 79e7007..7bd102c 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "qmljsastvisitor_p.h"
 #include "qmljsglobal_p.h"
+#include "qmljsmemorypool_p.h"
 
 #include <QtCore/QString>
 
@@ -98,7 +99,7 @@ enum Op {
 } // namespace QSOperator
 
 namespace QmlJS {
-class NameId;
+
 namespace AST {
 
 template <typename _T1, typename _T2>
@@ -110,7 +111,7 @@ _T1 cast(_T2 *ast)
     return 0;
 }
 
-class QML_PARSER_EXPORT Node
+class QML_PARSER_EXPORT Node: public Managed
 {
 public:
     enum Kind {
@@ -264,7 +265,7 @@ class QML_PARSER_EXPORT UiFormal: public Node
 public:
     QMLJS_DECLARE_AST_NODE(UiFormal)
 
-    UiFormal(NameId *name, NameId *alias = 0)
+    UiFormal(const QStringRef &name, const QStringRef &alias)
       : name(name), alias(alias)
     { }
 
@@ -277,8 +278,8 @@ public:
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *name;
-    NameId *alias;
+    QStringRef name;
+    QStringRef alias;
     SourceLocation identifierToken;
     SourceLocation asToken;
     SourceLocation aliasToken;
@@ -389,7 +390,7 @@ class QML_PARSER_EXPORT IdentifierExpression: public ExpressionNode
 public:
     QMLJS_DECLARE_AST_NODE(IdentifierExpression)
 
-    IdentifierExpression(NameId *n):
+    IdentifierExpression(const QStringRef &n):
         name (n) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
@@ -401,7 +402,7 @@ public:
     { return identifierToken; }
 
 // attributes
-    NameId *name;
+    QStringRef name;
     SourceLocation identifierToken;
 };
 
@@ -488,7 +489,7 @@ class QML_PARSER_EXPORT StringLiteral: public ExpressionNode
 public:
     QMLJS_DECLARE_AST_NODE(StringLiteral)
 
-    StringLiteral(NameId *v):
+    StringLiteral(const QStringRef &v):
         value (v) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
@@ -500,7 +501,7 @@ public:
     { return literalToken; }
 
 // attributes:
-    NameId *value;
+    QStringRef value;
     SourceLocation literalToken;
 };
 
@@ -509,7 +510,7 @@ class QML_PARSER_EXPORT RegExpLiteral: public ExpressionNode
 public:
     QMLJS_DECLARE_AST_NODE(RegExpLiteral)
 
-    RegExpLiteral(NameId *p, int f):
+    RegExpLiteral(const QStringRef &p, int f):
         pattern (p), flags (f) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
@@ -521,7 +522,7 @@ public:
     { return literalToken; }
 
 // attributes:
-    NameId *pattern;
+    QStringRef pattern;
     int flags;
     SourceLocation literalToken;
 };
@@ -696,13 +697,13 @@ class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
 public:
     QMLJS_DECLARE_AST_NODE(IdentifierPropertyName)
 
-    IdentifierPropertyName(NameId *n):
+    IdentifierPropertyName(const QStringRef &n):
         id (n) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *id;
+    QStringRef id;
 };
 
 class QML_PARSER_EXPORT StringLiteralPropertyName: public PropertyName
@@ -710,13 +711,13 @@ class QML_PARSER_EXPORT StringLiteralPropertyName: public PropertyName
 public:
     QMLJS_DECLARE_AST_NODE(StringLiteralPropertyName)
 
-    StringLiteralPropertyName(NameId *n):
+    StringLiteralPropertyName(const QStringRef &n):
         id (n) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *id;
+    QStringRef id;
 };
 
 class QML_PARSER_EXPORT NumericLiteralPropertyName: public PropertyName
@@ -762,7 +763,7 @@ class QML_PARSER_EXPORT FieldMemberExpression: public ExpressionNode
 public:
     QMLJS_DECLARE_AST_NODE(FieldMemberExpression)
 
-    FieldMemberExpression(ExpressionNode *b, NameId *n):
+    FieldMemberExpression(ExpressionNode *b, const QStringRef &n):
         base (b), name (n)
         { kind = K; }
 
@@ -776,7 +777,7 @@ public:
 
     // attributes
     ExpressionNode *base;
-    NameId *name;
+    QStringRef name;
     SourceLocation dotToken;
     SourceLocation identifierToken;
 };
@@ -1268,14 +1269,14 @@ class QML_PARSER_EXPORT VariableDeclaration: public Node
 public:
     QMLJS_DECLARE_AST_NODE(VariableDeclaration)
 
-    VariableDeclaration(NameId *n, ExpressionNode *e):
+    VariableDeclaration(const QStringRef &n, ExpressionNode *e):
         name (n), expression (e), readOnly(false)
         { kind = K; }
 
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *name;
+    QStringRef name;
     ExpressionNode *expression;
     bool readOnly;
     SourceLocation identifierToken;
@@ -1561,7 +1562,7 @@ class QML_PARSER_EXPORT ContinueStatement: public Statement
 public:
     QMLJS_DECLARE_AST_NODE(ContinueStatement)
 
-    ContinueStatement(NameId *l = 0):
+    ContinueStatement(const QStringRef &l = QStringRef()):
         label (l) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
@@ -1573,7 +1574,7 @@ public:
     { return semicolonToken; }
 
 // attributes
-    NameId *label;
+    QStringRef label;
     SourceLocation continueToken;
     SourceLocation identifierToken;
     SourceLocation semicolonToken;
@@ -1584,7 +1585,7 @@ class QML_PARSER_EXPORT BreakStatement: public Statement
 public:
     QMLJS_DECLARE_AST_NODE(BreakStatement)
 
-    BreakStatement(NameId *l = 0):
+    BreakStatement(const QStringRef &l):
         label (l) { kind = K; }
 
     virtual void accept0(Visitor *visitor);
@@ -1596,7 +1597,7 @@ public:
     { return semicolonToken; }
 
     // attributes
-    NameId *label;
+    QStringRef label;
     SourceLocation breakToken;
     SourceLocation identifierToken;
     SourceLocation semicolonToken;
@@ -1764,7 +1765,7 @@ class QML_PARSER_EXPORT LabelledStatement: public Statement
 public:
     QMLJS_DECLARE_AST_NODE(LabelledStatement)
 
-    LabelledStatement(NameId *l, Statement *stmt):
+    LabelledStatement(const QStringRef &l, Statement *stmt):
         label (l), statement (stmt)
         { kind = K; }
 
@@ -1777,7 +1778,7 @@ public:
     { return statement->lastSourceLocation(); }
 
 // attributes
-    NameId *label;
+    QStringRef label;
     Statement *statement;
     SourceLocation identifierToken;
     SourceLocation colonToken;
@@ -1810,14 +1811,14 @@ class QML_PARSER_EXPORT Catch: public Node
 public:
     QMLJS_DECLARE_AST_NODE(Catch)
 
-    Catch(NameId *n, Block *stmt):
+    Catch(const QStringRef &n, Block *stmt):
         name (n), statement (stmt)
         { kind = K; }
 
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *name;
+    QStringRef name;
     Block *statement;
     SourceLocation catchToken;
     SourceLocation lparenToken;
@@ -1885,7 +1886,7 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
 public:
     QMLJS_DECLARE_AST_NODE(FunctionExpression)
 
-    FunctionExpression(NameId *n, FormalParameterList *f, FunctionBody *b):
+    FunctionExpression(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
         name (n), formals (f), body (b)
         { kind = K; }
 
@@ -1898,7 +1899,7 @@ public:
     { return rbraceToken; }
 
 // attributes
-    NameId *name;
+    QStringRef name;
     FormalParameterList *formals;
     FunctionBody *body;
     SourceLocation functionToken;
@@ -1914,7 +1915,7 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
 public:
     QMLJS_DECLARE_AST_NODE(FunctionDeclaration)
 
-    FunctionDeclaration(NameId *n, FormalParameterList *f, FunctionBody *b):
+    FunctionDeclaration(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
         FunctionExpression(n, f, b)
         { kind = K; }
 
@@ -1926,11 +1927,11 @@ class QML_PARSER_EXPORT FormalParameterList: public Node
 public:
     QMLJS_DECLARE_AST_NODE(FormalParameterList)
 
-    FormalParameterList(NameId *n):
+    FormalParameterList(const QStringRef &n):
         name (n), next (this)
         { kind = K; }
 
-    FormalParameterList(FormalParameterList *previous, NameId *n):
+    FormalParameterList(FormalParameterList *previous, const QStringRef &n):
         name (n)
     {
         kind = K;
@@ -1948,7 +1949,7 @@ public:
     }
 
 // attributes
-    NameId *name;
+    QStringRef name;
     FormalParameterList *next;
     SourceLocation commaToken;
     SourceLocation identifierToken;
@@ -2096,11 +2097,11 @@ class QML_PARSER_EXPORT UiQualifiedId: public Node
 public:
     QMLJS_DECLARE_AST_NODE(UiQualifiedId)
 
-    UiQualifiedId(NameId *name)
+    UiQualifiedId(const QStringRef &name)
         : next(this), name(name)
     { kind = K; }
 
-    UiQualifiedId(UiQualifiedId *previous, NameId *name)
+    UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
         : name(name)
     {
         kind = K;
@@ -2119,7 +2120,7 @@ public:
 
 // attributes
     UiQualifiedId *next;
-    NameId *name;
+    QStringRef name;
     SourceLocation identifierToken;
 };
 
@@ -2128,12 +2129,12 @@ class QML_PARSER_EXPORT UiImport: public Node
 public:
     QMLJS_DECLARE_AST_NODE(UiImport)
 
-    UiImport(NameId *fileName)
-        : fileName(fileName), importUri(0), importId(0)
+    UiImport(const QStringRef &fileName)
+        : fileName(fileName), importUri(0)
     { kind = K; }
 
     UiImport(UiQualifiedId *uri)
-        : fileName(0), importUri(uri), importId(0)
+        : importUri(uri)
     { kind = K; }
 
     virtual SourceLocation firstSourceLocation() const
@@ -2145,9 +2146,9 @@ public:
     virtual void accept0(Visitor *visitor);
 
 // attributes
-    NameId *fileName;
+    QStringRef fileName;
     UiQualifiedId *importUri;
-    NameId *importId;
+    QStringRef importId;
     SourceLocation importToken;
     SourceLocation fileNameToken;
     SourceLocation versionToken;
@@ -2297,11 +2298,11 @@ class QML_PARSER_EXPORT UiParameterList: public Node
 public:
     QMLJS_DECLARE_AST_NODE(UiParameterList)
 
-    UiParameterList(NameId *t, NameId *n):
+    UiParameterList(const QStringRef &t, const QStringRef &n):
         type (t), name (n), next (this)
         { kind = K; }
 
-    UiParameterList(UiParameterList *previous, NameId *t, NameId *n):
+    UiParameterList(UiParameterList *previous, const QStringRef &t, const QStringRef &n):
         type (t), name (n)
     {
         kind = K;
@@ -2319,8 +2320,8 @@ public:
     }
 
 // attributes
-    NameId *type;
-    NameId *name;
+    QStringRef type;
+    QStringRef name;
     UiParameterList *next;
     SourceLocation commaToken;
     SourceLocation identifierToken;
@@ -2331,15 +2332,15 @@ class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
 public:
     QMLJS_DECLARE_AST_NODE(UiPublicMember)
 
-    UiPublicMember(NameId *memberType,
-                   NameId *name)
-        : type(Property), typeModifier(0), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+    UiPublicMember(const QStringRef &memberType,
+                   const QStringRef &name)
+        : type(Property), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
     { kind = K; }
 
-    UiPublicMember(NameId *memberType,
-                   NameId *name,
+    UiPublicMember(const QStringRef &memberType,
+                   const QStringRef &name,
                    Statement *statement)
-        : type(Property), typeModifier(0), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
+        : type(Property), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0)
     { kind = K; }
 
     virtual SourceLocation firstSourceLocation() const
@@ -2366,9 +2367,9 @@ public:
 
 // attributes
     enum { Signal, Property } type;
-    NameId *typeModifier;
-    NameId *memberType;
-    NameId *name;
+    QStringRef typeModifier;
+    QStringRef memberType;
+    QStringRef name;
     Statement *statement; // initialized with a JS expression
     UiObjectMember *binding; // initialized with a QML object or array.
     bool isDefaultMember;
index a562bc9..3d9a84e 100644 (file)
 **************************************************************************/
 
 #include "qmljsengine_p.h"
-
 #include "qmljsglobal_p.h"
-#include "qmljsnodepool_p.h"
 
 #include <qnumeric.h>
 #include <QHash>
+#include <QDebug>
 
 QT_QML_BEGIN_NAMESPACE
 
 namespace QmlJS {
 
-uint qHash(const QmlJS::NameId &id)
-{ return qHash(id.asString()); }
-
-QString numberToString(double value)
-{ return QString::number(value); }
-
-int Ecma::RegExp::flagFromChar(const QChar &ch)
-{
-    static QHash<QChar, int> flagsHash;
-    if (flagsHash.isEmpty()) {
-        flagsHash[QLatin1Char('g')] = Global;
-        flagsHash[QLatin1Char('i')] = IgnoreCase;
-        flagsHash[QLatin1Char('m')] = Multiline;
-    }
-    QHash<QChar, int>::const_iterator it;
-    it = flagsHash.constFind(ch);
-    if (it == flagsHash.constEnd())
-        return 0;
-    return it.value();
-}
-
-QString Ecma::RegExp::flagsToString(int flags)
-{
-    QString result;
-    if (flags & Global)
-        result += QLatin1Char('g');
-    if (flags & IgnoreCase)
-        result += QLatin1Char('i');
-    if (flags & Multiline)
-        result += QLatin1Char('m');
-    return result;
-}
-
-NodePool::NodePool(const QString &fileName, Engine *engine)
-    : m_fileName(fileName), m_engine(engine)
-{
-    m_engine->setNodePool(this);
-}
-
-NodePool::~NodePool()
-{
-}
-
-Code *NodePool::createCompiledCode(AST::Node *, CompilationUnit &)
-{
-    Q_ASSERT(0);
-    return 0;
-}
-
 static int toDigit(char c)
 {
     if ((c >= '0') && (c <= '9'))
@@ -163,14 +113,14 @@ double integerFromString(const QString &str, int radix)
 
 
 Engine::Engine()
-    : _lexer(0), _nodePool(0)
+    : _lexer(0)
 { }
 
 Engine::~Engine()
 { }
 
-QSet<NameId> Engine::literals() const
-{ return _literals; }
+void Engine::setCode(const QString &code)
+{ _code = code; }
 
 void Engine::addComment(int pos, int len, int line, int col)
 { if (len > 0) _comments.append(QmlJS::AST::SourceLocation(pos, len, line, col)); }
@@ -178,25 +128,24 @@ void Engine::addComment(int pos, int len, int line, int col)
 QList<QmlJS::AST::SourceLocation> Engine::comments() const
 { return _comments; }
 
-NameId *Engine::intern(const QChar *u, int s)
-{ return const_cast<NameId *>(&*_literals.insert(NameId(u, s))); }
-
-QString Engine::toString(NameId *id)
-{ return id->asString(); }
-
 Lexer *Engine::lexer() const
 { return _lexer; }
 
 void Engine::setLexer(Lexer *lexer)
 { _lexer = lexer; }
 
-NodePool *Engine::nodePool() const
-{ return _nodePool; }
-
-void Engine::setNodePool(NodePool *nodePool)
-{ _nodePool = nodePool; }
+MemoryPool *Engine::pool()
+{ return &_pool; }
 
+QStringRef Engine::newStringRef(const QString &text)
+{
+    const int pos = _extraCode.length();
+    _extraCode += text;
+    return _extraCode.midRef(pos, text.length());
+}
 
+QStringRef Engine::newStringRef(const QChar *chars, int size)
+{ return newStringRef(QString(chars, size)); }
 
 } // end of namespace QmlJS
 
index bc601af..9297b38 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "qmljsglobal_p.h"
 #include "qmljsastfwd_p.h"
+#include "qmljsmemorypool_p.h"
 
 #include <QString>
 #include <QSet>
 QT_QML_BEGIN_NAMESPACE
 
 namespace QmlJS {
-class QML_PARSER_EXPORT NameId
-{
-    QString _text;
-
-public:
-    NameId(const QChar *u, int s)
-        : _text(u, s)
-    { }
-
-    const QString asString() const
-    { return _text; }
-
-    bool operator == (const NameId &other) const
-    { return _text == other._text; }
-
-    bool operator != (const NameId &other) const
-    { return _text != other._text; }
-
-    bool operator < (const NameId &other) const
-    { return _text < other._text; }
-};
-
-uint qHash(const QmlJS::NameId &id);
-
-} // end of namespace QmlJS
-
-namespace QmlJS {
 
 class Lexer;
-class NodePool;
-
-namespace Ecma {
-
-class QML_PARSER_EXPORT RegExp
-{
-public:
-    enum RegExpFlag {
-        Global     = 0x01,
-        IgnoreCase = 0x02,
-        Multiline  = 0x04
-    };
-
-public:
-    static int flagFromChar(const QChar &);
-    static QString flagsToString(int flags);
-};
-
-} // end of namespace Ecma
+class MemoryPool;
 
 class QML_PARSER_EXPORT DiagnosticMessage
 {
@@ -127,30 +83,33 @@ public:
 class QML_PARSER_EXPORT Engine
 {
     Lexer *_lexer;
-    NodePool *_nodePool;
-    QSet<NameId> _literals;
-    QList<QmlJS::AST::SourceLocation> _comments;
+    MemoryPool _pool;
+    QList<AST::SourceLocation> _comments;
+    QString _extraCode;
+    QString _code;
 
 public:
     Engine();
     ~Engine();
 
-    QSet<NameId> literals() const;
+    void setCode(const QString &code);
 
     void addComment(int pos, int len, int line, int col);
-    QList<QmlJS::AST::SourceLocation> comments() const;
-
-    NameId *intern(const QChar *u, int s);
-
-    static QString toString(NameId *id);
+    QList<AST::SourceLocation> comments() const;
 
     Lexer *lexer() const;
     void setLexer(Lexer *lexer);
 
-    NodePool *nodePool() const;
-    void setNodePool(NodePool *nodePool);
+    MemoryPool *pool();
+
+    inline QStringRef midRef(int position, int size) { return _code.midRef(position, size); }
+
+    QStringRef newStringRef(const QString &s);
+    QStringRef newStringRef(const QChar *chars, int size);
 };
 
+double integerFromString(const char *buf, int size, int radix);
+
 } // end of namespace QmlJS
 
 QT_QML_END_NAMESPACE
index f39ba2d..93ffd96 100644 (file)
@@ -36,7 +36,7 @@
 QT_BEGIN_NAMESPACE
 
 const char *const QmlJSGrammar::spell [] = {
-  "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue", 
+  "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue", 
   "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===", 
   "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier", 
   "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=", 
@@ -46,44 +46,44 @@ const char *const QmlJSGrammar::spell [] = {
   "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^", 
   "^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", "public", 
   "import", "as", "on", 0, 0, 0, 0, 0, 0, 0, 
-  0};
+  0, 0};
 
 const short QmlJSGrammar::lhs [] = {
-  101, 101, 101, 101, 101, 101, 102, 108, 108, 111
-  111, 113, 112, 112, 112, 112, 112, 112, 112, 112
-  115, 110, 109, 118, 118, 119, 119, 120, 120, 117
-  106, 106, 106, 106, 122, 122, 122, 122, 106, 127
-  127, 127, 128, 128, 129, 129, 106, 106, 106, 106
-  106, 106, 106, 106, 106, 106, 106, 106, 106, 106
-  106, 106, 106, 116, 116, 116, 116, 116, 132, 132
-  132, 132, 132, 132, 132, 132, 132, 132, 132, 132
-  132, 132, 132, 132, 132, 132, 121, 134, 134, 134
-  134, 133, 133, 136, 136, 138, 138, 138, 138, 138
-  138, 139, 139, 139, 139, 139, 139, 139, 139, 139
-  139, 139, 139, 139, 139, 139, 139, 139, 139, 139
-  139, 139, 139, 139, 139, 139, 139, 139, 139, 139
-  139, 139, 140, 140, 114, 114, 114, 114, 114, 143
-  143, 144, 144, 144, 144, 142, 142, 145, 145, 146
-  146, 147, 147, 147, 148, 148, 148, 148, 148, 148
-  148, 148, 148, 148, 149, 149, 149, 149, 150, 150
-  150, 151, 151, 151, 151, 152, 152, 152, 152, 152
-  152, 152, 153, 153, 153, 153, 153, 153, 154, 154
-  154, 154, 154, 155, 155, 155, 155, 155, 156, 156
-  157, 157, 158, 158, 159, 159, 160, 160, 161, 161
-  162, 162, 163, 163, 164, 164, 165, 165, 166, 166
-  167, 167, 137, 137, 168, 168, 169, 169, 169, 169
-  169, 169, 169, 169, 169, 169, 169, 169, 104, 104
-  170, 170, 171, 171, 172, 172, 103, 103, 103, 103
-  103, 103, 103, 103, 103, 103, 103, 103, 103, 103
-  103, 123, 184, 184, 183, 183, 131, 131, 185, 185
-  186, 186, 188, 188, 187, 189, 192, 190, 190, 193
-  191, 191, 124, 125, 125, 126, 126, 173, 173, 173
-  173, 173, 173, 173, 174, 174, 174, 174, 175, 175
-  175, 175, 176, 176, 177, 179, 194, 194, 197, 197
-  195, 195, 198, 196, 178, 178, 178, 180, 180, 181
-  181, 181, 199, 200, 182, 182, 130, 141, 204, 204
-  201, 201, 202, 202, 205, 107, 206, 206, 105, 105
-  203, 203, 135, 135, 207};
+  102, 102, 102, 102, 102, 102, 103, 109, 109, 112
+  112, 114, 113, 113, 113, 113, 113, 113, 113, 113
+  116, 111, 110, 119, 119, 120, 120, 121, 121, 118
+  107, 107, 107, 107, 123, 123, 123, 123, 107, 128
+  128, 128, 129, 129, 130, 130, 107, 107, 107, 107
+  107, 107, 107, 107, 107, 107, 107, 107, 107, 107
+  107, 107, 107, 117, 117, 117, 117, 117, 133, 133
+  133, 133, 133, 133, 133, 133, 133, 133, 133, 133
+  133, 133, 133, 133, 133, 133, 122, 135, 135, 135
+  135, 134, 134, 137, 137, 139, 139, 139, 139, 139
+  139, 140, 140, 140, 140, 140, 140, 140, 140, 140
+  140, 140, 140, 140, 140, 140, 140, 140, 140, 140
+  140, 140, 140, 140, 140, 140, 140, 140, 140, 140
+  140, 140, 141, 141, 115, 115, 115, 115, 115, 144
+  144, 145, 145, 145, 145, 143, 143, 146, 146, 147
+  147, 148, 148, 148, 149, 149, 149, 149, 149, 149
+  149, 149, 149, 149, 150, 150, 150, 150, 151, 151
+  151, 152, 152, 152, 152, 153, 153, 153, 153, 153
+  153, 153, 154, 154, 154, 154, 154, 154, 155, 155
+  155, 155, 155, 156, 156, 156, 156, 156, 157, 157
+  158, 158, 159, 159, 160, 160, 161, 161, 162, 162
+  163, 163, 164, 164, 165, 165, 166, 166, 167, 167
+  168, 168, 138, 138, 169, 169, 170, 170, 170, 170
+  170, 170, 170, 170, 170, 170, 170, 170, 105, 105
+  171, 171, 172, 172, 173, 173, 104, 104, 104, 104
+  104, 104, 104, 104, 104, 104, 104, 104, 104, 104
+  104, 124, 185, 185, 184, 184, 132, 132, 186, 186
+  187, 187, 189, 189, 188, 190, 193, 191, 191, 194
+  192, 192, 125, 126, 126, 127, 127, 174, 174, 174
+  174, 174, 174, 174, 175, 175, 175, 175, 176, 176
+  176, 176, 177, 177, 178, 180, 195, 195, 198, 198
+  196, 196, 199, 197, 179, 179, 179, 181, 181, 182
+  182, 182, 200, 201, 183, 183, 131, 142, 205, 205
+  202, 202, 203, 203, 206, 108, 207, 207, 106, 106
+  204, 204, 136, 136, 208};
 
 const short QmlJSGrammar::rhs [] = {
   2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 
@@ -203,71 +203,71 @@ const short QmlJSGrammar::goto_default [] = {
   185, 199, 181, 184, 198, 206, 0};
 
 const short QmlJSGrammar::action_index [] = {
-  350, 1271, 2492, 2492, 2395, 999, 52, 93, 137, -101
-  104, 72, 66, 177, -101, 285, 80, -101, -101, 641
-  71, 130, 167, 178, -101, -101, -101, 431, 321, 1271
-  -101, -101, -101, 393, -101, 2201, 2007, 1271, 1271, 1271
-  -101, 811, 1271, -101, -101, -101, 1271, 1271, -101, -101
-  -101, -101, -101, 1271, -101, 1271, 1271, -101, 1271, 1271
-  87, 188, -101, -101, 1271, 1271, 1271, -101, -101, -101
-  179, 1271, 263, 1271, 1271, 1271, 1271, 456, 1271, 1271
-  1271, 1271, 1271, 1271, 321, 1271, 1271, 1271, 128, 114
-  120, 193, 181, 172, 321, 321, 446, 395, 405, 1271
-  -8, 1271, 76, 2104, 1271, 1271, -101, -101, -101, -101
-  -101, -101, -101, -101, -101, -101, -101, -101, -101, -101
-  -101, -101, -101, -101, -101, -101, -101, -101, -101, -101
-  -101, -101, -101, -101, -101, -101, -101, -101, -101, -101
-  110, 1271, -101, -101, 68, 38, -101, 1271, -101, -101
-  1271, -101, -101, -101, -101, -101, -101, -101, -101, -101
-  -101, -101, -101, -101, 1271, 32, 1271, 1271, 85, 83
-  1271, -101, 2104, 1271, 1271, -101, 108, -101, 53, -101
-  -101, 64, -101, 393, 89, 62, -101, 297, -101, 63
-  2492, -101, -101, -101, -101, -101, 154, -101, -101, 47, 
-  -101, -101, -101, -101, -101, -101, 2492, -101, -101, 461
-  -101, 470, 74, 2395, 59, 393, 92, 67, 2686, 152
-  1271, -101, 65, 43, 1271, 41, -101, 39, 34, -101
-  -101, 393, -101, -101, -101, -101, -101, -101, 86, -101
-  -101, -101, -101, 90, -101, -101, -101, -101, -101, -101
-  -11, 50, 1271, 103, 82, -101, -101, 1455, -101, 84, 
-  44, 5, -101, 267, 70, 33, 575, 79, 69, 471
-  235, 393, 1271, 275, 1271, 1271, 1271, 1271, 305, 1271
-  1271, 1271, 1271, 1271, 229, 201, 225, 202, 321, 355
-  374, 380, 1271, 35, 1271, 81, 1271, -101, 641, 1271
-  -101, 1271, 61, 1, 1271, 29, 2395, -101, 1271, 133
-  2395, -101, 1271, 73, 1271, 1271, 99, 97, 1271, -101
-  51, 153, 60, -101, -101, 1271, -101, 393, 1271, -101
-  56, 1271, -25, 2395, -101, 1271, 129, 2395, -101, -35, 
-  309, -56, -31, 2492, -39, -101, 2395, -101, 1271, 245
-  2395, -5, 2395, -101, 6, 0, -33, -101, -101, 2395
-  -43, 543, 7, 488, 112, 1271, 2395, -1, -27, 453
-  8, -18, 630, 14, 16, -101, 1365, -101, 12, -19, 
-  3, 1271, 58, -30, 1271, -2, 1271, -29, -36, 1271
-  -101, 2298, 18, -101, -101, -101, -101, -101, -101, 1271
-  -101, -101, -101, -101, 223, -101, 1271, -10, -101, 2395
-  -101, 95, -101, -101, 2395, -101, 1271, 107, 20, -101
-  40, -101, 46, 100, 1271, -101, 55, 57, -101, 28, 
-  -101, 2395, -101, 118, 2395, -101, 161, -101, -101, 126
-  2395, 37, -101, -12, -4, -101, 393, -34, -6, -101
-  -101, -101, -101, 1271, 98, 2395, -101, 1271, 116, 2395
-  -101, 19, -101, 186, -101, -101, 1271, -101, -101, 303
-  -101, -101, -101, 119, 1638, -101, -101, 1821, -101, -101
-  1914, -101, -101, -101, -101, -101, -101, 123, -101, -101
-  -101, -101, -101, -101, -101, -101, 2492, -101, -101, -101
-  94, -26, 819, 158, -28, 4, -101, -101, 210, -101
-  203, -101, -101, -101, 393, 230, -101, 1545, -101, -101
-  -101, -101, -101, -101, 234, 2, 393, 232, 17, 393
-  163, -101, 10, -101, 908, 125, -101, 13, 908, -101
-  -101, 1090, -101, -101, -101, 1181, -101, -101, 214, -101
-  1545, -101, 262, 9, -101, -101, 180, 318, 30, 1545
-  -101, 238, -101, 236, -101, 26, -32, 315, 183, 288
-  -101, 77, -101, -101, -101, 1728, 908, 291, 2589, 2007
-  -3, -101, 443, 25, 497, 88, 1271, 2395, 24, 11, 
-  384, 36, 27, 702, 48, 49, -101, 1365, -101, 54, 
-  31, 45, 1271, 58, 15, 1271, 42, 1271, 23, 22, 
-  122, -101, -101, 21, -101, -101, 730, -101, 254, -70, 
-  908, -101, -101, 138, 393, -101, 143, -101, 134, -101
-  -101, 268, -101, -101, 124, -101, -101, -101, -101, -101
-  -101
+  360, 1286, 2520, 2520, 2422, 1011, 52, 96, 132, -102
+  104, 69, 66, 177, -102, 283, 80, -102, -102, 649
+  71, 120, 160, 169, -102, -102, -102, 444, 325, 1286
+  -102, -102, -102, 324, -102, 2226, 2030, 1286, 1286, 1286
+  -102, 801, 1286, -102, -102, -102, 1286, 1286, -102, -102
+  -102, -102, -102, 1286, -102, 1286, 1286, -102, 1286, 1286
+  87, 190, -102, -102, 1286, 1286, 1286, -102, -102, -102
+  187, 1286, 251, 1286, 1286, 1286, 1286, 471, 1286, 1286
+  1286, 1286, 1286, 1286, 325, 1286, 1286, 1286, 128, 113
+  127, 182, 168, 159, 325, 325, 454, 406, 416, 1286
+  -7, 1286, 76, 2128, 1286, 1286, -102, -102, -102, -102
+  -102, -102, -102, -102, -102, -102, -102, -102, -102, -102
+  -102, -102, -102, -102, -102, -102, -102, -102, -102, -102
+  -102, -102, -102, -102, -102, -102, -102, -102, -102, -102
+  107, 1286, -102, -102, 68, 44, -102, 1286, -102, -102
+  1286, -102, -102, -102, -102, -102, -102, -102, -102, -102
+  -102, -102, -102, -102, 1286, 32, 1286, 1286, 88, 86
+  1286, -102, 2128, 1286, 1286, -102, 103, -102, 56, -102
+  -102, 65, -102, 398, 89, 63, -102, 274, -102, 62
+  2520, -102, -102, -102, -102, -102, 248, -102, -102, 47, 
+  -102, -102, -102, -102, -102, -102, 2520, -102, -102, 467
+  -102, 470, 73, 2422, 53, 398, 91, 67, 2716, 154
+  1286, -102, 64, 43, 1286, 41, -102, 39, 34, -102
+  -102, 398, -102, -102, -102, -102, -102, -102, 82, -102
+  -102, -102, -102, 90, -102, -102, -102, -102, -102, -102
+  -8, 51, 1286, 100, 77, -102, -102, 1472, -102, 84, 
+  38, 5, -102, 266, 70, 33, 555, 79, 74, 477
+  234, 320, 1286, 281, 1286, 1286, 1286, 1286, 311, 1286
+  1286, 1286, 1286, 1286, 230, 189, 213, 208, 325, 371
+  386, 396, 1286, 35, 1286, 81, 1286, -102, 649, 1286
+  -102, 1286, 60, 1, 1286, 31, 2422, -102, 1286, 140
+  2422, -102, 1286, 72, 1286, 1286, 97, 93, 1286, -102
+  50, 149, 61, -102, -102, 1286, -102, 310, 1286, -102
+  58, 1286, -25, 2422, -102, 1286, 125, 2422, -102, -35, 
+  292, -56, -31, 2520, -39, -102, 2422, -102, 1286, 141
+  2422, -5, 2422, -102, 6, 0, -33, -102, -102, 2422
+  -43, 550, 7, 478, 115, 1286, 2422, -1, -27, 451
+  8, -18, 627, 14, 16, -102, 1381, -102, 12, -19, 
+  3, 1286, 59, -30, 1286, -2, 1286, -29, -36, 1286
+  -102, 2324, 18, -102, -102, -102, -102, -102, -102, 1286
+  -102, -102, -102, -102, 203, -102, 1286, -10, -102, 2422
+  -102, 94, -102, -102, 2422, -102, 1286, 102, 20, -102
+  40, -102, 46, 99, 1286, -102, 55, 57, -102, 28, 
+  -102, 2422, -102, 114, 2422, -102, 161, -102, -102, 121
+  2422, 37, -102, -12, -4, -102, 398, -34, -6, -102
+  -102, -102, -102, 1286, 98, 2422, -102, 1286, 105, 2422
+  -102, 19, -102, 181, -102, -102, 1286, -102, -102, 288
+  -102, -102, -102, 110, 1657, -102, -102, 1842, -102, -102
+  1936, -102, -102, -102, -102, -102, -102, 122, -102, -102
+  -102, -102, -102, -102, -102, -102, 2520, -102, -102, -102
+  92, -26, 829, 142, -28, 4, -102, -102, 191, -102
+  202, -102, -102, -102, 398, 218, -102, 1563, -102, -102
+  -102, -102, -102, -102, 237, 2, 368, 207, 17, 398
+  205, -102, 10, -102, 919, 124, -102, 13, 919, -102
+  -102, 1103, -102, -102, -102, 1195, -102, -102, 214, -102
+  1563, -102, 271, 9, -102, -102, 174, 307, 30, 1563
+  -102, 228, -102, 212, -102, 26, -32, 301, 179, 265
+  -102, 75, -102, -102, -102, 1748, 919, 280, 2618, 2030
+  -3, -102, 459, 25, 486, 85, 1286, 2422, 24, 11, 
+  378, 36, 27, 711, 48, 49, -102, 1381, -102, 54, 
+  29, 45, 1286, 59, 15, 1286, 42, 1286, 23, 22, 
+  117, -102, -102, 21, -102, -102, 739, -102, 201, -70, 
+  919, -102, -102, 116, 398, -102, 143, -102, 129, -102
+  -102, 252, -102, -102, 126, -102, -102, -102, -102, -102
+  -102
 
   -107, 25, -75, 27, 30, 272, -107, -107, -107, -107, 
   -107, -107, -107, -107, -107, -107, -107, -107, -107, -42, 
@@ -342,252 +342,245 @@ const short QmlJSGrammar::action_info [] = {
   541, -110, -129, 561, 568, 333, 466, 559, 556, 527, 
   510, 529, 541, 346, 534, 424, 541, 257, 440, -126, 
   408, 424, -121, 420, 541, -118, -100, 444, 457, 453, 
-  424, -99, 304, 348, 431, -123, 251, 416, 325, 141, 
-  457, 101, 414, 164, 440, 453, 147, 71, 296, 416, 
-  99, 312, 272, 430, 294, 272, 252, 164, 141, 306, 
-  170, 335, 292, 640, 301, 257, 190, 187, 149, 346, 
-  183, 312, 236, 348, 318, 71, 141, 0, 0, 172, 
-  427, 141, 0, 179, 294, 141, 141, 331, 141, 314, 
-  99, 292, 189, 315, 141, 434, 141, 477, 173, 62, 
-  538, 141, 443, 538, 0, 249, 248, 141, 573, 572, 
-  63, 141, 616, 256, 255, 101, 444, 242, 241, 249, 
-  248, 247, 246, 172, 58, 428, 413, 412, 455, 409, 
-  58, 327, 141, 254, 177, 59, 142, 418, 58, 141, 
-  532, 59, 173, 249, 248, 478, 459, 58, 611, 59, 
-  166, 539, 172, 488, 167, 636, 635, 525, 59, 337, 
-  64, 64, 103, 310, 469, 630, 629, 85, 0, 86, 
-  64, 173, 0, 174, 633, 632, 85, 0, 86, 511, 
-  87, 104, 511, 105, 328, 235, 234, 575, 85, 87, 
-  86, 550, 438, 437, 533, 531, 85, 85, 86, 86, 
-  0, 87, 511, 513, 631, 65, 65, 517, 172, 87, 
-  87, 66, 66, 541, 512, 65, 0, 470, 468, 172, 
-  85, 66, 86, 141, 85, 513, 86, 173, 513, 406, 
-  85, 511, 86, 87, 0, 511, 512, 87, 173, 512, 
-  406, 0, 0, 87, 563, 551, 549, 172, 513, 0, 
-  0, 73, 74, 0, 0, 274, 275, 0, 0, 512, 
-  0, 518, 516, 274, 275, -87, 173, 34, 174, 564, 
-  562, 626, 576, 73, 74, 350, 172, 513, 75, 76, 
-  0, 513, 276, 277, 0, 627, 625, 34, 512, 0, 
-  276, 277, 512, 0, -87, 173, 34, 174, 279, 280, 
-  75, 76, 34, 0, 48, 50, 49, 281, 34, 0, 
-  282, 0, 283, 0, 34, 624, 85, 34, 86, 0, 
-  0, 0, 0, 0, 48, 50, 49, 0, 0, 87, 
-  45, 0, 0, 48, 50, 49, 0, 0, 0, 48, 
-  50, 49, 0, 0, 0, 48, 50, 49, 279, 280, 
-  45, 48, 50, 49, 48, 50, 49, 281, 0, 45, 
-  282, 0, 283, 0, 0, 45, 0, 279, 280, 0, 
-  0, 45, 0, 279, 280, 0, 281, 45, 0, 282, 
-  45, 283, 281, 34, 0, 282, 0, 283, 78, 79, 
-  -341, 0, 34, 0, 0, 0, 80, 81, 78, 79, 
-  82, 0, 83, 0, 0, 0, 80, 81, 0, 0, 
-  82, 0, 83, 6, 5, 4, 1, 3, 2, 0, 
-  48, 50, 49, 0, 78, 79, 0, 0, 0, 48, 
-  50, 49, 80, 81, 0, 0, 82, 0, 83, 78, 
-  79, 0, 34, 0, 0, 0, 45, 80, 81, 78, 
-  79, 82, 34, 83, 0, 45, 0, 80, 81, -341, 
-  34, 82, 0, 83, 279, 280, 0, 0, 0, 34, 
-  0, 0, 0, 281, 240, 239, 282, 0, 283, 48, 
-  50, 49, 0, 0, 0, 0, 0, 34, 0, 48, 
-  50, 49, 240, 239, 0, 0, 34, 48, 50, 49, 
-  0, 245, 244, 0, 0, 45, 48, 50, 49, 0, 
-  0, 0, 0, 0, 0, 45, 0, 0, 0, 245, 
-  244, 0, 0, 45, 48, 50, 49, 0, 245, 244, 
-  0, 0, 45, 48, 50, 49, 0, 0, 0, 0, 
-  0, 0, 34, 0, 0, 0, 0, 0, 151, 0, 
-  45, 0, 0, 0, 0, 0, 0, 0, 152, 45, 
-  0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 
-  0, 154, 0, 155, 240, 239, 308, 0, 0, 48, 
-  50, 49, 0, 0, 156, 0, 157, 62, 0, 0, 
+  424, -99, 304, 348, 431, 416, -123, 325, 141, 251, 
+  457, 414, 101, 164, 440, 453, 147, 71, 296, 416, 
+  99, 312, 272, 430, 294, 272, 292, 252, 141, 257, 
+  164, 306, 335, 170, 301, 190, 640, 187, 346, 312, 
+  318, 183, 236, 348, 149, 71, 141, 172, 141, 427, 
+  141, 141, 0, 141, 294, 141, 179, 99, 477, 331, 
+  292, 434, 141, 189, 314, 538, 173, 443, 315, 62, 
+  141, 172, 538, 141, 249, 248, 573, 572, 256, 255, 
+  63, 444, 616, 242, 241, 101, 249, 248, 141, 141, 
+  173, 247, 246, 58, 428, 413, 412, 327, 455, 177, 
+  254, 409, 418, 142, 59, 459, 478, 58, 58, 141, 
+  166, 525, 58, 611, 167, 172, 249, 248, 59, 59, 
+  539, 64, 488, 59, 85, 337, 86, 636, 635, 469, 
+  630, 629, 103, 85, 173, 86, 174, 87, 575, 64, 
+  310, 350, 64, 511, 633, 632, 87, 85, 511, 86, 
+  328, 104, 532, 105, 85, 0, 86, 513, 172, 0, 
+  87, 550, 438, 437, 541, 517, 65, 87, 512, 0, 
+  0, 511, 66, 85, 631, 86, 511, 173, 85, 406, 
+  86, 511, 470, 468, 65, 0, 87, 65, 626, 513, 
+  66, 87, 172, 66, 513, 85, 141, 86, 0, 85, 
+  512, 86, 627, 625, 563, 512, 533, 531, 87, 73, 
+  74, 173, 87, 406, 0, 551, 549, 513, 0, 518, 
+  516, 34, 513, 576, 274, 275, 172, 513, 512, 564, 
+  562, 0, 624, 512, 34, 172, 75, 76, 512, 274, 
+  275, 73, 74, 34, -87, 173, 0, 174, 0, 235, 
+  234, 276, 277, -87, 173, 0, 174, 34, 48, 50, 
+  49, 34, 0, 0, 0, 0, 276, 277, 75, 76, 
+  34, 48, 50, 49, 279, 280, 34, 0, 0, 34, 
+  48, 50, 49, 281, 45, 0, 282, 0, 283, 34, 
+  85, 0, 86, 34, 48, 50, 49, 45, 48, 50, 
+  49, 0, 0, 87, 0, 0, 45, 48, 50, 49, 
+  0, 0, 0, 48, 50, 49, 48, 50, 49, 0, 
+  45, 0, 0, 0, 45, 0, 48, 50, 49, 0, 
+  48, 50, 49, 45, 279, 280, 0, 34, 0, 45, 
+  0, 0, 45, 281, 0, 0, 282, 34, 283, 279, 
+  280, 0, 45, 0, -341, 0, 45, 0, 281, 279, 
+  280, 282, 0, 283, 0, 0, 0, 34, 281, 78, 
+  79, 282, 0, 283, 48, 50, 49, 80, 81, 78, 
+  79, 82, 0, 83, 48, 50, 49, 80, 81, 0, 
+  0, 82, 0, 83, 6, 5, 4, 1, 3, 2, 
+  45, 0, 0, 0, 48, 50, 49, 78, 79, 0, 
+  45, 0, 0, 0, 0, 80, 81, 78, 79, 82, 
+  34, 83, 0, 0, 0, 80, 81, -341, 34, 82, 
+  45, 83, 0, 0, 78, 79, 34, 0, 0, 34, 
+  279, 280, 80, 81, 0, 0, 82, 34, 83, 281, 
+  0, 0, 282, 0, 283, 34, 0, 48, 50, 49, 
+  240, 239, 0, 0, 0, 48, 50, 49, 240, 239, 
+  0, 245, 244, 48, 50, 49, 48, 50, 49, 245, 
+  244, 0, 0, 45, 48, 50, 49, 245, 244, 0, 
+  0, 45, 48, 50, 49, 0, 0, 0, 151, 45, 
+  0, 0, 45, 0, 0, 0, 0, 0, 152, 0, 
+  45, 0, 153, 0, 0, 0, 0, 0, 45, 34, 
+  0, 154, 0, 155, 0, 0, 308, 0, 0, 0, 
+  0, 0, 0, 0, 156, 0, 157, 62, 0, 0, 
   0, 0, 0, 0, 158, 0, 0, 159, 63, 0, 
-  0, 0, 0, 160, 0, 45, 0, 0, 0, 161, 
-  0, 0, 30, 31, 151, 0, 0, 0, 0, 0, 
-  0, 0, 33, 0, 152, 162, 0, 0, 153, 34, 
-  0, 0, 0, 35, 36, 0, 37, 154, 0, 155, 
-  0, 0, 0, 41, 0, 0, 0, 44, 0, 0, 
-  156, 0, 157, 62, 0, 0, 0, 0, 0, 0, 
-  158, 0, 0, 159, 63, 51, 48, 50, 49, 160, 
-  52, 0, 0, 0, 0, 161, 0, 0, 0, 0, 
-  0, 43, 54, 32, 30, 31, 0, 40, 0, 0, 
-  0, 162, 45, 0, 33, 0, 0, 0, 0, 0, 
-  0, 34, 0, 0, 0, 35, 36, 0, 37, 0, 
-  0, 0, 30, 31, 0, 41, 0, 0, 0, 44, 
-  0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 
-  0, 0, 0, 35, 36, 0, 37, 51, 48, 50, 
-  49, 0, 52, 502, 0, 0, 0, 44, 0, 0, 
-  0, 0, 0, 43, 54, 32, 0, 0, 0, 40, 
-  0, 0, 0, 0, 45, 51, 48, 50, 49, 0, 
-  52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 43, 54, 32, 0, 0, 0, 40, 0, 0, 
-  0, 0, 45, 30, 31, 0, 0, 0, 0, 0, 
-  0, 30, 31, 33, 0, 0, 0, 0, 0, 0, 
-  34, 33, 0, 0, 35, 36, 0, 37, 34, 0, 
-  0, 0, 35, 36, 41, 37, 0, 0, 44, 0, 
-  0, 0, 502, 0, 0, 0, 44, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 51, 48, 50, 49, 
-  0, 52, 0, 0, 51, 48, 50, 49, 0, 52, 
+  0, 240, 239, 160, 0, 0, 48, 50, 49, 161, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 162, 0, 0, 0, 30, 
+  31, 0, 45, 0, 0, 0, 0, 0, 0, 33, 
+  0, 0, 151, 0, 0, 0, 34, 0, 0, 0, 
+  35, 36, 152, 37, 0, 0, 153, 0, 0, 0, 
+  41, 0, 0, 0, 44, 154, 0, 155, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 
+  157, 62, 51, 48, 50, 49, 0, 52, 158, 0, 
+  0, 159, 63, 0, 0, 0, 0, 160, 43, 54, 
+  32, 0, 0, 161, 40, 0, 0, 0, 0, 45, 
+  0, 0, 0, 30, 31, 0, 0, 0, 0, 162, 
+  0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 
+  34, 0, 0, 0, 35, 36, 0, 37, 0, 0, 
+  0, 30, 31, 0, 41, 0, 0, 0, 44, 0, 
+  0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 
+  0, 0, 35, 36, 0, 37, 51, 48, 50, 49, 
+  0, 52, 502, 0, 0, 0, 44, 0, 0, 0, 
   0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 
-  43, 54, 32, 45, 0, 0, 40, 0, 0, 0, 
-  0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 
-  30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 
-  33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 
-  0, 35, 36, 0, 37, 0, 0, 0, 0, 0, 
-  0, 502, 0, 0, 0, 44, 0, 0, 0, 0, 
+  0, 0, 0, 45, 51, 48, 50, 49, 0, 52, 
+  0, 0, 0, 30, 31, 0, 0, 0, 0, 0, 
+  43, 54, 32, 33, 0, 0, 40, 0, 0, 0, 
+  34, 45, 0, 0, 35, 36, 0, 37, 0, 0, 
+  0, 30, 31, 0, 41, 0, 0, 0, 44, 0, 
+  0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 
+  0, 0, 35, 36, 0, 37, 51, 48, 50, 49, 
+  0, 52, 502, 0, 0, 0, 44, 0, 0, 0, 
+  0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 
+  0, 0, 0, 45, 51, 48, 50, 49, 0, 52, 
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 51, 48, 50, 49, 0, 52, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 
-  54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 
-  45, 0, 0, 0, 0, 0, 0, 0, 0, 501, 
+  43, 54, 32, 0, 0, 0, 40, 0, 0, 0, 
+  0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 
   0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 
-  0, 215, 0, 0, 0, 0, 0, 0, 34, 0, 
+  0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 
   0, 0, 35, 36, 0, 37, 0, 0, 0, 0, 
   0, 0, 502, 0, 0, 0, 44, 0, 0, 0, 
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 51, 503, 505, 504, 0, 52, 
-  0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 
-  43, 54, 32, 210, 0, 0, 40, 0, 0, 0, 
+  0, 0, 0, 0, 51, 48, 50, 49, 0, 52, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  43, 54, 32, 0, 0, 0, 40, 0, 0, 0, 
   0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 
-  501, 0, 30, 31, 0, 0, 0, 0, 0, 0, 
-  0, 0, 215, 0, 0, 0, 0, 0, 0, 34, 
-  0, 0, 0, 35, 36, 0, 37, 0, 0, 0, 
-  0, 0, 0, 502, 0, 0, 0, 44, 0, 0, 
-  0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 51, 503, 505, 504, 0, 
-  52, 0, 0, 0, 0, 226, 0, 0, 0, 0, 
-  0, 43, 54, 32, 210, 0, 0, 40, 0, 0, 
-  0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 
   0, 501, 0, 30, 31, 0, 0, 0, 0, 0, 
   0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 
   34, 0, 0, 0, 35, 36, 0, 37, 0, 0, 
   0, 0, 0, 0, 502, 0, 0, 0, 44, 0, 
-  0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
   0, 0, 0, 0, 0, 0, 51, 503, 505, 504, 
   0, 52, 0, 0, 0, 0, 226, 0, 0, 0, 
   0, 0, 43, 54, 32, 210, 0, 0, 40, 0, 
   0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 
-  0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 
-  0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 
-  34, 0, 0, 0, 35, 36, 0, 37, 0, 0
-  0, 38, 0, 39, 41, 42, 0, 0, 44, 0, 
-  0, 0, 46, 0, 47, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 51, 48, 50, 49
-  0, 52, 0, 53, 0, 55, 0, 56, 0, 0, 
-  0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 
-  0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 
-  0, 0, -119, 0, 0, 0, 29, 30, 31, 0, 
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 
+  0, 0, 0, 501, 0, 30, 31, 0, 0, 0, 
+  0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 
+  0, 0, 34, 0, 0, 0, 35, 36, 0, 37
+  0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 
+  44, 0, 0, 0, 0, 0, 0, 0, 543, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 51, 503
+  505, 504, 0, 52, 0, 0, 0, 0, 226, 0, 
+  0, 0, 0, 0, 43, 54, 32, 210, 0, 0, 
+  40, 0, 0, 0, 0, 45, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 501, 0, 30, 31, 0, 
+  0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 
   0, 0, 0, 0, 34, 0, 0, 0, 35, 36, 
-  0, 37, 0, 0, 0, 38, 0, 39, 41, 42
-  0, 0, 44, 0, 0, 0, 46, 0, 47, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  51, 48, 50, 49, 0, 52, 0, 53, 0, 55
-  0, 56, 0, 0, 0, 0, 43, 54, 32, 0, 
+  0, 37, 0, 0, 0, 0, 0, 0, 502, 0
+  0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 
+  546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  51, 503, 505, 504, 0, 52, 0, 0, 0, 0
+  226, 0, 0, 0, 0, 0, 43, 54, 32, 210, 
   0, 0, 40, 0, 0, 0, 0, 45, 0, 0, 
-  0, 0, 0, 0, 0, 0, 29, 30, 31, 0
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 
-  0, 0, 0, 0, 34, 0, 0, 0, 35, 36
-  0, 37, 0, 0, 0, 38, 0, 39, 41, 42
-  0, 0, 44, 0, 0, 0, 46, 0, 47, 0
+  0, 0, 0, 0, 0, 0, 0, 29, 30, 31
+  0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 
+  0, 0, 0, 0, 0, 34, 0, 0, 0, 35
+  36, 0, 37, 0, 0, 0, 38, 0, 39, 41
+  42, 0, 0, 44, 0, 0, 0, 46, 0, 47
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  51, 48, 50, 49, 0, 52, 0, 53, 0, 55, 
-  271, 56, 0, 0, 0, 0, 43, 54, 32, 0, 
-  0, 0, 40, 0, 0, 0, 0, 45, 0, 0, 
-  0, 0, 0, 0, 0, 0, 29, 30, 31, 0, 
-  0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 
-  0, 0, 0, 0, 34, 217, 0, 0, 218, 36, 
-  0, 37, 0, 0, 0, 38, 0, 39, 41, 42, 
-  0, 0, 44, 0, 0, 0, 46, 0, 47, 0, 
-  0, 0, 0, 0, 0, 0, 221, 0, 0, 0, 
-  51, 48, 50, 49, 0, 52, 0, 53, 0, 55, 
-  0, 56, 0, 0, 0, 0, 43, 54, 32, 0, 
-  0, 0, 40, 0, 0, 0, 0, 45, 0, 0, 
-  0, 0, 0, 0, 0, 0, 483, 0, 0, 29, 
-  30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 
-  33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 
-  0, 35, 36, 0, 37, 0, 0, 0, 38, 0, 
-  39, 41, 42, 0, 0, 44, 0, 0, 0, 46, 
-  0, 47, 0, 0, 486, 0, 0, 0, 0, 0, 
-  0, 0, 0, 51, 48, 50, 49, 0, 52, 0, 
-  53, 0, 55, 0, 56, 0, 0, 0, 0, 43, 
-  54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 
-  45, 0, 0, 0, 0, 0, 0, 0, 0, 29, 
-  30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 
-  33, 0, 0, 0, 0, 0, 0, 34, 217, 0, 
-  0, 578, 579, 0, 37, 0, 0, 0, 38, 0, 
-  39, 41, 42, 0, 0, 44, 0, 0, 0, 46, 
-  0, 47, 0, 0, 0, 0, 0, 0, 0, 221, 
-  0, 0, 0, 51, 48, 50, 49, 0, 52, 0, 
-  53, 0, 55, 0, 56, 0, 0, 0, 0, 43, 
-  54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 
-  45, 0, 0, 0, 0, 0, 0, 0, 0, 475, 
+  0, 51, 48, 50, 49, 0, 52, 0, 53, 0, 
+  55, 0, 56, 0, 0, 0, 0, 43, 54, 32, 
+  0, 0, 0, 40, 0, 0, 0, 0, 45, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, -119, 0, 
   0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 
   0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 
   34, 0, 0, 0, 35, 36, 0, 37, 0, 0, 
   0, 38, 0, 39, 41, 42, 0, 0, 44, 0, 
-  0, 0, 46, 0, 47, 0, 0, 481, 0, 0, 
+  0, 0, 46, 0, 47, 0, 0, 0, 0, 0, 
   0, 0, 0, 0, 0, 0, 51, 48, 50, 49, 
   0, 52, 0, 53, 0, 55, 0, 56, 0, 0, 
   0, 0, 43, 54, 32, 0, 0, 0, 40, 0, 
   0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 
-  0, 0, 483, 0, 0, 29, 30, 31, 0, 0, 
-  0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 
-  0, 0, 0, 34, 0, 0, 0, 35, 36, 0, 
-  37, 0, 0, 0, 38, 0, 39, 41, 42, 0, 
-  0, 44, 0, 0, 0, 46, 0, 47, 0, 0, 
-  484, 0, 0, 0, 0, 0, 0, 0, 0, 51, 
-  48, 50, 49, 0, 52, 0, 53, 0, 55, 0, 
-  56, 0, 0, 0, 0, 43, 54, 32, 0, 0, 
-  0, 40, 0, 0, 0, 0, 45, 0, 0, 0, 
-  0, 0, 0, 0, 0, 475, 0, 0, 29, 30, 
+  0, 0, 0, 29, 30, 31, 0, 0, 0, 0, 
+  0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 
+  0, 34, 0, 0, 0, 35, 36, 0, 37, 0, 
+  0, 0, 38, 0, 39, 41, 42, 0, 0, 44, 
+  0, 0, 0, 46, 0, 47, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 51, 48, 50, 
+  49, 0, 52, 0, 53, 0, 55, 271, 56, 0, 
+  0, 0, 0, 43, 54, 32, 0, 0, 0, 40, 
+  0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 29, 30, 31, 0, 0, 0, 
+  0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 
+  0, 0, 34, 217, 0, 0, 218, 36, 0, 37, 
+  0, 0, 0, 38, 0, 39, 41, 42, 0, 0, 
+  44, 0, 0, 0, 46, 0, 47, 0, 0, 0, 
+  0, 0, 0, 0, 221, 0, 0, 0, 51, 48, 
+  50, 49, 0, 52, 0, 53, 0, 55, 0, 56, 
+  0, 0, 0, 0, 43, 54, 32, 0, 0, 0, 
+  40, 0, 0, 0, 0, 45, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 483, 0, 0, 29, 30, 
   31, 0, 0, 0, 0, 0, 0, 0, 0, 33, 
   0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 
   35, 36, 0, 37, 0, 0, 0, 38, 0, 39, 
   41, 42, 0, 0, 44, 0, 0, 0, 46, 0, 
-  47, 0, 0, 476, 0, 0, 0, 0, 0, 0, 
+  47, 0, 0, 486, 0, 0, 0, 0, 0, 0, 
   0, 0, 51, 48, 50, 49, 0, 52, 0, 53, 
   0, 55, 0, 56, 0, 0, 0, 0, 43, 54, 
   32, 0, 0, 0, 40, 0, 0, 0, 0, 45, 
-  0, 0, 0, 0, 0, 0, 0, 0, 109, 110, 
-  111, 0, 0, 113, 115, 116, 0, 0, 117, 0, 
-  118, 0, 0, 0, 120, 121, 122, 0, 0, 0, 
-  0, 0, 0, 34, 123, 124, 125, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 
-  48, 50, 49, 130, 131, 132, 0, 134, 135, 136, 
-  137, 138, 139, 0, 0, 127, 133, 119, 112, 114, 
-  128, 0, 0, 0, 0, 0, 45, 0, 0, 0, 
-  0, 0, 0, 0, 0, 109, 110, 111, 0, 0, 
-  113, 115, 116, 0, 0, 117, 0, 118, 0, 0, 
-  0, 120, 121, 122, 0, 0, 0, 0, 0, 0, 
-  393, 123, 124, 125, 0, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 126, 0, 0, 0, 394, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  129, 0, 0, 0, 0, 0, 398, 395, 397, 0, 
-  130, 131, 132, 0, 134, 135, 136, 137, 138, 139, 
-  0, 0, 127, 133, 119, 112, 114, 128, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 
+  30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 
+  33, 0, 0, 0, 0, 0, 0, 34, 217, 0, 
+  0, 578, 579, 0, 37, 0, 0, 0, 38, 0, 
+  39, 41, 42, 0, 0, 44, 0, 0, 0, 46, 
+  0, 47, 0, 0, 0, 0, 0, 0, 0, 221, 
+  0, 0, 0, 51, 48, 50, 49, 0, 52, 0, 
+  53, 0, 55, 0, 56, 0, 0, 0, 0, 43, 
+  54, 32, 0, 0, 0, 40, 0, 0, 0, 0, 
+  45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  475, 0, 0, 29, 30, 31, 0, 0, 0, 0, 
+  0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 
+  0, 34, 0, 0, 0, 35, 36, 0, 37, 0, 
+  0, 0, 38, 0, 39, 41, 42, 0, 0, 44, 
+  0, 0, 0, 46, 0, 47, 0, 0, 481, 0, 
+  0, 0, 0, 0, 0, 0, 0, 51, 48, 50, 
+  49, 0, 52, 0, 53, 0, 55, 0, 56, 0, 
+  0, 0, 0, 43, 54, 32, 0, 0, 0, 40, 
+  0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 483, 0, 0, 29, 30, 31, 
+  0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 
+  0, 0, 0, 0, 0, 34, 0, 0, 0, 35, 
+  36, 0, 37, 0, 0, 0, 38, 0, 39, 41, 
+  42, 0, 0, 44, 0, 0, 0, 46, 0, 47, 
+  0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 
+  0, 51, 48, 50, 49, 0, 52, 0, 53, 0, 
+  55, 0, 56, 0, 0, 0, 0, 43, 54, 32, 
+  0, 0, 0, 40, 0, 0, 0, 0, 45, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 475, 0, 
+  0, 29, 30, 31, 0, 0, 0, 0, 0, 0, 
+  0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 
+  0, 0, 0, 35, 36, 0, 37, 0, 0, 0, 
+  38, 0, 39, 41, 42, 0, 0, 44, 0, 0, 
+  0, 46, 0, 47, 0, 0, 476, 0, 0, 0, 
+  0, 0, 0, 0, 0, 51, 48, 50, 49, 0, 
+  52, 0, 53, 0, 55, 0, 56, 0, 0, 0, 
+  0, 43, 54, 32, 0, 0, 0, 40, 0, 0, 
+  0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 
   0, 0, 109, 110, 111, 0, 0, 113, 115, 116, 
   0, 0, 117, 0, 118, 0, 0, 0, 120, 121, 
-  122, 0, 0, 0, 0, 0, 0, 393, 123, 124, 
+  122, 0, 0, 0, 0, 0, 0, 34, 123, 124, 
   125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-  0, 126, 0, 0, 0, 394, 0, 0, 0, 0, 
-  0, 0, 0, 396, 0, 0, 0, 129, 0, 0, 
-  0, 0, 0, 398, 395, 397, 0, 130, 131, 132, 
+  0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 129, 0, 0, 
+  0, 0, 0, 0, 48, 50, 49, 130, 131, 132, 
   0, 134, 135, 136, 137, 138, 139, 0, 0, 127, 
   133, 119, 112, 114, 128, 0, 0, 0, 0, 0, 
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 
-  0, 0, 0, 0, 211, 0, 29, 30, 31, 213, 
-  0, 0, 0, 0, 0, 0, 214, 33, 0, 0, 
-  0, 0, 0, 0, 216, 217, 0, 0, 218, 36, 
-  0, 37, 0, 0, 0, 38, 0, 39, 41, 42, 
-  0, 0, 44, 0, 0, 0, 46, 0, 47, 0, 
-  0, 0, 0, 0, 220, 0, 221, 0, 0, 0, 
-  51, 219, 222, 49, 223, 52, 224, 53, 225, 55, 
-  226, 56, 227, 228, 0, 0, 43, 54, 32, 210, 
-  212, 0, 40, 0, 0, 0, 0, 45, 0, 0, 
+  45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  109, 110, 111, 0, 0, 113, 115, 116, 0, 0, 
+  117, 0, 118, 0, 0, 0, 120, 121, 122, 0, 
+  0, 0, 0, 0, 0, 393, 123, 124, 125, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 
+  0, 0, 0, 394, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 129, 0, 0, 0, 0, 
+  0, 398, 395, 397, 0, 130, 131, 132, 0, 134, 
+  135, 136, 137, 138, 139, 0, 0, 127, 133, 119, 
+  112, 114, 128, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 109, 110, 
+  111, 0, 0, 113, 115, 116, 0, 0, 117, 0, 
+  118, 0, 0, 0, 120, 121, 122, 0, 0, 0, 
+  0, 0, 0, 393, 123, 124, 125, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 
+  0, 394, 0, 0, 0, 0, 0, 0, 0, 396, 
+  0, 0, 0, 129, 0, 0, 0, 0, 0, 398, 
+  395, 397, 0, 130, 131, 132, 0, 134, 135, 136, 
+  137, 138, 139, 0, 0, 127, 133, 119, 112, 114, 
+  128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
   0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 
   0, 211, 0, 29, 30, 31, 213, 0, 0, 0, 
-  0, 0, 0, 214, 215, 0, 0, 0, 0, 0, 
+  0, 0, 0, 214, 33, 0, 0, 0, 0, 0, 
   0, 216, 217, 0, 0, 218, 36, 0, 37, 0, 
   0, 0, 38, 0, 39, 41, 42, 0, 0, 44, 
   0, 0, 0, 46, 0, 47, 0, 0, 0, 0, 
@@ -595,16 +588,26 @@ const short QmlJSGrammar::action_info [] = {
   49, 223, 52, 224, 53, 225, 55, 226, 56, 227, 
   228, 0, 0, 43, 54, 32, 210, 212, 0, 40, 
   0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 
-  0, 0, 0, 582, 110, 111, 0, 0, 584, 115, 
-  586, 30, 31, 587, 0, 118, 0, 0, 0, 120, 
-  589, 590, 0, 0, 0, 0, 0, 0, 591, 592, 
-  124, 125, 218, 36, 0, 37, 0, 0, 0, 38, 
-  0, 39, 593, 42, 0, 0, 595, 0, 0, 0, 
-  46, 0, 47, 0, 0, 0, 0, 0, 597, 0, 
-  221, 0, 0, 0, 599, 596, 598, 49, 600, 601, 
-  602, 53, 604, 605, 606, 607, 608, 609, 0, 0, 
-  594, 603, 588, 583, 585, 128, 40, 0, 0, 0, 
-  0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 209, 0, 0, 0, 0, 211, 
+  0, 29, 30, 31, 213, 0, 0, 0, 0, 0, 
+  0, 214, 215, 0, 0, 0, 0, 0, 0, 216, 
+  217, 0, 0, 218, 36, 0, 37, 0, 0, 0, 
+  38, 0, 39, 41, 42, 0, 0, 44, 0, 0, 
+  0, 46, 0, 47, 0, 0, 0, 0, 0, 220, 
+  0, 221, 0, 0, 0, 51, 219, 222, 49, 223, 
+  52, 224, 53, 225, 55, 226, 56, 227, 228, 0, 
+  0, 43, 54, 32, 210, 212, 0, 40, 0, 0, 
+  0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 582, 110, 111, 0, 0, 584, 115, 586, 
+  30, 31, 587, 0, 118, 0, 0, 0, 120, 589, 
+  590, 0, 0, 0, 0, 0, 0, 591, 592, 124, 
+  125, 218, 36, 0, 37, 0, 0, 0, 38, 0, 
+  39, 593, 42, 0, 0, 595, 0, 0, 0, 46, 
+  0, 47, 0, 0, 0, 0, 0, 597, 0, 221, 
+  0, 0, 0, 599, 596, 598, 49, 600, 601, 602, 
+  53, 604, 605, 606, 607, 608, 609, 0, 0, 594, 
+  603, 588, 583, 585, 128, 40, 0, 0, 0, 0, 
+  45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
   361, 110, 111, 0, 0, 363, 115, 365, 30, 31, 
   366, 0, 118, 0, 0, 0, 120, 368, 369, 0, 
   0, 0, 0, 0, 0, 370, 371, 124, 125, 218, 
@@ -614,7 +617,7 @@ const short QmlJSGrammar::action_info [] = {
   0, 378, 375, 377, 49, 379, 380, 381, 53, 383, 
   384, 385, 386, 387, 388, 0, 0, 373, 382, 367, 
   362, 364, 128, 40, 0, 0, 0, 0, 45, 0, 
-  0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 
 
   567, 169, 558, 570, 574, 515, 569, 557, 309, 548, 
   461, 528, 311, 530, 417, 555, 307, 188, 415, 358, 
@@ -672,201 +675,166 @@ const short QmlJSGrammar::action_check [] = {
   33, 7, 7, 29, 8, 60, 17, 7, 66, 37, 
   66, 24, 33, 7, 34, 5, 33, 36, 33, 7, 
   60, 5, 7, 33, 33, 7, 7, 20, 36, 36, 
-  5, 7, 61, 36, 7, 7, 77, 36, 17, 8, 
-  36, 79, 7, 2, 33, 36, 8, 1, 8, 36, 
-  48, 2, 1, 55, 79, 1, 36, 2, 8, 60, 
-  7, 31, 48, 0, 61, 36, 33, 8, 60, 7, 
-  36, 2, 55, 36, 7, 1, 8, -1, -1, 15, 
-  10, 8, -1, 60, 79, 8, 8, 61, 8, 50, 
-  48, 48, 60, 54, 8, 7, 8, 8, 34, 42, 
-  8, 8, 6, 8, -1, 61, 62, 8, 61, 62, 
-  53, 8, 90, 61, 62, 79, 20, 61, 62, 61, 
-  62, 61, 62, 15, 40, 55, 61, 62, 60, 7, 
-  40, 8, 8, 60, 56, 51, 56, 60, 40, 8, 
-  7, 51, 34, 61, 62, 56, 60, 40, 56, 51, 
-  50, 56, 15, 60, 54, 61, 62, 29, 51, 60, 
-  12, 12, 15, 60, 8, 61, 62, 25, -1, 27, 
-  12, 34, -1, 36, 61, 62, 25, -1, 27, 29, 
-  38, 34, 29, 36, 61, 61, 62, 7, 25, 38, 
-  27, 7, 61, 62, 61, 62, 25, 25, 27, 27, 
-  -1, 38, 29, 75, 91, 57, 57, 7, 15, 38, 
-  38, 63, 63, 33, 86, 57, -1, 61, 62, 15, 
-  25, 63, 27, 8, 25, 75, 27, 34, 75, 36, 
-  25, 29, 27, 38, -1, 29, 86, 38, 34, 86, 
-  36, -1, -1, 38, 36, 61, 62, 15, 75, -1, 
-  -1, 18, 19, -1, -1, 18, 19, -1, -1, 86, 
-  -1, 61, 62, 18, 19, 33, 34, 29, 36, 61, 
-  62, 47, 92, 18, 19, 60, 15, 75, 45, 46, 
-  -1, 75, 45, 46, -1, 61, 62, 29, 86, -1, 
-  45, 46, 86, -1, 33, 34, 29, 36, 23, 24, 
-  45, 46, 29, -1, 66, 67, 68, 32, 29, -1, 
-  35, -1, 37, -1, 29, 91, 25, 29, 27, -1, 
-  -1, -1, -1, -1, 66, 67, 68, -1, -1, 38, 
-  92, -1, -1, 66, 67, 68, -1, -1, -1, 66, 
-  67, 68, -1, -1, -1, 66, 67, 68, 23, 24, 
-  92, 66, 67, 68, 66, 67, 68, 32, -1, 92, 
-  35, -1, 37, -1, -1, 92, -1, 23, 24, -1, 
-  -1, 92, -1, 23, 24, -1, 32, 92, -1, 35, 
-  92, 37, 32, 29, -1, 35, -1, 37, 23, 24, 
-  36, -1, 29, -1, -1, -1, 31, 32, 23, 24, 
-  35, -1, 37, -1, -1, -1, 31, 32, -1, -1, 
-  35, -1, 37, 93, 94, 95, 96, 97, 98, -1, 
-  66, 67, 68, -1, 23, 24, -1, -1, -1, 66, 
-  67, 68, 31, 32, -1, -1, 35, -1, 37, 23, 
-  24, -1, 29, -1, -1, -1, 92, 31, 32, 23, 
-  24, 35, 29, 37, -1, 92, -1, 31, 32, 36, 
-  29, 35, -1, 37, 23, 24, -1, -1, -1, 29, 
-  -1, -1, -1, 32, 61, 62, 35, -1, 37, 66, 
-  67, 68, -1, -1, -1, -1, -1, 29, -1, 66, 
-  67, 68, 61, 62, -1, -1, 29, 66, 67, 68, 
-  -1, 61, 62, -1, -1, 92, 66, 67, 68, -1, 
-  -1, -1, -1, -1, -1, 92, -1, -1, -1, 61, 
-  62, -1, -1, 92, 66, 67, 68, -1, 61, 62, 
-  -1, -1, 92, 66, 67, 68, -1, -1, -1, -1, 
-  -1, -1, 29, -1, -1, -1, -1, -1, 3, -1, 
-  92, -1, -1, -1, -1, -1, -1, -1, 13, 92, 
-  -1, -1, 17, -1, -1, -1, -1, -1, -1, -1, 
-  -1, 26, -1, 28, 61, 62, 31, -1, -1, 66, 
-  67, 68, -1, -1, 39, -1, 41, 42, -1, -1, 
+  5, 7, 61, 36, 7, 36, 7, 17, 8, 77, 
+  36, 7, 79, 2, 33, 36, 8, 1, 8, 36, 
+  48, 2, 1, 55, 79, 1, 48, 36, 8, 36, 
+  2, 60, 31, 7, 61, 33, 0, 8, 7, 2, 
+  7, 36, 55, 36, 60, 1, 8, 15, 8, 10, 
+  8, 8, -1, 8, 79, 8, 60, 48, 8, 61, 
+  48, 7, 8, 60, 50, 8, 34, 6, 54, 42, 
+  8, 15, 8, 8, 61, 62, 61, 62, 61, 62, 
+  53, 20, 90, 61, 62, 79, 61, 62, 8, 8, 
+  34, 61, 62, 40, 55, 61, 62, 8, 60, 56, 
+  60, 7, 60, 56, 51, 60, 56, 40, 40, 8, 
+  50, 29, 40, 56, 54, 15, 61, 62, 51, 51, 
+  56, 12, 60, 51, 25, 60, 27, 61, 62, 8, 
+  61, 62, 15, 25, 34, 27, 36, 38, 7, 12, 
+  60, 60, 12, 29, 61, 62, 38, 25, 29, 27, 
+  61, 34, 7, 36, 25, -1, 27, 75, 15, -1, 
+  38, 7, 61, 62, 33, 7, 57, 38, 86, -1, 
+  -1, 29, 63, 25, 91, 27, 29, 34, 25, 36, 
+  27, 29, 61, 62, 57, -1, 38, 57, 47, 75, 
+  63, 38, 15, 63, 75, 25, 8, 27, -1, 25, 
+  86, 27, 61, 62, 36, 86, 61, 62, 38, 18, 
+  19, 34, 38, 36, -1, 61, 62, 75, -1, 61, 
+  62, 29, 75, 92, 18, 19, 15, 75, 86, 61, 
+  62, -1, 91, 86, 29, 15, 45, 46, 86, 18, 
+  19, 18, 19, 29, 33, 34, -1, 36, -1, 61, 
+  62, 45, 46, 33, 34, -1, 36, 29, 66, 67, 
+  68, 29, -1, -1, -1, -1, 45, 46, 45, 46, 
+  29, 66, 67, 68, 23, 24, 29, -1, -1, 29, 
+  66, 67, 68, 32, 92, -1, 35, -1, 37, 29, 
+  25, -1, 27, 29, 66, 67, 68, 92, 66, 67, 
+  68, -1, -1, 38, -1, -1, 92, 66, 67, 68, 
+  -1, -1, -1, 66, 67, 68, 66, 67, 68, -1, 
+  92, -1, -1, -1, 92, -1, 66, 67, 68, -1, 
+  66, 67, 68, 92, 23, 24, -1, 29, -1, 92, 
+  -1, -1, 92, 32, -1, -1, 35, 29, 37, 23, 
+  24, -1, 92, -1, 36, -1, 92, -1, 32, 23, 
+  24, 35, -1, 37, -1, -1, -1, 29, 32, 23, 
+  24, 35, -1, 37, 66, 67, 68, 31, 32, 23, 
+  24, 35, -1, 37, 66, 67, 68, 31, 32, -1, 
+  -1, 35, -1, 37, 94, 95, 96, 97, 98, 99, 
+  92, -1, -1, -1, 66, 67, 68, 23, 24, -1, 
+  92, -1, -1, -1, -1, 31, 32, 23, 24, 35, 
+  29, 37, -1, -1, -1, 31, 32, 36, 29, 35, 
+  92, 37, -1, -1, 23, 24, 29, -1, -1, 29, 
+  23, 24, 31, 32, -1, -1, 35, 29, 37, 32, 
+  -1, -1, 35, -1, 37, 29, -1, 66, 67, 68, 
+  61, 62, -1, -1, -1, 66, 67, 68, 61, 62, 
+  -1, 61, 62, 66, 67, 68, 66, 67, 68, 61, 
+  62, -1, -1, 92, 66, 67, 68, 61, 62, -1, 
+  -1, 92, 66, 67, 68, -1, -1, -1, 3, 92, 
+  -1, -1, 92, -1, -1, -1, -1, -1, 13, -1, 
+  92, -1, 17, -1, -1, -1, -1, -1, 92, 29, 
+  -1, 26, -1, 28, -1, -1, 31, -1, -1, -1, 
+  -1, -1, -1, -1, 39, -1, 41, 42, -1, -1, 
   -1, -1, -1, -1, 49, -1, -1, 52, 53, -1, 
-  -1, -1, -1, 58, -1, 92, -1, -1, -1, 64, 
-  -1, -1, 12, 13, 3, -1, -1, -1, -1, -1, 
-  -1, -1, 22, -1, 13, 80, -1, -1, 17, 29, 
-  -1, -1, -1, 33, 34, -1, 36, 26, -1, 28, 
-  -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, 
-  39, -1, 41, 42, -1, -1, -1, -1, -1, -1, 
-  49, -1, -1, 52, 53, 65, 66, 67, 68, 58, 
-  70, -1, -1, -1, -1, 64, -1, -1, -1, -1, 
-  -1, 81, 82, 83, 12, 13, -1, 87, -1, -1, 
-  -1, 80, 92, -1, 22, -1, -1, -1, -1, -1, 
-  -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, 
-  -1, -1, 12, 13, -1, 43, -1, -1, -1, 47, 
-  -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, 
-  -1, -1, -1, 33, 34, -1, 36, 65, 66, 67, 
-  68, -1, 70, 43, -1, -1, -1, 47, -1, -1, 
-  -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, 
-  -1, -1, -1, -1, 92, 65, 66, 67, 68, -1, 
-  70, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, 
-  -1, -1, 92, 12, 13, -1, -1, -1, -1, -1, 
-  -1, 12, 13, 22, -1, -1, -1, -1, -1, -1, 
-  29, 22, -1, -1, 33, 34, -1, 36, 29, -1, 
-  -1, -1, 33, 34, 43, 36, -1, -1, 47, -1, 
-  -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, 
-  -1, 70, -1, -1, 65, 66, 67, 68, -1, 70, 
+  -1, 61, 62, 58, -1, -1, 66, 67, 68, 64, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 80, -1, -1, -1, 12, 
+  13, -1, 92, -1, -1, -1, -1, -1, -1, 22, 
+  -1, -1, 3, -1, -1, -1, 29, -1, -1, -1, 
+  33, 34, 13, 36, -1, -1, 17, -1, -1, -1, 
+  43, -1, -1, -1, 47, 26, -1, 28, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 39, -1, 
+  41, 42, 65, 66, 67, 68, -1, 70, 49, -1, 
+  -1, 52, 53, -1, -1, -1, -1, 58, 81, 82, 
+  83, -1, -1, 64, 87, -1, -1, -1, -1, 92, 
+  -1, -1, -1, 12, 13, -1, -1, -1, -1, 80, 
+  -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 
+  29, -1, -1, -1, 33, 34, -1, 36, -1, -1, 
+  -1, 12, 13, -1, 43, -1, -1, -1, 47, -1, 
+  -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, 
+  -1, -1, 33, 34, -1, 36, 65, 66, 67, 68, 
+  -1, 70, 43, -1, -1, -1, 47, -1, -1, -1, 
   -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, 
-  81, 82, 83, 92, -1, -1, 87, -1, -1, -1, 
-  -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 
-  12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 
-  22, -1, -1, -1, -1, -1, -1, 29, -1, -1, 
-  -1, 33, 34, -1, 36, -1, -1, -1, -1, -1, 
-  -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, 
+  -1, -1, -1, 92, 65, 66, 67, 68, -1, 70, 
+  -1, -1, -1, 12, 13, -1, -1, -1, -1, -1, 
+  81, 82, 83, 22, -1, -1, 87, -1, -1, -1, 
+  29, 92, -1, -1, 33, 34, -1, 36, -1, -1, 
+  -1, 12, 13, -1, 43, -1, -1, -1, 47, -1, 
+  -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, 
+  -1, -1, 33, 34, -1, 36, 65, 66, 67, 68, 
+  -1, 70, 43, -1, -1, -1, 47, -1, -1, -1, 
+  -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, 
+  -1, -1, -1, 92, 65, 66, 67, 68, -1, 70, 
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, 
-  82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 
-  92, -1, -1, -1, -1, -1, -1, -1, -1, 10, 
+  81, 82, 83, -1, -1, -1, 87, -1, -1, -1, 
+  -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 
   -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, 
   -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, 
   -1, -1, 33, 34, -1, 36, -1, -1, -1, -1, 
   -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, 
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
   -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, 
-  -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, 
-  81, 82, 83, 84, -1, -1, 87, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  81, 82, 83, -1, -1, -1, 87, -1, -1, -1, 
   -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 
-  10, -1, 12, 13, -1, -1, -1, -1, -1, -1, 
-  -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, 
-  -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, 
-  -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, 
-  -1, -1, -1, -1, -1, 55, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, 
-  70, -1, -1, -1, -1, 75, -1, -1, -1, -1, 
-  -1, 81, 82, 83, 84, -1, -1, 87, -1, -1, 
-  -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 
   -1, 10, -1, 12, 13, -1, -1, -1, -1, -1, 
   -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 
   29, -1, -1, -1, 33, 34, -1, 36, -1, -1, 
   -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, 
-  -1, -1, -1, -1, -1, -1, 55, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
   -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, 
   -1, 70, -1, -1, -1, -1, 75, -1, -1, -1, 
   -1, -1, 81, 82, 83, 84, -1, -1, 87, -1, 
   -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, 
-  -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, 
-  -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 
-  29, -1, -1, -1, 33, 34, -1, 36, -1, -1
-  -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, 
-  -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 65, 66, 67, 68
-  -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, 
-  -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, 
-  -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, 
-  -1, -1, 7, -1, -1, -1, 11, 12, 13, -1, 
+  -1, -1, -1, 10, -1, 12, 13, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, 
+  -1, -1, 29, -1, -1, -1, 33, 34, -1, 36
+  -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, 
+  47, -1, -1, -1, -1, -1, -1, -1, 55, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 65, 66
+  67, 68, -1, 70, -1, -1, -1, -1, 75, -1, 
+  -1, -1, -1, -1, 81, 82, 83, 84, -1, -1, 
+  87, -1, -1, -1, -1, 92, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 10, -1, 12, 13, -1, 
   -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, 
   -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, 
-  -1, 36, -1, -1, -1, 40, -1, 42, 43, 44
-  -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  65, 66, 67, 68, -1, 70, -1, 72, -1, 74
-  -1, 76, -1, -1, -1, -1, 81, 82, 83, -1
+  -1, 36, -1, -1, -1, -1, -1, -1, 43, -1
+  -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, 
+  55, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  65, 66, 67, 68, -1, 70, -1, -1, -1, -1
+  75, -1, -1, -1, -1, -1, 81, 82, 83, 84
   -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 11, 12, 13, -1
-  -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, 
-  -1, -1, -1, -1, 29, -1, -1, -1, 33, 34
-  -1, 36, -1, -1, -1, 40, -1, 42, 43, 44
-  -1, -1, 47, -1, -1, -1, 51, -1, 53, -1
+  -1, -1, -1, -1, -1, -1, -1, 11, 12, 13
+  -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, 
+  -1, -1, -1, -1, -1, 29, -1, -1, -1, 33
+  34, -1, 36, -1, -1, -1, 40, -1, 42, 43
+  44, -1, -1, 47, -1, -1, -1, 51, -1, 53
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  65, 66, 67, 68, -1, 70, -1, 72, -1, 74, 
-  75, 76, -1, -1, -1, -1, 81, 82, 83, -1, 
-  -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 11, 12, 13, -1, 
-  -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, 
-  -1, -1, -1, -1, 29, 30, -1, -1, 33, 34, 
-  -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, 
-  -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, 
-  -1, -1, -1, -1, -1, -1, 61, -1, -1, -1, 
-  65, 66, 67, 68, -1, 70, -1, 72, -1, 74, 
-  -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, 
-  -1, -1, 87, -1, -1, -1, -1, 92, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 8, -1, -1, 11, 
-  12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 
-  22, -1, -1, -1, -1, -1, -1, 29, -1, -1, 
-  -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, 
-  42, 43, 44, -1, -1, 47, -1, -1, -1, 51, 
-  -1, 53, -1, -1, 56, -1, -1, -1, -1, -1, 
-  -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, 
-  72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 
-  82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 
-  92, -1, -1, -1, -1, -1, -1, -1, -1, 11, 
-  12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 
-  22, -1, -1, -1, -1, -1, -1, 29, 30, -1, 
-  -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, 
-  42, 43, 44, -1, -1, 47, -1, -1, -1, 51, 
-  -1, 53, -1, -1, -1, -1, -1, -1, -1, 61, 
-  -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, 
-  72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 
-  82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 
-  92, -1, -1, -1, -1, -1, -1, -1, -1, 8, 
+  -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, 
+  74, -1, 76, -1, -1, -1, -1, 81, 82, 83, 
+  -1, -1, -1, 87, -1, -1, -1, -1, 92, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, 
   -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, 
   -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 
   29, -1, -1, -1, 33, 34, -1, 36, -1, -1, 
   -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, 
-  -1, -1, 51, -1, 53, -1, -1, 56, -1, -1, 
+  -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, 
   -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, 
   -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, 
   -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, 
   -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, 
-  -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, 
-  -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, 
-  -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, 
-  36, -1, -1, -1, 40, -1, 42, 43, 44, -1, 
-  -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, 
-  56, -1, -1, -1, -1, -1, -1, -1, -1, 65, 
-  66, 67, 68, -1, 70, -1, 72, -1, 74, -1, 
-  76, -1, -1, -1, -1, 81, 82, 83, -1, -1, 
-  -1, 87, -1, -1, -1, -1, 92, -1, -1, -1, 
+  -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, 
+  -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, 
+  -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, 
+  -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, 
+  -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, 
+  68, -1, 70, -1, 72, -1, 74, 75, 76, -1, 
+  -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, 
+  -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, 11, 12, 13, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, 
+  -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, 
+  -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, 
+  47, -1, -1, -1, 51, -1, 53, -1, -1, -1, 
+  -1, -1, -1, -1, 61, -1, -1, -1, 65, 66, 
+  67, 68, -1, 70, -1, 72, -1, 74, -1, 76, 
+  -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 
+  87, -1, -1, -1, -1, 92, -1, -1, -1, -1, 
   -1, -1, -1, -1, -1, 8, -1, -1, 11, 12, 
   13, -1, -1, -1, -1, -1, -1, -1, -1, 22, 
   -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, 
@@ -876,45 +844,73 @@ const short QmlJSGrammar::action_check [] = {
   -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, 
   -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, 
   83, -1, -1, -1, 87, -1, -1, -1, -1, 92, 
-  -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 
-  6, -1, -1, 9, 10, 11, -1, -1, 14, -1, 
-  16, -1, -1, -1, 20, 21, 22, -1, -1, -1, 
-  -1, -1, -1, 29, 30, 31, 32, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, 59, -1, -1, -1, -1, -1, -1, 
-  66, 67, 68, 69, 70, 71, -1, 73, 74, 75, 
-  76, 77, 78, -1, -1, 81, 82, 83, 84, 85, 
-  86, -1, -1, -1, -1, -1, 92, -1, -1, -1, 
-  -1, -1, -1, -1, -1, 4, 5, 6, -1, -1, 
-  9, 10, 11, -1, -1, 14, -1, 16, -1, -1, 
-  -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, 
-  29, 30, 31, 32, -1, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  59, -1, -1, -1, -1, -1, 65, 66, 67, -1, 
-  69, 70, 71, -1, 73, 74, 75, 76, 77, 78, 
-  -1, -1, 81, 82, 83, 84, 85, 86, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 
+  12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 
+  22, -1, -1, -1, -1, -1, -1, 29, 30, -1, 
+  -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, 
+  42, 43, 44, -1, -1, 47, -1, -1, -1, 51, 
+  -1, 53, -1, -1, -1, -1, -1, -1, -1, 61, 
+  -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, 
+  72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 
+  82, 83, -1, -1, -1, 87, -1, -1, -1, -1, 
+  92, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  8, -1, -1, 11, 12, 13, -1, -1, -1, -1, 
+  -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, 
+  -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, 
+  -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, 
+  -1, -1, -1, 51, -1, 53, -1, -1, 56, -1, 
+  -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, 
+  68, -1, 70, -1, 72, -1, 74, -1, 76, -1, 
+  -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, 
+  -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, 8, -1, -1, 11, 12, 13, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, 
+  -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, 
+  34, -1, 36, -1, -1, -1, 40, -1, 42, 43, 
+  44, -1, -1, 47, -1, -1, -1, 51, -1, 53, 
+  -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, 
+  -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, 
+  74, -1, 76, -1, -1, -1, -1, 81, 82, 83, 
+  -1, -1, -1, 87, -1, -1, -1, -1, 92, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, 
+  -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, 
+  -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, 
+  -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, 
+  40, -1, 42, 43, 44, -1, -1, 47, -1, -1, 
+  -1, 51, -1, 53, -1, -1, 56, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, 
+  70, -1, 72, -1, 74, -1, 76, -1, -1, -1, 
+  -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, 
+  -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 
   -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, 
   -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, 
   22, -1, -1, -1, -1, -1, -1, 29, 30, 31, 
   32, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-  -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, 
-  -1, -1, -1, 55, -1, -1, -1, 59, -1, -1, 
-  -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, 
+  -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, 
+  -1, -1, -1, -1, 66, 67, 68, 69, 70, 71, 
   -1, 73, 74, 75, 76, 77, 78, -1, -1, 81, 
   82, 83, 84, 85, 86, -1, -1, -1, -1, -1, 
-  -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 
-  -1, -1, -1, -1, 9, -1, 11, 12, 13, 14, 
-  -1, -1, -1, -1, -1, -1, 21, 22, -1, -1, 
-  -1, -1, -1, -1, 29, 30, -1, -1, 33, 34, 
-  -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, 
-  -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, 
-  -1, -1, -1, -1, 59, -1, 61, -1, -1, -1, 
-  65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 
-  75, 76, 77, 78, -1, -1, 81, 82, 83, 84, 
-  85, -1, 87, -1, -1, -1, -1, 92, -1, -1, 
+  92, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+  4, 5, 6, -1, -1, 9, 10, 11, -1, -1, 
+  14, -1, 16, -1, -1, -1, 20, 21, 22, -1, 
+  -1, -1, -1, -1, -1, 29, 30, 31, 32, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, 
+  -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, 59, -1, -1, -1, -1, 
+  -1, 65, 66, 67, -1, 69, 70, 71, -1, 73, 
+  74, 75, 76, 77, 78, -1, -1, 81, 82, 83, 
+  84, 85, 86, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 
+  6, -1, -1, 9, 10, 11, -1, -1, 14, -1, 
+  16, -1, -1, -1, 20, 21, 22, -1, -1, -1, 
+  -1, -1, -1, 29, 30, 31, 32, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, 
+  -1, 47, -1, -1, -1, -1, -1, -1, -1, 55, 
+  -1, -1, -1, 59, -1, -1, -1, -1, -1, 65, 
+  66, 67, -1, 69, 70, 71, -1, 73, 74, 75, 
+  76, 77, 78, -1, -1, 81, 82, 83, 84, 85, 
+  86, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
   -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, 
   -1, 9, -1, 11, 12, 13, 14, -1, -1, -1, 
   -1, -1, -1, 21, 22, -1, -1, -1, -1, -1, 
@@ -925,16 +921,26 @@ const short QmlJSGrammar::action_check [] = {
   68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 
   78, -1, -1, 81, 82, 83, 84, 85, -1, 87, 
   -1, -1, -1, -1, 92, -1, -1, -1, -1, -1, 
-  -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, 
-  11, 12, 13, 14, -1, 16, -1, -1, -1, 20, 
-  21, 22, -1, -1, -1, -1, -1, -1, 29, 30, 
-  31, 32, 33, 34, -1, 36, -1, -1, -1, 40, 
-  -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, 
-  51, -1, 53, -1, -1, -1, -1, -1, 59, -1, 
-  61, -1, -1, -1, 65, 66, 67, 68, 69, 70, 
-  71, 72, 73, 74, 75, 76, 77, 78, -1, -1, 
-  81, 82, 83, 84, 85, 86, 87, -1, -1, -1, 
-  -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, 4, -1, -1, -1, -1, 9, 
+  -1, 11, 12, 13, 14, -1, -1, -1, -1, -1, 
+  -1, 21, 22, -1, -1, -1, -1, -1, -1, 29, 
+  30, -1, -1, 33, 34, -1, 36, -1, -1, -1, 
+  40, -1, 42, 43, 44, -1, -1, 47, -1, -1, 
+  -1, 51, -1, 53, -1, -1, -1, -1, -1, 59, 
+  -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, 
+  70, 71, 72, 73, 74, 75, 76, 77, 78, -1, 
+  -1, 81, 82, 83, 84, 85, -1, 87, -1, -1, 
+  -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, 
+  12, 13, 14, -1, 16, -1, -1, -1, 20, 21, 
+  22, -1, -1, -1, -1, -1, -1, 29, 30, 31, 
+  32, 33, 34, -1, 36, -1, -1, -1, 40, -1, 
+  42, 43, 44, -1, -1, 47, -1, -1, -1, 51, 
+  -1, 53, -1, -1, -1, -1, -1, 59, -1, 61, 
+  -1, -1, -1, 65, 66, 67, 68, 69, 70, 71, 
+  72, 73, 74, 75, 76, 77, 78, -1, -1, 81, 
+  82, 83, 84, 85, 86, 87, -1, -1, -1, -1, 
+  92, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
   4, 5, 6, -1, -1, 9, 10, 11, 12, 13, 
   14, -1, 16, -1, -1, -1, 20, 21, 22, -1, 
   -1, -1, -1, -1, -1, 29, 30, 31, 32, 33, 
@@ -944,7 +950,7 @@ const short QmlJSGrammar::action_check [] = {
   -1, 65, 66, 67, 68, 69, 70, 71, 72, 73, 
   74, 75, 76, 77, 78, -1, -1, 81, 82, 83, 
   84, 85, 86, 87, -1, -1, -1, -1, 92, -1, 
-  -1, -1, -1, -1, -1, -1, -1, 
+  -1, -1, -1, -1, -1, -1, -1, -1, 
 
   26, 36, 15, 15, 15, 15, 26, 26, 3, 15, 
   15, 26, 2, 15, 3, 19, 2, 15, 2, 2, 
index 7e55a38..cd0d5e1 100644 (file)
@@ -54,8 +54,8 @@ class QmlJSGrammar
 public:
   enum VariousConstants {
     EOF_SYMBOL = 0,
-    REDUCE_HERE = 100,
-    SHIFT_THERE = 99,
+    REDUCE_HERE = 101,
+    SHIFT_THERE = 100,
     T_AND = 1,
     T_AND_AND = 2,
     T_AND_EQ = 3,
@@ -80,13 +80,14 @@ public:
     T_EQ = 17,
     T_EQ_EQ = 18,
     T_EQ_EQ_EQ = 19,
+    T_ERROR = 93,
     T_FALSE = 83,
-    T_FEED_JS_EXPRESSION = 96,
-    T_FEED_JS_PROGRAM = 98,
-    T_FEED_JS_SOURCE_ELEMENT = 97,
-    T_FEED_JS_STATEMENT = 95,
-    T_FEED_UI_OBJECT_MEMBER = 94,
-    T_FEED_UI_PROGRAM = 93,
+    T_FEED_JS_EXPRESSION = 97,
+    T_FEED_JS_PROGRAM = 99,
+    T_FEED_JS_SOURCE_ELEMENT = 98,
+    T_FEED_JS_STATEMENT = 96,
+    T_FEED_UI_OBJECT_MEMBER = 95,
+    T_FEED_UI_PROGRAM = 94,
     T_FINALLY = 20,
     T_FOR = 21,
     T_FUNCTION = 22,
@@ -158,12 +159,12 @@ public:
     ACCEPT_STATE = 640,
     RULE_COUNT = 345,
     STATE_COUNT = 641,
-    TERMINAL_COUNT = 101,
+    TERMINAL_COUNT = 102,
     NON_TERMINAL_COUNT = 107,
 
     GOTO_INDEX_OFFSET = 641,
-    GOTO_INFO_OFFSET = 2787,
-    GOTO_CHECK_OFFSET = 2787
+    GOTO_INFO_OFFSET = 2818,
+    GOTO_CHECK_OFFSET = 2818
   };
 
   static const char  *const    spell [];
diff --git a/src/libs/qmljs/parser/qmljskeywords_p.h b/src/libs/qmljs/parser/qmljskeywords_p.h
new file mode 100644 (file)
index 0000000..b86efc5
--- /dev/null
@@ -0,0 +1,851 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLJSKEYWORDS_P_H
+#define QMLJSKEYWORDS_P_H
+
+//
+//  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.
+//
+
+static inline int classify2(const QChar *s, bool qmlMode) {
+  if (s[0].unicode() == 'a') {
+    if (s[1].unicode() == 's') {
+      return qmlMode ? Lexer::T_AS : Lexer::T_RESERVED_WORD;
+    }
+  }
+  else if (s[0].unicode() == 'd') {
+    if (s[1].unicode() == 'o') {
+      return Lexer::T_DO;
+    }
+  }
+  else if (s[0].unicode() == 'i') {
+    if (s[1].unicode() == 'f') {
+      return Lexer::T_IF;
+    }
+    else if (s[1].unicode() == 'n') {
+      return Lexer::T_IN;
+    }
+  }
+  else if (qmlMode && s[0].unicode() == 'o') {
+    if (s[1].unicode() == 'n') {
+      return Lexer::T_ON;
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify3(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'f') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'r') {
+        return Lexer::T_FOR;
+      }
+    }
+  }
+  else if (s[0].unicode() == 'i') {
+    if (s[1].unicode() == 'n') {
+      if (s[2].unicode() == 't') {
+        return Lexer::T_INT;
+      }
+    }
+  }
+  else if (s[0].unicode() == 'n') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 'w') {
+        return Lexer::T_NEW;
+      }
+    }
+  }
+  else if (s[0].unicode() == 't') {
+    if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'y') {
+        return Lexer::T_TRY;
+      }
+    }
+  }
+  else if (s[0].unicode() == 'v') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 'r') {
+        return Lexer::T_VAR;
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify4(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'b') {
+    if (s[1].unicode() == 'y') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'e') {
+          return Lexer::T_BYTE;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'c') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 's') {
+        if (s[3].unicode() == 'e') {
+          return Lexer::T_CASE;
+        }
+      }
+    }
+    else if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'a') {
+        if (s[3].unicode() == 'r') {
+          return Lexer::T_CHAR;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'e') {
+    if (s[1].unicode() == 'l') {
+      if (s[2].unicode() == 's') {
+        if (s[3].unicode() == 'e') {
+          return Lexer::T_ELSE;
+        }
+      }
+    }
+    else if (s[1].unicode() == 'n') {
+      if (s[2].unicode() == 'u') {
+        if (s[3].unicode() == 'm') {
+          return Lexer::T_ENUM;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'g') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'o') {
+          return Lexer::T_GOTO;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'l') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 'g') {
+          return Lexer::T_LONG;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'n') {
+    if (s[1].unicode() == 'u') {
+      if (s[2].unicode() == 'l') {
+        if (s[3].unicode() == 'l') {
+          return Lexer::T_NULL;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 't') {
+    if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'i') {
+        if (s[3].unicode() == 's') {
+          return Lexer::T_THIS;
+        }
+      }
+    }
+    else if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'u') {
+        if (s[3].unicode() == 'e') {
+          return Lexer::T_TRUE;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'v') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'i') {
+        if (s[3].unicode() == 'd') {
+          return Lexer::T_VOID;
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'w') {
+    if (s[1].unicode() == 'i') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'h') {
+          return Lexer::T_WITH;
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify5(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'b') {
+    if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'e') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 'k') {
+            return Lexer::T_BREAK;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'c') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'c') {
+          if (s[4].unicode() == 'h') {
+            return Lexer::T_CATCH;
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'l') {
+      if (s[2].unicode() == 'a') {
+        if (s[3].unicode() == 's') {
+          if (s[4].unicode() == 's') {
+            return Lexer::T_CLASS;
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 's') {
+          if (s[4].unicode() == 't') {
+            return Lexer::T_CONST;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'f') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 'l') {
+        if (s[3].unicode() == 's') {
+          if (s[4].unicode() == 'e') {
+            return Lexer::T_FALSE;
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'i') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 'l') {
+            return Lexer::T_FINAL;
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'l') {
+      if (s[2].unicode() == 'o') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 't') {
+            return Lexer::T_FLOAT;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 's') {
+    if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'o') {
+        if (s[3].unicode() == 'r') {
+          if (s[4].unicode() == 't') {
+            return Lexer::T_SHORT;
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'u') {
+      if (s[2].unicode() == 'p') {
+        if (s[3].unicode() == 'e') {
+          if (s[4].unicode() == 'r') {
+            return Lexer::T_SUPER;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 't') {
+    if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'r') {
+        if (s[3].unicode() == 'o') {
+          if (s[4].unicode() == 'w') {
+            return Lexer::T_THROW;
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'w') {
+    if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'i') {
+        if (s[3].unicode() == 'l') {
+          if (s[4].unicode() == 'e') {
+            return Lexer::T_WHILE;
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify6(const QChar *s, bool qmlMode) {
+  if (s[0].unicode() == 'd') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 'l') {
+        if (s[3].unicode() == 'e') {
+          if (s[4].unicode() == 't') {
+            if (s[5].unicode() == 'e') {
+              return Lexer::T_DELETE;
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'u') {
+        if (s[3].unicode() == 'b') {
+          if (s[4].unicode() == 'l') {
+            if (s[5].unicode() == 'e') {
+              return Lexer::T_DOUBLE;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'e') {
+    if (s[1].unicode() == 'x') {
+      if (s[2].unicode() == 'p') {
+        if (s[3].unicode() == 'o') {
+          if (s[4].unicode() == 'r') {
+            if (s[5].unicode() == 't') {
+              return Lexer::T_EXPORT;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'i') {
+    if (s[1].unicode() == 'm') {
+      if (s[2].unicode() == 'p') {
+        if (s[3].unicode() == 'o') {
+          if (s[4].unicode() == 'r') {
+            if (s[5].unicode() == 't') {
+              return qmlMode ? Lexer::T_IMPORT : Lexer::T_RESERVED_WORD;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'n') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'i') {
+          if (s[4].unicode() == 'v') {
+            if (s[5].unicode() == 'e') {
+              return Lexer::T_NATIVE;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'p') {
+    if (s[1].unicode() == 'u') {
+      if (s[2].unicode() == 'b') {
+        if (s[3].unicode() == 'l') {
+          if (s[4].unicode() == 'i') {
+            if (s[5].unicode() == 'c') {
+              return qmlMode ? Lexer::T_PUBLIC : Lexer::T_RESERVED_WORD;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'r') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'u') {
+          if (s[4].unicode() == 'r') {
+            if (s[5].unicode() == 'n') {
+              return Lexer::T_RETURN;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 's') {
+    if (qmlMode && s[1].unicode() == 'i') {
+      if (s[2].unicode() == 'g') {
+        if (s[3].unicode() == 'n') {
+          if (s[4].unicode() == 'a') {
+            if (s[5].unicode() == 'l') {
+              return Lexer::T_SIGNAL;
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 't') {
+      if (s[2].unicode() == 'a') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'i') {
+            if (s[5].unicode() == 'c') {
+              return Lexer::T_STATIC;
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'w') {
+      if (s[2].unicode() == 'i') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'c') {
+            if (s[5].unicode() == 'h') {
+              return Lexer::T_SWITCH;
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 't') {
+    if (s[1].unicode() == 'h') {
+      if (s[2].unicode() == 'r') {
+        if (s[3].unicode() == 'o') {
+          if (s[4].unicode() == 'w') {
+            if (s[5].unicode() == 's') {
+              return Lexer::T_THROWS;
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'y') {
+      if (s[2].unicode() == 'p') {
+        if (s[3].unicode() == 'e') {
+          if (s[4].unicode() == 'o') {
+            if (s[5].unicode() == 'f') {
+              return Lexer::T_TYPEOF;
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify7(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'b') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'o') {
+        if (s[3].unicode() == 'l') {
+          if (s[4].unicode() == 'e') {
+            if (s[5].unicode() == 'a') {
+              if (s[6].unicode() == 'n') {
+                return Lexer::T_BOOLEAN;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'd') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 'f') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 'u') {
+            if (s[5].unicode() == 'l') {
+              if (s[6].unicode() == 't') {
+                return Lexer::T_DEFAULT;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'e') {
+    if (s[1].unicode() == 'x') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'e') {
+          if (s[4].unicode() == 'n') {
+            if (s[5].unicode() == 'd') {
+              if (s[6].unicode() == 's') {
+                return Lexer::T_EXTENDS;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'f') {
+    if (s[1].unicode() == 'i') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 'l') {
+            if (s[5].unicode() == 'l') {
+              if (s[6].unicode() == 'y') {
+                return Lexer::T_FINALLY;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'p') {
+    if (s[1].unicode() == 'a') {
+      if (s[2].unicode() == 'c') {
+        if (s[3].unicode() == 'k') {
+          if (s[4].unicode() == 'a') {
+            if (s[5].unicode() == 'g') {
+              if (s[6].unicode() == 'e') {
+                return Lexer::T_PACKAGE;
+              }
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'i') {
+        if (s[3].unicode() == 'v') {
+          if (s[4].unicode() == 'a') {
+            if (s[5].unicode() == 't') {
+              if (s[6].unicode() == 'e') {
+                return Lexer::T_PRIVATE;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify8(const QChar *s, bool qmlMode) {
+  if (s[0].unicode() == 'a') {
+    if (s[1].unicode() == 'b') {
+      if (s[2].unicode() == 's') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'r') {
+            if (s[5].unicode() == 'a') {
+              if (s[6].unicode() == 'c') {
+                if (s[7].unicode() == 't') {
+                  return Lexer::T_ABSTRACT;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'c') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'i') {
+            if (s[5].unicode() == 'n') {
+              if (s[6].unicode() == 'u') {
+                if (s[7].unicode() == 'e') {
+                  return Lexer::T_CONTINUE;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'd') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 'b') {
+        if (s[3].unicode() == 'u') {
+          if (s[4].unicode() == 'g') {
+            if (s[5].unicode() == 'g') {
+              if (s[6].unicode() == 'e') {
+                if (s[7].unicode() == 'r') {
+                  return Lexer::T_DEBUGGER;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'f') {
+    if (s[1].unicode() == 'u') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 'c') {
+          if (s[4].unicode() == 't') {
+            if (s[5].unicode() == 'i') {
+              if (s[6].unicode() == 'o') {
+                if (s[7].unicode() == 'n') {
+                  return Lexer::T_FUNCTION;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (qmlMode && s[0].unicode() == 'p') {
+    if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'o') {
+        if (s[3].unicode() == 'p') {
+          if (s[4].unicode() == 'e') {
+            if (s[5].unicode() == 'r') {
+              if (s[6].unicode() == 't') {
+                if (s[7].unicode() == 'y') {
+                  return Lexer::T_PROPERTY;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (qmlMode && s[0].unicode() == 'r') {
+    if (s[1].unicode() == 'e') {
+      if (s[2].unicode() == 'a') {
+        if (s[3].unicode() == 'd') {
+          if (s[4].unicode() == 'o') {
+            if (s[5].unicode() == 'n') {
+              if (s[6].unicode() == 'l') {
+                if (s[7].unicode() == 'y') {
+                  return Lexer::T_READONLY;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'v') {
+    if (s[1].unicode() == 'o') {
+      if (s[2].unicode() == 'l') {
+        if (s[3].unicode() == 'a') {
+          if (s[4].unicode() == 't') {
+            if (s[5].unicode() == 'i') {
+              if (s[6].unicode() == 'l') {
+                if (s[7].unicode() == 'e') {
+                  return Lexer::T_VOLATILE;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify9(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'i') {
+    if (s[1].unicode() == 'n') {
+      if (s[2].unicode() == 't') {
+        if (s[3].unicode() == 'e') {
+          if (s[4].unicode() == 'r') {
+            if (s[5].unicode() == 'f') {
+              if (s[6].unicode() == 'a') {
+                if (s[7].unicode() == 'c') {
+                  if (s[8].unicode() == 'e') {
+                    return Lexer::T_INTERFACE;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 'p') {
+    if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'o') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'e') {
+            if (s[5].unicode() == 'c') {
+              if (s[6].unicode() == 't') {
+                if (s[7].unicode() == 'e') {
+                  if (s[8].unicode() == 'd') {
+                    return Lexer::T_PROTECTED;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  else if (s[0].unicode() == 't') {
+    if (s[1].unicode() == 'r') {
+      if (s[2].unicode() == 'a') {
+        if (s[3].unicode() == 'n') {
+          if (s[4].unicode() == 's') {
+            if (s[5].unicode() == 'i') {
+              if (s[6].unicode() == 'e') {
+                if (s[7].unicode() == 'n') {
+                  if (s[8].unicode() == 't') {
+                    return Lexer::T_TRANSIENT;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify10(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 'i') {
+    if (s[1].unicode() == 'm') {
+      if (s[2].unicode() == 'p') {
+        if (s[3].unicode() == 'l') {
+          if (s[4].unicode() == 'e') {
+            if (s[5].unicode() == 'm') {
+              if (s[6].unicode() == 'e') {
+                if (s[7].unicode() == 'n') {
+                  if (s[8].unicode() == 't') {
+                    if (s[9].unicode() == 's') {
+                      return Lexer::T_IMPLEMENTS;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    else if (s[1].unicode() == 'n') {
+      if (s[2].unicode() == 's') {
+        if (s[3].unicode() == 't') {
+          if (s[4].unicode() == 'a') {
+            if (s[5].unicode() == 'n') {
+              if (s[6].unicode() == 'c') {
+                if (s[7].unicode() == 'e') {
+                  if (s[8].unicode() == 'o') {
+                    if (s[9].unicode() == 'f') {
+                      return Lexer::T_INSTANCEOF;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+static inline int classify12(const QChar *s, bool /*qmlMode*/) {
+  if (s[0].unicode() == 's') {
+    if (s[1].unicode() == 'y') {
+      if (s[2].unicode() == 'n') {
+        if (s[3].unicode() == 'c') {
+          if (s[4].unicode() == 'h') {
+            if (s[5].unicode() == 'r') {
+              if (s[6].unicode() == 'o') {
+                if (s[7].unicode() == 'n') {
+                  if (s[8].unicode() == 'i') {
+                    if (s[9].unicode() == 'z') {
+                      if (s[10].unicode() == 'e') {
+                        if (s[11].unicode() == 'd') {
+                          return Lexer::T_SYNCHRONIZED;
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return Lexer::T_IDENTIFIER;
+}
+
+int Lexer::classify(const QChar *s, int n, bool qmlMode) {
+  switch (n) {
+    case 2: return classify2(s, qmlMode);
+    case 3: return classify3(s, qmlMode);
+    case 4: return classify4(s, qmlMode);
+    case 5: return classify5(s, qmlMode);
+    case 6: return classify6(s, qmlMode);
+    case 7: return classify7(s, qmlMode);
+    case 8: return classify8(s, qmlMode);
+    case 9: return classify9(s, qmlMode);
+    case 10: return classify10(s, qmlMode);
+    case 12: return classify12(s, qmlMode);
+    default: return Lexer::T_IDENTIFIER;
+  } // switch
+}
+
+#endif // QMLJSKEYWORDS_P_H
index 296de77..8bbc0f0 100644 (file)
 **
 **************************************************************************/
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "qmljslexer_p.h"
-
-#include "qmljsglobal_p.h"
 #include "qmljsengine_p.h"
-#include "qmljsgrammar_p.h"
-
-#include <QtCore/qcoreapplication.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include "qmljsmemorypool_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QDebug>
+
+#ifndef QMLJS_NO_FTW
+#include <qmlutils_p.h>
+#else
+namespace QmlUtils {
+inline bool isUpper(const QChar &qc){ return qc.isUpper(); }
+inline bool isLower(const QChar &qc) { return qc.isLower(); }
+inline bool isLetter(const QChar &qc) { return qc.isLetter(); }
+inline bool isDigit(const QChar &qc) { return qc.isDigit(); }
+inline bool isLetterOrNumber(const QChar &qc) { return qc.isLetterOrNumber(); }
+inline bool isSpace(const QChar &qc) { return qc.isSpace(); }
+} // namespace QmlUtils
+#endif
 
 QT_BEGIN_NAMESPACE
 Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
 QT_END_NAMESPACE
 
-QT_QML_BEGIN_NAMESPACE
+using namespace QmlJS;
 
-#define shiftWindowsLineBreak() \
-    do { \
-        if (((current == '\r') && (next1 == '\n')) \
-            || ((current == '\n') && (next1 == '\r'))) { \
-            shift(1); \
-        } \
-    } \
-    while (0)
+enum RegExpFlag {
+    Global     = 0x01,
+    IgnoreCase = 0x02,
+    Multiline  = 0x04
+};
 
-namespace QmlJS {
-extern double integerFromString(const char *buf, int size, int radix);
+static int flagFromChar(const QChar &ch)
+{
+    switch (ch.unicode()) {
+    case 'g': return Global;
+    case 'i': return IgnoreCase;
+    case 'm': return Multiline;
+    }
+    return 0;
 }
 
-using namespace QmlJS;
+static unsigned char convertHex(ushort c)
+{
+    if (c >= '0' && c <= '9')
+        return (c - '0');
+    else if (c >= 'a' && c <= 'f')
+        return (c - 'a' + 10);
+    else
+        return (c - 'A' + 10);
+}
 
-Lexer::Lexer(Engine *eng, bool tokenizeComments)
-    : driver(eng),
-      yylineno(0),
-      done(false),
-      size8(128), size16(128),
-      pos8(0), pos16(0),
-      terminator(false),
-      restrKeyword(false),
-      delimited(false),
-      stackToken(-1),
-      state(Start),
-      pos(0),
-      code(0), length(0),
-      yycolumn(0),
-      startpos(0),
-      startlineno(0), startcolumn(0),
-      bol(true),
-      current(0), next1(0), next2(0), next3(0),
-      err(NoError),
-      wantRx(false),
-      check_reserved(true),
-      parenthesesState(IgnoreParentheses),
-      parenthesesCount(0),
-      prohibitAutomaticSemicolon(false),
-      tokenizeComments(tokenizeComments)
+static QChar convertHex(QChar c1, QChar c2)
 {
-    if (driver) driver->setLexer(this);
-    // allocate space for read buffers
-    buffer8 = new char[size8];
-    buffer16 = new QChar[size16];
-    pattern = 0;
-    flags = 0;
+    return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
+}
 
+static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
+{
+    return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
+                 (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
 }
 
-Lexer::~Lexer()
+Lexer::Lexer(Engine *engine)
+    : _engine(engine)
+    , _codePtr(0)
+    , _lastLinePtr(0)
+    , _tokenLinePtr(0)
+    , _tokenStartPtr(0)
+    , _char(QLatin1Char('\n'))
+    , _errorCode(NoError)
+    , _currentLineNumber(0)
+    , _tokenValue(0)
+    , _parenthesesState(IgnoreParentheses)
+    , _parenthesesCount(0)
+    , _stackToken(-1)
+    , _patternFlags(0)
+    , _tokenKind(0)
+    , _tokenLength(0)
+    , _tokenLine(0)
+    , _validTokenText(false)
+    , _prohibitAutomaticSemicolon(false)
+    , _restrictedKeyword(false)
+    , _terminator(false)
+    , _delimited(false)
+    , _qmlMode(true)
 {
-    delete [] buffer8;
-    delete [] buffer16;
+    if (engine)
+        engine->setLexer(this);
 }
 
-void Lexer::setCode(const QString &c, int lineno)
+QString Lexer::code() const
 {
-    errmsg.clear();
-    yylineno = lineno;
-    yycolumn = 1;
-    restrKeyword = false;
-    delimited = false;
-    stackToken = -1;
-    pos = 0;
-    code = c.unicode();
-    length = c.length();
-    bol = true;
-
-    // read first characters
-    current = (length > 0) ? code[0].unicode() : 0;
-    next1 = (length > 1) ? code[1].unicode() : 0;
-    next2 = (length > 2) ? code[2].unicode() : 0;
-    next3 = (length > 3) ? code[3].unicode() : 0;
+    return _code;
 }
 
-void Lexer::shift(uint p)
+void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
 {
-    while (p--) {
-        ++pos;
-        ++yycolumn;
-        current = next1;
-        next1 = next2;
-        next2 = next3;
-        next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
-    }
+    if (_engine)
+        _engine->setCode(code);
+
+    _qmlMode = qmlMode;
+    _code = code;
+    _tokenText.clear();
+    _tokenText.reserve(1024);
+    _errorMessage.clear();
+    _tokenSpell = QStringRef();
+
+    _codePtr = code.unicode();
+    _lastLinePtr = _codePtr;
+    _tokenLinePtr = _codePtr;
+    _tokenStartPtr = _codePtr;
+
+    _char = QLatin1Char('\n');
+    _errorCode = NoError;
+
+    _currentLineNumber = lineno;
+    _tokenValue = 0;
+
+    // parentheses state
+    _parenthesesState = IgnoreParentheses;
+    _parenthesesCount = 0;
+
+    _stackToken = -1;
+
+    _patternFlags = 0;
+    _tokenLength = 0;
+    _tokenLine = lineno;
+
+    _validTokenText = false;
+    _prohibitAutomaticSemicolon = false;
+    _restrictedKeyword = false;
+    _terminator = false;
+    _delimited = false;
 }
 
-void Lexer::setDone(State s)
+void Lexer::scanChar()
 {
-    state = s;
-    done = true;
+    _char = *_codePtr++;
+
+    if (_char == QLatin1Char('\n')) {
+        _lastLinePtr = _codePtr; // points to the first character after the newline
+        ++_currentLineNumber;
+    }
 }
 
-int Lexer::findReservedWord(const QChar *c, int size) const
+int Lexer::lex()
 {
-    switch (size) {
-    case 2: {
-        if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
-            return QmlJSGrammar::T_DO;
-        else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
-            return QmlJSGrammar::T_IF;
-        else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
-            return QmlJSGrammar::T_IN;
-        else if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('s'))
-            return QmlJSGrammar::T_AS;
-        else if (c[0] == QLatin1Char('o') && c[1] == QLatin1Char('n'))
-            return QmlJSGrammar::T_ON;
-    }   break;
-
-    case 3: {
-        if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
-            return QmlJSGrammar::T_FOR;
-        else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
-            return QmlJSGrammar::T_NEW;
-        else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
-            return QmlJSGrammar::T_TRY;
-        else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
-            return QmlJSGrammar::T_VAR;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 4: {
-        if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
-                && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
-            return QmlJSGrammar::T_CASE;
-        else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
-                && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
-            return QmlJSGrammar::T_ELSE;
-        else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
-                && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
-            return QmlJSGrammar::T_THIS;
-        else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
-                && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
-            return QmlJSGrammar::T_VOID;
-        else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
-                && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
-            return QmlJSGrammar::T_WITH;
-        else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
-                && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
-            return QmlJSGrammar::T_TRUE;
-        else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
-                && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
-            return QmlJSGrammar::T_NULL;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
-                    && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
-                    && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
-                    && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
-                    && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
-                    && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 5: {
-        if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
-                && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
-                && c[4] == QLatin1Char('k'))
-            return QmlJSGrammar::T_BREAK;
-        else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
-                && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
-                && c[4] == QLatin1Char('h'))
-            return QmlJSGrammar::T_CATCH;
-        else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
-                && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
-                && c[4] == QLatin1Char('w'))
-            return QmlJSGrammar::T_THROW;
-        else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
-                && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
-                && c[4] == QLatin1Char('e'))
-            return QmlJSGrammar::T_WHILE;
-        else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
-                && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
-                && c[4] == QLatin1Char('t'))
-            return QmlJSGrammar::T_CONST;
-        else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
-                && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
-                && c[4] == QLatin1Char('e'))
-            return QmlJSGrammar::T_FALSE;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
-                    && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
-                    && c[4] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
-                    && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
-                    && c[4] == QLatin1Char('r'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
-                    && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
-                    && c[4] == QLatin1Char('l'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
-                    && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
-                    && c[4] == QLatin1Char('s'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
-                    && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
-                    && c[4] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 6: {
-        if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
-                && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
-                && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
-            return QmlJSGrammar::T_DELETE;
-        else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
-                && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
-                && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
-            return QmlJSGrammar::T_RETURN;
-        else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
-                && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
-                && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
-            return QmlJSGrammar::T_SWITCH;
-        else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
-                && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
-                && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
-            return QmlJSGrammar::T_TYPEOF;
-        else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
-            && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
-            && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
-            return QmlJSGrammar::T_IMPORT;
-        else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('i')
-            && c[2] == QLatin1Char('g') && c[3] == QLatin1Char('n')
-            && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('l'))
-            return QmlJSGrammar::T_SIGNAL;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
-                    && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
-                    && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
-                    && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
-                    && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
-                    && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
-                    && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
-                    && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
-                    && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
-                    && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
-                    && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
-                return QmlJSGrammar::T_PUBLIC;
-            else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
-                    && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
-                    && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
-                    && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
-                    && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 7: {
-        if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
-                && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
-                && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
-                && c[6] == QLatin1Char('t'))
-            return QmlJSGrammar::T_DEFAULT;
-        else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
-                && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
-                && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
-                && c[6] == QLatin1Char('y'))
-            return QmlJSGrammar::T_FINALLY;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
-                    && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
-                    && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
-                    && c[6] == QLatin1Char('n'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
-                    && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
-                    && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
-                    && c[6] == QLatin1Char('s'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
-                    && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
-                    && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
-                    && c[6] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
-                    && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
-                    && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
-                    && c[6] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 8: {
-        if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
-                && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
-                && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
-                && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
-            return QmlJSGrammar::T_CONTINUE;
-        else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
-                && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
-                && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
-                && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
-            return QmlJSGrammar::T_FUNCTION;
-        else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
-                && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
-                && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
-                && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
-            return QmlJSGrammar::T_DEBUGGER;
-        else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
-                && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('p')
-                && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('r')
-                && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('y'))
-            return QmlJSGrammar::T_PROPERTY;
-        else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
-                && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('d')
-                && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('n')
-                && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('y'))
-            return QmlJSGrammar::T_READONLY;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
-                    && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
-                    && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
-                    && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
-                    && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
-                    && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
-                    && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 9: {
-        if (check_reserved) {
-            if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
-                    && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
-                    && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
-                    && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
-                    && c[8] == QLatin1Char('e'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
-                    && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
-                    && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
-                    && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
-                    && c[8] == QLatin1Char('t'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-            else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
-                    && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
-                    && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
-                    && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
-                    && c[8] == QLatin1Char('d'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 10: {
-        if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
-                && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
-                && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
-                && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
-                && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
-            return QmlJSGrammar::T_INSTANCEOF;
-        else if (check_reserved) {
-            if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
-                    && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
-                    && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
-                    && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
-                    && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
-                return QmlJSGrammar::T_RESERVED_WORD;
-        }
-    }   break;
-
-    case 12: {
-        if (check_reserved) {
-            if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y')
-                    && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
-                    && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r')
-                    && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
-                    && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
-                    && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
-                return QmlJSGrammar::T_RESERVED_WORD;
+    _tokenSpell = QStringRef();
+    _tokenKind = scanToken();
+    _tokenLength = _codePtr - _tokenStartPtr - 1;
+
+    _delimited = false;
+    _restrictedKeyword = false;
+
+    // update the flags
+    switch (_tokenKind) {
+    case T_LBRACE:
+    case T_SEMICOLON:
+        _delimited = true;
+        break;
+
+    case T_IF:
+    case T_FOR:
+    case T_WHILE:
+    case T_WITH:
+        _parenthesesState = CountParentheses;
+        _parenthesesCount = 0;
+        break;
+
+    case T_DO:
+        _parenthesesState = BalancedParentheses;
+        break;
+
+    case T_CONTINUE:
+    case T_BREAK:
+    case T_RETURN:
+    case T_THROW:
+        _restrictedKeyword = true;
+        break;
+    } // switch
+
+    // update the parentheses state
+    switch (_parenthesesState) {
+    case IgnoreParentheses:
+        break;
+
+    case CountParentheses:
+        if (_tokenKind == T_RPAREN) {
+            --_parenthesesCount;
+            if (_parenthesesCount == 0)
+                _parenthesesState = BalancedParentheses;
+        } else if (_tokenKind == T_LPAREN) {
+            ++_parenthesesCount;
         }
-    }   break;
+        break;
 
+    case BalancedParentheses:
+        _parenthesesState = IgnoreParentheses;
+        break;
     } // switch
 
-    return -1;
+    return _tokenKind;
 }
 
-int Lexer::lex()
+bool Lexer::isUnicodeEscapeSequence(const QChar *chars)
+{
+    if (isHexDigit(chars[0]) && isHexDigit(chars[1]) && isHexDigit(chars[2]) && isHexDigit(chars[3]))
+        return true;
+
+    return false;
+}
+
+QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
 {
-    int token = 0;
-    state = Start;
-    ushort stringType = 0; // either single or double quotes
-    bool multiLineString = false;
-    pos8 = pos16 = 0;
-    done = false;
-    terminator = false;
-
-    // did we push a token on the stack previously ?
-    // (after an automatic semicolon insertion)
-    if (stackToken >= 0) {
-        setDone(Other);
-        token = stackToken;
-        stackToken = -1;
+    if (_char == QLatin1Char('u') && isUnicodeEscapeSequence(&_codePtr[0])) {
+        scanChar(); // skip u
+
+        const QChar c1 = _char;
+        scanChar();
+
+        const QChar c2 = _char;
+        scanChar();
+
+        const QChar c3 = _char;
+        scanChar();
+
+        const QChar c4 = _char;
+        scanChar();
+
+        if (ok)
+            *ok = true;
+
+        return convertUnicode(c1, c2, c3, c4);
     }
 
-    bool identifierWithEscapedUnicode = false;
-
-    while (!done) {
-        switch (state) {
-        case Start:
-            if (isWhiteSpace()) {
-                // do nothing
-            } else if (current == '/' && next1 == '/') {
-                recordStartPos();
-                shift(1);
-                state = InSingleLineComment;
-            } else if (current == '/' && next1 == '*') {
-                recordStartPos();
-                shift(1);
-                state = InMultiLineComment;
-            } else if (current == 0) {
-                syncProhibitAutomaticSemicolon();
-                if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
-                    // automatic semicolon insertion if program incomplete
-                    token = QmlJSGrammar::T_SEMICOLON;
-                    stackToken = 0;
-                    setDone(Other);
-                } else {
-                    setDone(Eof);
-                }
-            } else if (isLineTerminator()) {
-                if (restrKeyword) {
-                    // automatic semicolon insertion
-                    recordStartPos();
-                    token = QmlJSGrammar::T_SEMICOLON;
-                    setDone(Other);
-                } else {
-                    shiftWindowsLineBreak();
-                    yylineno++;
-                    yycolumn = 0;
-                    bol = true;
-                    terminator = true;
-                    syncProhibitAutomaticSemicolon();
-                }
-            } else if (current == '"' || current == '\'') {
-                recordStartPos();
-                state = InString;
-                multiLineString = false;
-                stringType = current;
-            } else if (current == '\\' && next1 == 'u') {
-                identifierWithEscapedUnicode = true;
-                recordStartPos();
-
-                shift(2); // skip the unicode escape prefix `\u'
-
-                if (isHexDigit(current) && isHexDigit(next1) &&
-                     isHexDigit(next2) && isHexDigit(next3)) {
-                    record16(convertUnicode(current, next1, next2, next3));
-                    shift(3);
-                    state = InIdentifier;
-                } else {
-                    setDone(Bad);
-                    err = IllegalUnicodeEscapeSequence;
-                    errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
-                    break;
-                }
+    *ok = false;
+    return QChar();
+}
 
-            } else if (isIdentLetter(current)) {
-                identifierWithEscapedUnicode = false;
-                recordStartPos();
-                record16(current);
-                state = InIdentifier;
-            } else if (current == '0') {
-                recordStartPos();
-                record8(current);
-                state = InNum0;
-            } else if (isDecimalDigit(current)) {
-                recordStartPos();
-                record8(current);
-                state = InNum;
-            } else if (current == '.' && isDecimalDigit(next1)) {
-                recordStartPos();
-                record8(current);
-                state = InDecimal;
+int Lexer::scanToken()
+{
+    if (_stackToken != -1) {
+        int tk = _stackToken;
+        _stackToken = -1;
+        return tk;
+    }
+
+    _terminator = false;
+
+again:
+    _validTokenText = false;
+    _tokenLinePtr = _lastLinePtr;
+
+    while (QmlUtils::isSpace(_char)) {
+        if (_char == QLatin1Char('\n')) {
+            _tokenLinePtr = _codePtr;
+
+            if (_restrictedKeyword) {
+                // automatic semicolon insertion
+                _tokenLine = _currentLineNumber;
+                _tokenStartPtr = _codePtr - 1; // ### TODO: insert it before the optional \r sequence.
+                return T_SEMICOLON;
             } else {
-                recordStartPos();
-                token = matchPunctuator(current, next1, next2, next3);
-                if (token != -1) {
-                    if (terminator && !delimited && !prohibitAutomaticSemicolon
-                        && (token == QmlJSGrammar::T_PLUS_PLUS
-                            || token == QmlJSGrammar::T_MINUS_MINUS)) {
-                        // automatic semicolon insertion
-                        stackToken = token;
-                        token = QmlJSGrammar::T_SEMICOLON;
-                    }
-                    setDone(Other);
-                }
-                else {
-                    setDone(Bad);
-                    err = IllegalCharacter;
-                    errmsg = QCoreApplication::translate("QmlParser", "Illegal character");
+                _terminator = true;
+                syncProhibitAutomaticSemicolon();
+            }
+        }
+
+        scanChar();
+    }
+
+    _tokenStartPtr = _codePtr - 1;
+    _tokenLine = _currentLineNumber;
+
+    if (_char.isNull())
+        return EOF_SYMBOL;
+
+    const QChar ch = _char;
+    scanChar();
+
+    switch (ch.unicode()) {
+    case '~': return T_TILDE;
+    case '}': return T_RBRACE;
+
+    case '|':
+        if (_char == QLatin1Char('|')) {
+            scanChar();
+            return T_OR_OR;
+        } else if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_OR_EQ;
+        }
+        return T_OR;
+
+    case '{': return T_LBRACE;
+
+    case '^':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_XOR_EQ;
+        }
+        return T_XOR;
+
+    case ']': return T_RBRACKET;
+    case '[': return T_LBRACKET;
+    case '?': return T_QUESTION;
+
+    case '>':
+        if (_char == QLatin1Char('>')) {
+            scanChar();
+            if (_char == QLatin1Char('>')) {
+                scanChar();
+                if (_char == QLatin1Char('=')) {
+                    scanChar();
+                    return T_GT_GT_GT_EQ;
                 }
+                return T_GT_GT_GT;
+            } else if (_char == QLatin1Char('=')) {
+                scanChar();
+                return T_GT_GT_EQ;
             }
-            break;
-        case InString:
-            if (current == stringType) {
-                shift(1);
-                setDone(String);
-            } else if (isLineTerminator()) {
-                multiLineString = true;
-                record16(current);
-            } else if (current == 0 || isLineTerminator()) {
-                setDone(Bad);
-                err = UnclosedStringLiteral;
-                errmsg = QCoreApplication::translate("QmlParser", "Unclosed string at end of line");
-            } else if (current == '\\') {
-                state = InEscapeSequence;
-            } else {
-                record16(current);
+            return T_GT_GT;
+        } else if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_GE;
+        }
+        return T_GT;
+
+    case '=':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            if (_char == QLatin1Char('=')) {
+                scanChar();
+                return T_EQ_EQ_EQ;
             }
-            break;
-            // Escape Sequences inside of strings
-        case InEscapeSequence:
-            if (isOctalDigit(current)) {
-                if (current >= '0' && current <= '3' &&
-                     isOctalDigit(next1) && isOctalDigit(next2)) {
-                    record16(convertOctal(current, next1, next2));
-                    shift(2);
-                    state = InString;
-                } else if (isOctalDigit(current) &&
-                            isOctalDigit(next1)) {
-                    record16(convertOctal('0', current, next1));
-                    shift(1);
-                    state = InString;
-                } else if (isOctalDigit(current)) {
-                    record16(convertOctal('0', '0', current));
-                    state = InString;
-                } else {
-                    setDone(Bad);
-                    err = IllegalEscapeSequence;
-                    errmsg = QCoreApplication::translate("QmlParser", "Illegal escape sequence");
-                }
-            } else if (current == 'x')
-                state = InHexEscape;
-            else if (current == 'u')
-                state = InUnicodeEscape;
-            else {
-                if (isLineTerminator()) {
-                    shiftWindowsLineBreak();
-                    yylineno++;
-                    yycolumn = 0;
-                    bol = true;
+            return T_EQ_EQ;
+        }
+        return T_EQ;
+
+    case '<':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_LE;
+        } else if (_char == QLatin1Char('<')) {
+            scanChar();
+            if (_char == QLatin1Char('=')) {
+                scanChar();
+                return T_LT_LT_EQ;
+            }
+            return T_LT_LT;
+        }
+        return T_LT;
+
+    case ';': return T_SEMICOLON;
+    case ':': return T_COLON;
+
+    case '/':
+        if (_char == QLatin1Char('*')) {
+            scanChar();
+            while (!_char.isNull()) {
+                if (_char == QLatin1Char('*')) {
+                    scanChar();
+                    if (_char == QLatin1Char('/')) {
+                        scanChar();
+
+                        if (_engine) {
+                            _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
+                                                tokenStartLine(), tokenStartColumn() + 2);
+                        }
+
+                        goto again;
+                    }
                 } else {
-                    record16(singleEscape(current));
+                    scanChar();
                 }
-                state = InString;
             }
-            break;
-        case InHexEscape:
-            if (isHexDigit(current) && isHexDigit(next1)) {
-                state = InString;
-                record16(QLatin1Char(convertHex(current, next1)));
-                shift(1);
-            } else if (current == stringType) {
-                record16(QLatin1Char('x'));
-                shift(1);
-                setDone(String);
-            } else {
-                record16(QLatin1Char('x'));
-                record16(current);
-                state = InString;
+        } else if (_char == QLatin1Char('/')) {
+            while (!_char.isNull() && _char != QLatin1Char('\n')) {
+                scanChar();
             }
-            break;
-        case InUnicodeEscape:
-            if (isHexDigit(current) && isHexDigit(next1) &&
-                 isHexDigit(next2) && isHexDigit(next3)) {
-                record16(convertUnicode(current, next1, next2, next3));
-                shift(3);
-                state = InString;
-            } else if (current == stringType) {
-                record16(QLatin1Char('u'));
-                shift(1);
-                setDone(String);
-            } else {
-                setDone(Bad);
-                err = IllegalUnicodeEscapeSequence;
-                errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
-            }
-            break;
-        case InSingleLineComment:
-            if (isLineTerminator()) {
-                shiftWindowsLineBreak();
-                yylineno++;
-                yycolumn = 0;
-                terminator = true;
-                bol = true;
-                if (restrKeyword) {
-                    token = QmlJSGrammar::T_SEMICOLON;
-                    setDone(Other);
-                } else
-                    state = Start;
-                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
-            } else if (current == 0) {
-                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
-                setDone(Eof);
+            if (_engine) {
+                _engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
+                                    tokenStartLine(), tokenStartColumn() + 2);
             }
+            goto again;
+        } if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_DIVIDE_EQ;
+        }
+        return T_DIVIDE_;
 
-            break;
-        case InMultiLineComment:
-            if (current == 0) {
-                setDone(Bad);
-                err = UnclosedComment;
-                errmsg = QCoreApplication::translate("QmlParser", "Unclosed comment at end of file");
-                if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2);
-            } else if (isLineTerminator()) {
-                shiftWindowsLineBreak();
-                yylineno++;
-            } else if (current == '*' && next1 == '/') {
-                state = Start;
-                shift(1);
-                if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2);
+    case '.':
+        if (QmlUtils::isDigit(_char)) {
+            QVarLengthArray<char,32> chars;
+
+            chars.append(ch.unicode()); // append the `.'
+
+            while (QmlUtils::isDigit(_char)) {
+                chars.append(_char.unicode());
+                scanChar();
             }
 
-            break;
-        case InIdentifier:
-            if (isIdentLetter(current) || isDecimalDigit(current)) {
-                record16(current);
-                break;
-            } else if (current == '\\' && next1 == 'u') {
-                identifierWithEscapedUnicode = true;
-                shift(2); // skip the unicode escape prefix `\u'
-
-                if (isHexDigit(current) && isHexDigit(next1) &&
-                     isHexDigit(next2) && isHexDigit(next3)) {
-                    record16(convertUnicode(current, next1, next2, next3));
-                    shift(3);
-                    break;
-                } else {
-                    setDone(Bad);
-                    err = IllegalUnicodeEscapeSequence;
-                    errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
-                    break;
+            if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+                if (QmlUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                              QmlUtils::isDigit(_codePtr[1]))) {
+
+                    chars.append(_char.unicode());
+                    scanChar(); // consume `e'
+
+                    if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+                        chars.append(_char.unicode());
+                        scanChar(); // consume the sign
+                    }
+
+                    while (QmlUtils::isDigit(_char)) {
+                        chars.append(_char.unicode());
+                        scanChar();
+                    }
                 }
             }
-            setDone(Identifier);
-            break;
-        case InNum0:
-            if (current == 'x' || current == 'X') {
-                record8(current);
-                state = InHex;
-            } else if (current == '.') {
-                record8(current);
-                state = InDecimal;
-            } else if (current == 'e' || current == 'E') {
-                record8(current);
-                state = InExponentIndicator;
-            } else if (isOctalDigit(current)) {
-                record8(current);
-                state = InOctal;
-            } else if (isDecimalDigit(current)) {
-                record8(current);
-                state = InDecimal;
-            } else {
-                setDone(Number);
-            }
-            break;
-        case InHex:
-            if (isHexDigit(current))
-                record8(current);
-            else
-                setDone(Hex);
-            break;
-        case InOctal:
-            if (isOctalDigit(current)) {
-                record8(current);
-            } else if (isDecimalDigit(current)) {
-                record8(current);
-                state = InDecimal;
-            } else {
-                setDone(Octal);
+
+            chars.append('\0');
+
+            const char *begin = chars.constData();
+            const char *end = 0;
+            bool ok = false;
+
+            _tokenValue = qstrtod(begin, &end, &ok);
+
+            if (end - begin != chars.size() - 1) {
+                _errorCode = IllegalExponentIndicator;
+                _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number");
+                return T_ERROR;
             }
-            break;
-        case InNum:
-            if (isDecimalDigit(current)) {
-                record8(current);
-            } else if (current == '.') {
-                record8(current);
-                state = InDecimal;
-            } else if (current == 'e' || current == 'E') {
-                record8(current);
-                state = InExponentIndicator;
-            } else {
-                setDone(Number);
+
+            return T_NUMERIC_LITERAL;
+        }
+        return T_DOT;
+
+    case '-':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_MINUS_EQ;
+        } else if (_char == QLatin1Char('-')) {
+            scanChar();
+
+            if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
+                _stackToken = T_PLUS_PLUS;
+                return T_SEMICOLON;
             }
-            break;
-        case InDecimal:
-            if (isDecimalDigit(current)) {
-                record8(current);
-            } else if (current == 'e' || current == 'E') {
-                record8(current);
-                state = InExponentIndicator;
-            } else {
-                setDone(Number);
+
+            return T_MINUS_MINUS;
+        }
+        return T_MINUS;
+
+    case ',': return T_COMMA;
+
+    case '+':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_PLUS_EQ;
+        } else if (_char == QLatin1Char('+')) {
+            scanChar();
+
+            if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
+                _stackToken = T_PLUS_PLUS;
+                return T_SEMICOLON;
             }
-            break;
-        case InExponentIndicator:
-            if (current == '+' || current == '-') {
-                record8(current);
-            } else if (isDecimalDigit(current)) {
-                record8(current);
-                state = InExponent;
-            } else {
-                setDone(Bad);
-                err = IllegalExponentIndicator;
-                errmsg = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number");
+
+            return T_PLUS_PLUS;
+        }
+        return T_PLUS;
+
+    case '*':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_STAR_EQ;
+        }
+        return T_STAR;
+
+    case ')': return T_RPAREN;
+    case '(': return T_LPAREN;
+
+    case '&':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_AND_EQ;
+        } else if (_char == QLatin1Char('&')) {
+            scanChar();
+            return T_AND_AND;
+        }
+        return T_AND;
+
+    case '%':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            return T_REMAINDER_EQ;
+        }
+        return T_REMAINDER;
+
+    case '!':
+        if (_char == QLatin1Char('=')) {
+            scanChar();
+            if (_char == QLatin1Char('=')) {
+                scanChar();
+                return T_NOT_EQ_EQ;
             }
-            break;
-        case InExponent:
-            if (isDecimalDigit(current)) {
-                record8(current);
-            } else {
-                setDone(Number);
+            return T_NOT_EQ;
+        }
+        return T_NOT;
+
+    case '\'':
+    case '"': {
+        const QChar quote = ch;
+        bool multilineStringLiteral = false;
+
+        const QChar *startCode = _codePtr;
+
+        if (_engine) {
+            while (!_char.isNull()) {
+                if (_char == QLatin1Char('\n') || _char == QLatin1Char('\\')) {
+                    break;
+                } else if (_char == quote) {
+                    _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
+                    scanChar();
+
+                    return T_STRING_LITERAL;
+                }
+                scanChar();
             }
-            break;
-        default:
-            Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement");
         }
 
-        // move on to the next character
-        if (!done)
-            shift(1);
-        if (state != Start && state != InSingleLineComment)
-            bol = false;
-    }
+        _validTokenText = true;
+        _tokenText.resize(0);
+        startCode--;
+        while (startCode != _codePtr - 1) 
+            _tokenText += *startCode++;
+
+        while (! _char.isNull()) {
+            if (_char == QLatin1Char('\n')) {
+                multilineStringLiteral = true;
+                _tokenText += _char;
+                scanChar();
+            } else if (_char == quote) {
+                scanChar();
+
+                if (_engine)
+                    _tokenSpell = _engine->newStringRef(_tokenText);
+
+                return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
+            } else if (_char == QLatin1Char('\\')) {
+                scanChar();
+
+                QChar u;
+                bool ok = false;
+
+                switch (_char.unicode()) {
+                // unicode escape sequence
+                case 'u':
+                    u = decodeUnicodeEscapeCharacter(&ok);
+                    if (! ok)
+                        u = _char;
+                    break;
 
-    // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
-    if ((state == Number || state == Octal || state == Hex)
-         && isIdentLetter(current)) {
-        state = Bad;
-        err = IllegalIdentifier;
-        errmsg = QCoreApplication::translate("QmlParser", "Identifier cannot start with numeric literal");
-    }
+                // hex escape sequence
+                case 'x':
+                case 'X':
+                    if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
+                        scanChar();
 
-    // terminate string
-    buffer8[pos8] = '\0';
-
-    double dval = 0;
-    if (state == Number) {
-        dval = qstrtod(buffer8, 0, 0);
-    } else if (state == Hex) { // scan hex numbers
-        dval = integerFromString(buffer8, pos8, 16);
-        state = Number;
-    } else if (state == Octal) {   // scan octal number
-        dval = integerFromString(buffer8, pos8, 8);
-        state = Number;
-    }
+                        const QChar c1 = _char;
+                        scanChar();
 
-    restrKeyword = false;
-    delimited = false;
+                        const QChar c2 = _char;
+                        scanChar();
 
-    switch (parenthesesState) {
-    case IgnoreParentheses:
-        break;
-    case CountParentheses:
-        if (token == QmlJSGrammar::T_RPAREN) {
-            --parenthesesCount;
-            if (parenthesesCount == 0)
-                parenthesesState = BalancedParentheses;
-        } else if (token == QmlJSGrammar::T_LPAREN) {
-            ++parenthesesCount;
+                        u = convertHex(c1, c2);
+                    } else {
+                        u = _char;
+                    }
+                    break;
+
+                // single character escape sequence
+                case '\\': u = QLatin1Char('\\'); scanChar(); break;
+                case '\'': u = QLatin1Char('\''); scanChar(); break;
+                case '\"': u = QLatin1Char('\"'); scanChar(); break;
+                case 'b':  u = QLatin1Char('\b'); scanChar(); break;
+                case 'f':  u = QLatin1Char('\f'); scanChar(); break;
+                case 'n':  u = QLatin1Char('\n'); scanChar(); break;
+                case 'r':  u = QLatin1Char('\r'); scanChar(); break;
+                case 't':  u = QLatin1Char('\t'); scanChar(); break;
+                case 'v':  u = QLatin1Char('\v'); scanChar(); break;
+
+                case '0':
+                    if (! _codePtr[1].isDigit()) {
+                        scanChar();
+                        u = QLatin1Char('\0');
+                    } else {
+                        // ### parse deprecated octal escape sequence ?
+                        u = _char;
+                    }
+                    break;
+
+                case '\r':
+                    while (_char == QLatin1Char('\r'))
+                        scanChar();
+
+                    if (_char == QLatin1Char('\n')) {
+                        u = _char;
+                        scanChar();
+                    } else {
+                        u = QLatin1Char('\n');
+                    }
+
+                    break;
+
+                case '\n':
+                    u = _char;
+                    scanChar();
+                    break;
+
+                default:
+                    // non escape character
+                    u = _char;
+                    scanChar();
+                }
+
+                _tokenText += u;
+            } else {
+                _tokenText += _char;
+                scanChar();
+            }
         }
-        break;
-    case BalancedParentheses:
-        parenthesesState = IgnoreParentheses;
-        break;
+
+        _errorCode = UnclosedStringLiteral;
+        _errorMessage = QCoreApplication::translate("QmlParser", "Unclosed string at end of line");
+        return T_ERROR;
     }
 
-    switch (state) {
-    case Eof:
-        return 0;
-    case Other:
-        if (token == QmlJSGrammar::T_RBRACE || token == QmlJSGrammar::T_SEMICOLON)
-            delimited = true;
-        return token;
-    case Identifier:
-        token = -1;
-        if (! identifierWithEscapedUnicode)
-            token = findReservedWord(buffer16, pos16);
-
-        if (token < 0) {
-            /* TODO: close leak on parse error. same holds true for String */
-            if (driver)
-                qsyylval.ustr = driver->intern(buffer16, pos16);
-            else
-                qsyylval.ustr = 0;
-            return QmlJSGrammar::T_IDENTIFIER;
-        }
-        if (token == QmlJSGrammar::T_CONTINUE || token == QmlJSGrammar::T_BREAK
-            || token == QmlJSGrammar::T_RETURN || token == QmlJSGrammar::T_THROW) {
-            restrKeyword = true;
-        } else if (token == QmlJSGrammar::T_IF || token == QmlJSGrammar::T_FOR
-                   || token == QmlJSGrammar::T_WHILE || token == QmlJSGrammar::T_WITH) {
-            parenthesesState = CountParentheses;
-            parenthesesCount = 0;
-        } else if (token == QmlJSGrammar::T_DO) {
-            parenthesesState = BalancedParentheses;
-        }
-        return token;
-    case String:
-        if (driver)
-            qsyylval.ustr = driver->intern(buffer16, pos16);
-        else
-            qsyylval.ustr = 0;
-        return multiLineString?QmlJSGrammar::T_MULTILINE_STRING_LITERAL:QmlJSGrammar::T_STRING_LITERAL;
-    case Number:
-        qsyylval.dval = dval;
-        return QmlJSGrammar::T_NUMERIC_LITERAL;
-    case Bad:
-        return -1;
     default:
-        Q_ASSERT(!"unhandled numeration value in switch");
-        return -1;
-    }
-}
+        if (QmlUtils::isLetter(ch) || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
+            bool identifierWithEscapeChars = false;
+            if (ch == QLatin1Char('\\')) {
+                identifierWithEscapeChars = true;
+                _tokenText.resize(0);
+                bool ok = false;
+                _tokenText += decodeUnicodeEscapeCharacter(&ok);
+                _validTokenText = true;
+                if (! ok) {
+                    _errorCode = IllegalUnicodeEscapeSequence;
+                    _errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
+                    return T_ERROR;
+                }
+            }
+            while (true) {
+                if (QmlUtils::isLetterOrNumber(_char) || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
+                    if (identifierWithEscapeChars)
+                        _tokenText += _char;
+
+                    scanChar();
+                } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
+                    if (! identifierWithEscapeChars) {
+                        identifierWithEscapeChars = true;
+                        _tokenText.resize(0);
+                        _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
+                        _validTokenText = true;
+                    }
 
-bool Lexer::isWhiteSpace() const
-{
-    return (current == ' ' || current == '\t' ||
-             current == 0x0b || current == 0x0c);
-}
+                    scanChar(); // skip '\\'
+                    bool ok = false;
+                    _tokenText += decodeUnicodeEscapeCharacter(&ok);
+                    if (! ok) {
+                        _errorCode = IllegalUnicodeEscapeSequence;
+                        _errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
+                        return T_ERROR;
+                    }
+                } else {
+                    _tokenLength = _codePtr - _tokenStartPtr - 1;
 
-bool Lexer::isLineTerminator() const
-{
-    return (current == '\n' || current == '\r');
-}
+                    int kind = T_IDENTIFIER;
 
-bool Lexer::isIdentLetter(ushort c)
-{
-    // ASCII-biased, since all reserved words are ASCII, aand hence the
-    // bulk of content to be parsed.
-    if ((c >= 'a' && c <= 'z')
-            || (c >= 'A' && c <= 'Z')
-            || c == '$'
-            || c == '_')
-        return true;
-    if (c < 128)
-        return false;
-    return QChar(c).isLetterOrNumber();
-}
+                    if (! identifierWithEscapeChars)
+                        kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
 
-bool Lexer::isDecimalDigit(ushort c)
-{
-    return (c >= '0' && c <= '9');
-}
+                    if (_engine) {
+                        if (kind == T_IDENTIFIER && identifierWithEscapeChars)
+                            _tokenSpell = _engine->newStringRef(_tokenText);
+                        else
+                            _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
+                    }
 
-bool Lexer::isHexDigit(ushort c) const
-{
-    return ((c >= '0' && c <= '9')
-            || (c >= 'a' && c <= 'f')
-            || (c >= 'A' && c <= 'F'));
-}
+                    return kind;
+                }
+            }
+        } else if (QmlUtils::isDigit(ch)) {
+            if (ch != QLatin1Char('0')) {
+                double integer = ch.unicode() - '0';
+
+                QChar n = _char;
+                const QChar *code = _codePtr;
+                while (QmlUtils::isDigit(n)) {
+                    integer = integer * 10 + (n.unicode() - '0');
+                    n = *code++;
+                }
 
-bool Lexer::isOctalDigit(ushort c) const
-{
-    return (c >= '0' && c <= '7');
-}
+                if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) {
+                    if (code != _codePtr) {
+                        _codePtr = code - 1;
+                        scanChar();
+                    }
+                    _tokenValue = integer;
+                    return T_NUMERIC_LITERAL;
+                }
+            }
 
-int Lexer::matchPunctuator(ushort c1, ushort c2,
-                            ushort c3, ushort c4)
-{
-    if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
-        shift(4);
-        return QmlJSGrammar::T_GT_GT_GT_EQ;
-    } else if (c1 == '=' && c2 == '=' && c3 == '=') {
-        shift(3);
-        return QmlJSGrammar::T_EQ_EQ_EQ;
-    } else if (c1 == '!' && c2 == '=' && c3 == '=') {
-        shift(3);
-        return QmlJSGrammar::T_NOT_EQ_EQ;
-    } else if (c1 == '>' && c2 == '>' && c3 == '>') {
-        shift(3);
-        return QmlJSGrammar::T_GT_GT_GT;
-    } else if (c1 == '<' && c2 == '<' && c3 == '=') {
-        shift(3);
-        return QmlJSGrammar::T_LT_LT_EQ;
-    } else if (c1 == '>' && c2 == '>' && c3 == '=') {
-        shift(3);
-        return QmlJSGrammar::T_GT_GT_EQ;
-    } else if (c1 == '<' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_LE;
-    } else if (c1 == '>' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_GE;
-    } else if (c1 == '!' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_NOT_EQ;
-    } else if (c1 == '+' && c2 == '+') {
-        shift(2);
-        return QmlJSGrammar::T_PLUS_PLUS;
-    } else if (c1 == '-' && c2 == '-') {
-        shift(2);
-        return QmlJSGrammar::T_MINUS_MINUS;
-    } else if (c1 == '=' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_EQ_EQ;
-    } else if (c1 == '+' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_PLUS_EQ;
-    } else if (c1 == '-' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_MINUS_EQ;
-    } else if (c1 == '*' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_STAR_EQ;
-    } else if (c1 == '/' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_DIVIDE_EQ;
-    } else if (c1 == '&' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_AND_EQ;
-    } else if (c1 == '^' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_XOR_EQ;
-    } else if (c1 == '%' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_REMAINDER_EQ;
-    } else if (c1 == '|' && c2 == '=') {
-        shift(2);
-        return QmlJSGrammar::T_OR_EQ;
-    } else if (c1 == '<' && c2 == '<') {
-        shift(2);
-        return QmlJSGrammar::T_LT_LT;
-    } else if (c1 == '>' && c2 == '>') {
-        shift(2);
-        return QmlJSGrammar::T_GT_GT;
-    } else if (c1 == '&' && c2 == '&') {
-        shift(2);
-        return QmlJSGrammar::T_AND_AND;
-    } else if (c1 == '|' && c2 == '|') {
-        shift(2);
-        return QmlJSGrammar::T_OR_OR;
-    }
+            QVarLengthArray<char,32> chars;
+            chars.append(ch.unicode());
 
-    switch(c1) {
-        case '=': shift(1); return QmlJSGrammar::T_EQ;
-        case '>': shift(1); return QmlJSGrammar::T_GT;
-        case '<': shift(1); return QmlJSGrammar::T_LT;
-        case ',': shift(1); return QmlJSGrammar::T_COMMA;
-        case '!': shift(1); return QmlJSGrammar::T_NOT;
-        case '~': shift(1); return QmlJSGrammar::T_TILDE;
-        case '?': shift(1); return QmlJSGrammar::T_QUESTION;
-        case ':': shift(1); return QmlJSGrammar::T_COLON;
-        case '.': shift(1); return QmlJSGrammar::T_DOT;
-        case '+': shift(1); return QmlJSGrammar::T_PLUS;
-        case '-': shift(1); return QmlJSGrammar::T_MINUS;
-        case '*': shift(1); return QmlJSGrammar::T_STAR;
-        case '/': shift(1); return QmlJSGrammar::T_DIVIDE_;
-        case '&': shift(1); return QmlJSGrammar::T_AND;
-        case '|': shift(1); return QmlJSGrammar::T_OR;
-        case '^': shift(1); return QmlJSGrammar::T_XOR;
-        case '%': shift(1); return QmlJSGrammar::T_REMAINDER;
-        case '(': shift(1); return QmlJSGrammar::T_LPAREN;
-        case ')': shift(1); return QmlJSGrammar::T_RPAREN;
-        case '{': shift(1); return QmlJSGrammar::T_LBRACE;
-        case '}': shift(1); return QmlJSGrammar::T_RBRACE;
-        case '[': shift(1); return QmlJSGrammar::T_LBRACKET;
-        case ']': shift(1); return QmlJSGrammar::T_RBRACKET;
-        case ';': shift(1); return QmlJSGrammar::T_SEMICOLON;
-
-        default: return -1;
-    }
-}
+            if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
+                // parse hex integer literal
 
-ushort Lexer::singleEscape(ushort c) const
-{
-    switch(c) {
-    case 'b':
-        return 0x08;
-    case 't':
-        return 0x09;
-    case 'n':
-        return 0x0A;
-    case 'v':
-        return 0x0B;
-    case 'f':
-        return 0x0C;
-    case 'r':
-        return 0x0D;
-    case '"':
-        return 0x22;
-    case '\'':
-        return 0x27;
-    case '\\':
-        return 0x5C;
-    default:
-        return c;
-    }
-}
+                chars.append(_char.unicode());
+                scanChar(); // consume `x'
 
-ushort Lexer::convertOctal(ushort c1, ushort c2,
-                            ushort c3) const
-{
-    return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
-}
+                while (isHexDigit(_char)) {
+                    chars.append(_char.unicode());
+                    scanChar();
+                }
 
-unsigned char Lexer::convertHex(ushort c)
-{
-    if (c >= '0' && c <= '9')
-        return (c - '0');
-    else if (c >= 'a' && c <= 'f')
-        return (c - 'a' + 10);
-    else
-        return (c - 'A' + 10);
-}
+                _tokenValue = integerFromString(chars.constData(), chars.size(), 16);
+                return T_NUMERIC_LITERAL;
+            }
 
-unsigned char Lexer::convertHex(ushort c1, ushort c2)
-{
-    return ((convertHex(c1) << 4) + convertHex(c2));
-}
+            // decimal integer literal
+            while (QmlUtils::isDigit(_char)) {
+                chars.append(_char.unicode());
+                scanChar(); // consume the digit
+            }
 
-QChar Lexer::convertUnicode(ushort c1, ushort c2,
-                             ushort c3, ushort c4)
-{
-    return QChar((convertHex(c3) << 4) + convertHex(c4),
-                  (convertHex(c1) << 4) + convertHex(c2));
-}
+            if (_char == QLatin1Char('.')) {
+                chars.append(_char.unicode());
+                scanChar(); // consume `.'
 
-void Lexer::record8(ushort c)
-{
-    Q_ASSERT(c <= 0xff);
-
-    // enlarge buffer if full
-    if (pos8 >= size8 - 1) {
-        char *tmp = new char[2 * size8];
-        memcpy(tmp, buffer8, size8 * sizeof(char));
-        delete [] buffer8;
-        buffer8 = tmp;
-        size8 *= 2;
-    }
+                while (QmlUtils::isDigit(_char)) {
+                    chars.append(_char.unicode());
+                    scanChar();
+                }
 
-    buffer8[pos8++] = (char) c;
-}
+                if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+                    if (QmlUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                                  QmlUtils::isDigit(_codePtr[1]))) {
 
-void Lexer::record16(QChar c)
-{
-    // enlarge buffer if full
-    if (pos16 >= size16 - 1) {
-        QChar *tmp = new QChar[2 * size16];
-        memcpy(tmp, buffer16, size16 * sizeof(QChar));
-        delete [] buffer16;
-        buffer16 = tmp;
-        size16 *= 2;
-    }
+                        chars.append(_char.unicode());
+                        scanChar(); // consume `e'
 
-    buffer16[pos16++] = c;
-}
+                        if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+                            chars.append(_char.unicode());
+                            scanChar(); // consume the sign
+                        }
 
-void Lexer::recordStartPos()
-{
-    startpos = pos;
-    startlineno = yylineno;
-    startcolumn = yycolumn;
+                        while (QmlUtils::isDigit(_char)) {
+                            chars.append(_char.unicode());
+                            scanChar();
+                        }
+                    }
+                }
+            } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+                if (QmlUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                              QmlUtils::isDigit(_codePtr[1]))) {
+
+                    chars.append(_char.unicode());
+                    scanChar(); // consume `e'
+
+                    if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+                        chars.append(_char.unicode());
+                        scanChar(); // consume the sign
+                    }
+
+                    while (QmlUtils::isDigit(_char)) {
+                        chars.append(_char.unicode());
+                        scanChar();
+                    }
+                }
+            }
+
+            chars.append('\0');
+
+            const char *begin = chars.constData();
+            const char *end = 0;
+            bool ok = false;
+
+            _tokenValue = qstrtod(begin, &end, &ok);
+
+            if (end - begin != chars.size() - 1) {
+                _errorCode = IllegalExponentIndicator;
+                _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number");
+                return T_ERROR;
+            }
+
+            return T_NUMERIC_LITERAL;
+        }
+
+        break;
+    }
+
+    return T_ERROR;
 }
 
 bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
 {
-    pos16 = 0;
-    pattern = 0;
+    _tokenText.resize(0);
+    _validTokenText = true;
+    _patternFlags = 0;
 
     if (prefix == EqualPrefix)
-        record16(QLatin1Char('='));
+        _tokenText += QLatin1Char('=');
 
     while (true) {
-        switch (current) {
-
+        switch (_char.unicode()) {
         case 0: // eof
         case '\n': case '\r': // line terminator
-            errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression literal");
+            _errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression literal");
             return false;
 
         case '/':
-            shift(1);
-
-            if (driver) // create the pattern
-                pattern = driver->intern(buffer16, pos16);
+            scanChar();
 
             // scan the flags
-            pos16 = 0;
-            flags = 0;
-            while (isIdentLetter(current)) {
-                int flag = Ecma::RegExp::flagFromChar(current);
+            _patternFlags = 0;
+            while (isIdentLetter(_char)) {
+                int flag = flagFromChar(_char);
                 if (flag == 0) {
-                    errmsg = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'")
-                             .arg(QChar(current));
+                    _errorMessage = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'")
+                             .arg(QChar(_char));
                     return false;
                 }
-                flags |= flag;
-                record16(current);
-                shift(1);
+                _patternFlags |= flag;
+                scanChar();
             }
+
+            _tokenLength = _codePtr - _tokenStartPtr - 1;
             return true;
 
         case '\\':
             // regular expression backslash sequence
-            record16(current);
-            shift(1);
+            _tokenText += _char;
+            scanChar();
 
-            if (! current || isLineTerminator()) {
-                errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
+            if (_char.isNull() || isLineTerminator()) {
+                _errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
                 return false;
             }
 
-            record16(current);
-            shift(1);
+            _tokenText += _char;
+            scanChar();
             break;
 
         case '[':
             // regular expression class
-            record16(current);
-            shift(1);
+            _tokenText += _char;
+            scanChar();
 
-            while (current && ! isLineTerminator()) {
-                if (current == ']')
+            while (! _char.isNull() && ! isLineTerminator()) {
+                if (_char == QLatin1Char(']'))
                     break;
-                else if (current == '\\') {
+                else if (_char == QLatin1Char('\\')) {
                     // regular expression backslash sequence
-                    record16(current);
-                    shift(1);
+                    _tokenText += _char;
+                    scanChar();
 
-                    if (! current || isLineTerminator()) {
-                        errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
+                    if (_char.isNull() || isLineTerminator()) {
+                        _errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
                         return false;
                     }
 
-                    record16(current);
-                    shift(1);
+                    _tokenText += _char;
+                    scanChar();
                 } else {
-                    record16(current);
-                    shift(1);
+                    _tokenText += _char;
+                    scanChar();
                 }
             }
 
-            if (current != ']') {
-                errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression class");
+            if (_char != QLatin1Char(']')) {
+                _errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression class");
                 return false;
             }
 
-            record16(current);
-            shift(1); // skip ]
+            _tokenText += _char;
+            scanChar(); // skip ]
             break;
 
         default:
-            record16(current);
-            shift(1);
+            _tokenText += _char;
+            scanChar();
         } // switch
     } // while
 
     return false;
 }
 
+bool Lexer::isLineTerminator() const
+{
+    return (_char == QLatin1Char('\n') || _char == QLatin1Char('\r'));
+}
+
+bool Lexer::isIdentLetter(QChar ch)
+{
+    // ASCII-biased, since all reserved words are ASCII, aand hence the
+    // bulk of content to be parsed.
+    if ((ch >= QLatin1Char('a') && ch <= QLatin1Char('z'))
+            || (ch >= QLatin1Char('A') && ch <= QLatin1Char('Z'))
+            || ch == QLatin1Char('$')
+            || ch == QLatin1Char('_'))
+        return true;
+    if (ch.unicode() < 128)
+        return false;
+    return ch.isLetterOrNumber();
+}
+
+bool Lexer::isDecimalDigit(ushort c)
+{
+    return (c >= '0' && c <= '9');
+}
+
+bool Lexer::isHexDigit(QChar c)
+{
+    return ((c >= QLatin1Char('0') && c <= QLatin1Char('9'))
+            || (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
+            || (c >= QLatin1Char('A') && c <= QLatin1Char('F')));
+}
+
+bool Lexer::isOctalDigit(ushort c)
+{
+    return (c >= '0' && c <= '7');
+}
+
+int Lexer::tokenOffset() const
+{
+    return _tokenStartPtr - _code.unicode();
+}
+
+int Lexer::tokenLength() const
+{
+    return _tokenLength;
+}
+
+int Lexer::tokenStartLine() const
+{
+    return _tokenLine;
+}
+
+int Lexer::tokenStartColumn() const
+{
+    return _tokenStartPtr - _tokenLinePtr + 1;
+}
+
+int Lexer::tokenEndLine() const
+{
+    return _currentLineNumber;
+}
+
+int Lexer::tokenEndColumn() const
+{
+    return _codePtr - _lastLinePtr;
+}
+
+QStringRef Lexer::tokenSpell() const
+{
+    return _tokenSpell;
+}
+
+double Lexer::tokenValue() const
+{
+    return _tokenValue;
+}
+
+QString Lexer::tokenText() const
+{
+    if (_validTokenText)
+        return _tokenText;
+
+    if (_tokenKind == T_STRING_LITERAL)
+        return QString(_tokenStartPtr + 1, _tokenLength - 2);
+
+    return QString(_tokenStartPtr, _tokenLength);
+}
+
+Lexer::Error Lexer::errorCode() const
+{
+    return _errorCode;
+}
+
+QString Lexer::errorMessage() const
+{
+    return _errorMessage;
+}
+
 void Lexer::syncProhibitAutomaticSemicolon()
 {
-    if (parenthesesState == BalancedParentheses) {
+    if (_parenthesesState == BalancedParentheses) {
         // we have seen something like "if (foo)", which means we should
         // never insert an automatic semicolon at this point, since it would
         // then be expanded into an empty statement (ECMA-262 7.9.1)
-        prohibitAutomaticSemicolon = true;
-        parenthesesState = IgnoreParentheses;
+        _prohibitAutomaticSemicolon = true;
+        _parenthesesState = IgnoreParentheses;
     } else {
-        prohibitAutomaticSemicolon = false;
+        _prohibitAutomaticSemicolon = false;
     }
 }
 
-QT_QML_END_NAMESPACE
-
+bool Lexer::prevTerminator() const
+{
+    return _terminator;
+}
 
+#include "qmljskeywords_p.h"
index 7f081af..540df38 100644 (file)
@@ -45,7 +45,7 @@
 //
 
 #include "qmljsglobal_p.h"
-
+#include "qmljsgrammar_p.h"
 #include <QtCore/QString>
 
 QT_QML_BEGIN_NAMESPACE
@@ -53,55 +53,41 @@ QT_QML_BEGIN_NAMESPACE
 namespace QmlJS {
 
 class Engine;
-class NameId;
 
-class QML_PARSER_EXPORT Lexer
+class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
 {
 public:
-    Lexer(Engine *eng, bool tokenizeComments = false);
-    ~Lexer();
-
-    void setCode(const QString &c, int lineno);
-    int lex();
-
-    int currentLineNo() const { return yylineno; }
-    int currentColumnNo() const { return yycolumn; }
-
-    int tokenOffset() const { return startpos; }
-    int tokenLength() const { return pos - startpos; }
-
-    int startLineNo() const { return startlineno; }
-    int startColumnNo() const { return startcolumn; }
-
-    int endLineNo() const { return currentLineNo(); }
-    int endColumnNo() const
-    { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; }
-
-    bool prevTerminator() const { return terminator; }
-
-    enum State { Start,
-                 Identifier,
-                 InIdentifier,
-                 InSingleLineComment,
-                 InMultiLineComment,
-                 InNum,
-                 InNum0,
-                 InHex,
-                 InOctal,
-                 InDecimal,
-                 InExponentIndicator,
-                 InExponent,
-                 Hex,
-                 Octal,
-                 Number,
-                 String,
-                 Eof,
-                 InString,
-                 InEscapeSequence,
-                 InHexEscape,
-                 InUnicodeEscape,
-                 Other,
-                 Bad };
+    enum {
+        T_ABSTRACT = T_RESERVED_WORD,
+        T_BOOLEAN = T_RESERVED_WORD,
+        T_BYTE = T_RESERVED_WORD,
+        T_CHAR = T_RESERVED_WORD,
+        T_CLASS = T_RESERVED_WORD,
+        T_DOUBLE = T_RESERVED_WORD,
+        T_ENUM = T_RESERVED_WORD,
+        T_EXPORT = T_RESERVED_WORD,
+        T_EXTENDS = T_RESERVED_WORD,
+        T_FINAL = T_RESERVED_WORD,
+        T_FLOAT = T_RESERVED_WORD,
+        T_GOTO = T_RESERVED_WORD,
+        T_IMPLEMENTS = T_RESERVED_WORD,
+        T_INT = T_RESERVED_WORD,
+        T_INTERFACE = T_RESERVED_WORD,
+        T_LET = T_RESERVED_WORD,
+        T_LONG = T_RESERVED_WORD,
+        T_NATIVE = T_RESERVED_WORD,
+        T_PACKAGE = T_RESERVED_WORD,
+        T_PRIVATE = T_RESERVED_WORD,
+        T_PROTECTED = T_RESERVED_WORD,
+        T_SHORT = T_RESERVED_WORD,
+        T_STATIC = T_RESERVED_WORD,
+        T_SUPER = T_RESERVED_WORD,
+        T_SYNCHRONIZED = T_RESERVED_WORD,
+        T_THROWS = T_RESERVED_WORD,
+        T_TRANSIENT = T_RESERVED_WORD,
+        T_VOLATILE = T_RESERVED_WORD,
+        T_YIELD = T_RESERVED_WORD
+    };
 
     enum Error {
         NoError,
@@ -114,127 +100,104 @@ public:
         IllegalIdentifier
     };
 
-    enum ParenthesesState {
-        IgnoreParentheses,
-        CountParentheses,
-        BalancedParentheses
-    };
-
     enum RegExpBodyPrefix {
         NoPrefix,
         EqualPrefix
     };
 
+public:
+    Lexer(Engine *engine);
+
+    QString code() const;
+    void setCode(const QString &code, int lineno, bool qmlMode = true);
+
+    int lex();
+
     bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
 
-    NameId *pattern;
-    int flags;
+    int regExpFlags() const { return _patternFlags; }
+    QString regExpPattern() const { return _tokenText; }
+
+    int tokenOffset() const;
+    int tokenLength() const;
 
-    State lexerState() const
-        { return state; }
+    int tokenStartLine() const;
+    int tokenStartColumn() const;
 
-    QString errorMessage() const
-        { return errmsg; }
-    void setErrorMessage(const QString &err)
-        { errmsg = err; }
-    void setErrorMessage(const char *err)
-        { setErrorMessage(QString::fromLatin1(err)); }
+    int tokenEndLine() const;
+    int tokenEndColumn() const;
 
-    Error error() const
-        { return err; }
-    void clearError()
-        { err = NoError; }
+    QStringRef tokenSpell() const;
+    double tokenValue() const;
+    QString tokenText() const;
+
+    Error errorCode() const;
+    QString errorMessage() const;
+
+    bool prevTerminator() const;
+
+    enum ParenthesesState {
+        IgnoreParentheses,
+        CountParentheses,
+        BalancedParentheses
+    };
 
 private:
-    Engine *driver;
-    int yylineno;
-    bool done;
-    char *buffer8;
-    QChar *buffer16;
-    uint size8, size16;
-    uint pos8, pos16;
-    bool terminator;
-    bool restrKeyword;
-    // encountered delimiter like "'" and "}" on last run
-    bool delimited;
-    int stackToken;
-
-    State state;
-    void setDone(State s);
-    uint pos;
-    void shift(uint p);
-    int lookupKeyword(const char *);
-
-    bool isWhiteSpace() const;
+    inline void scanChar();
+    int scanToken();
+
+    int classify(const QChar *s, int n, bool qmlMode);
+
     bool isLineTerminator() const;
-    bool isHexDigit(ushort c) const;
-    bool isOctalDigit(ushort c) const;
-
-    int matchPunctuator(ushort c1, ushort c2,
-                         ushort c3, ushort c4);
-    ushort singleEscape(ushort c) const;
-    ushort convertOctal(ushort c1, ushort c2,
-                         ushort c3) const;
-public:
-    static unsigned char convertHex(ushort c1);
-    static unsigned char convertHex(ushort c1, ushort c2);
-    static QChar convertUnicode(ushort c1, ushort c2,
-                                 ushort c3, ushort c4);
-    static bool isIdentLetter(ushort c);
+    static bool isIdentLetter(QChar c);
     static bool isDecimalDigit(ushort c);
+    static bool isHexDigit(QChar c);
+    static bool isOctalDigit(ushort c);
+    static bool isUnicodeEscapeSequence(const QChar *chars);
 
-    inline int ival() const { return qsyylval.ival; }
-    inline double dval() const { return qsyylval.dval; }
-    inline NameId *ustr() const { return qsyylval.ustr; }
-
-    const QChar *characterBuffer() const { return buffer16; }
-    int characterCount() const { return pos16; }
+    void syncProhibitAutomaticSemicolon();
+    QChar decodeUnicodeEscapeCharacter(bool *ok);
 
 private:
-    void record8(ushort c);
-    void record16(QChar c);
-    void recordStartPos();
+    Engine *_engine;
 
-    int findReservedWord(const QChar *buffer, int size) const;
+    QString _code;
+    QString _tokenText;
+    QString _errorMessage;
+    QStringRef _tokenSpell;
 
-    void syncProhibitAutomaticSemicolon();
+    const QChar *_codePtr;
+    const QChar *_lastLinePtr;
+    const QChar *_tokenLinePtr;
+    const QChar *_tokenStartPtr;
 
-    const QChar *code;
-    uint length;
-    int yycolumn;
-    int startpos;
-    int startlineno;
-    int startcolumn;
-    int bol;     // begin of line
-
-    union {
-        int ival;
-        double dval;
-        NameId *ustr;
-    } qsyylval;
-
-    // current and following unicode characters
-    ushort current, next1, next2, next3;
-
-    struct keyword {
-        const char *name;
-        int token;
-    };
+    QChar _char;
+    Error _errorCode;
+
+    int _currentLineNumber;
+    double _tokenValue;
+
+    // parentheses state
+    ParenthesesState _parenthesesState;
+    int _parenthesesCount;
 
-    QString errmsg;
-    Error err;
+    int _stackToken;
 
-    bool wantRx;
-    bool check_reserved;
+    int _patternFlags;
+    int _tokenKind;
+    int _tokenLength;
+    int _tokenLine;
 
-    ParenthesesState parenthesesState;
-    int parenthesesCount;
-    bool prohibitAutomaticSemicolon;
-    bool tokenizeComments;
+    bool _validTokenText;
+    bool _prohibitAutomaticSemicolon;
+    bool _restrictedKeyword;
+    bool _terminator;
+    bool _delimited;
+    bool _qmlMode;
 };
 
-} // namespace QmlJS
+} // end of namespace QmlJS
 
 QT_QML_END_NAMESPACE
 
-#endif
+#endif // LEXER_H
index a3f1bb9..3f5cafd 100644 (file)
@@ -48,8 +48,9 @@
 
 #include <QtCore/qglobal.h>
 #include <QtCore/qshareddata.h>
+#include <QtCore/qdebug.h>
 
-#include <string.h>
+#include <cstring>
 
 QT_QML_BEGIN_NAMESPACE
 
@@ -57,64 +58,103 @@ namespace QmlJS {
 
 class QML_PARSER_EXPORT MemoryPool : public QSharedData
 {
+    MemoryPool(const MemoryPool &other);
+    void operator =(const MemoryPool &other);
+
 public:
-    enum { maxBlockCount = -1 };
-    enum { defaultBlockSize = 1 << 12 };
-
-    MemoryPool() {
-        m_blockIndex = maxBlockCount;
-        m_currentIndex = 0;
-        m_storage = 0;
-        m_currentBlock = 0;
-        m_currentBlockSize = 0;
+    MemoryPool()
+        : _blocks(0),
+          _allocatedBlocks(0),
+          _blockCount(-1),
+          _ptr(0),
+          _end(0)
+    { }
+
+    ~MemoryPool()
+    {
+        if (_blocks) {
+            for (int i = 0; i < _allocatedBlocks; ++i) {
+                if (char *b = _blocks[i])
+                    qFree(b);
+            }
+
+            qFree(_blocks);
+        }
     }
 
-    virtual ~MemoryPool() {
-        for (int index = 0; index < m_blockIndex + 1; ++index)
-            qFree(m_storage[index]);
+    inline void *allocate(size_t size)
+    {
+        size = (size + 7) & ~7;
+        if (_ptr && (_ptr + size < _end)) {
+            void *addr = _ptr;
+            _ptr += size;
+            return addr;
+        }
+        return allocate_helper(size);
+    }
 
-        qFree(m_storage);
+    void reset()
+    {
+        _blockCount = -1;
+        _ptr = _end = 0;
     }
 
-    char *allocate(int bytes) {
-        bytes += (8 - bytes) & 7; // ensure multiple of 8 bytes (maintain alignment)
-        if (m_currentBlock == 0 || m_currentBlockSize < m_currentIndex + bytes) {
-            ++m_blockIndex;
-            m_currentBlockSize = defaultBlockSize << m_blockIndex;
+private:
+    void *allocate_helper(size_t size)
+    {
+        Q_ASSERT(size < BLOCK_SIZE);
+
+        if (++_blockCount == _allocatedBlocks) {
+            if (! _allocatedBlocks)
+                _allocatedBlocks = DEFAULT_BLOCK_COUNT;
+            else
+                _allocatedBlocks *= 2;
 
-            m_storage = reinterpret_cast<char**>(qRealloc(m_storage, sizeof(char*) * (1 + m_blockIndex)));
-            m_currentBlock = m_storage[m_blockIndex] = reinterpret_cast<char*>(qMalloc(m_currentBlockSize));
-            ::memset(m_currentBlock, 0, m_currentBlockSize);
+            _blocks = (char **) qRealloc(_blocks, sizeof(char *) * _allocatedBlocks);
 
-            m_currentIndex = (8 - quintptr(m_currentBlock)) & 7; // ensure first chunk is 64-bit aligned
-            Q_ASSERT(m_currentIndex + bytes <= m_currentBlockSize);
+            for (int index = _blockCount; index < _allocatedBlocks; ++index)
+                _blocks[index] = 0;
         }
 
-        char *p = reinterpret_cast<char *>
-            (m_currentBlock + m_currentIndex);
+        char *&block = _blocks[_blockCount];
 
-        m_currentIndex += bytes;
+        if (! block)
+            block = (char *) qMalloc(BLOCK_SIZE);
 
-        return p;
-    }
+        _ptr = block;
+        _end = _ptr + BLOCK_SIZE;
 
-    int bytesAllocated() const {
-        int bytes = 0;
-        for (int index = 0; index < m_blockIndex; ++index)
-            bytes += (defaultBlockSize << index);
-        bytes += m_currentIndex;
-        return bytes;
+        void *addr = _ptr;
+        _ptr += size;
+        return addr;
     }
 
 private:
-    int m_blockIndex;
-    int m_currentIndex;
-    char *m_currentBlock;
-    int m_currentBlockSize;
-    char **m_storage;
+    char **_blocks;
+    int _allocatedBlocks;
+    int _blockCount;
+    char *_ptr;
+    char *_end;
+
+    enum
+    {
+        BLOCK_SIZE = 8 * 1024,
+        DEFAULT_BLOCK_COUNT = 8
+    };
+};
 
-private:
-    Q_DISABLE_COPY(MemoryPool)
+class QML_PARSER_EXPORT Managed
+{
+    Managed(const Managed &other);
+    void operator = (const Managed &other);
+
+public:
+    Managed() {}
+    ~Managed() {}
+
+    void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
+    void operator delete(void *) {}
+    void operator delete(void *, MemoryPool *) {}
 };
 
 } // namespace QmlJS
diff --git a/src/libs/qmljs/parser/qmljsnodepool_p.h b/src/libs/qmljs/parser/qmljsnodepool_p.h
deleted file mode 100644 (file)
index ce01077..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/**************************************************************************
-**
-** This file is part of Qt Creator
-**
-** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
-**
-** Contact: Nokia Corporation (info@qt.nokia.com)
-**
-**
-** GNU Lesser General Public License Usage
-**
-** 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.
-**
-** Other Usage
-**
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at info@qt.nokia.com.
-**
-**************************************************************************/
-
-#ifndef QMLJSNODEPOOL_P_H
-#define QMLJSNODEPOOL_P_H
-
-//
-//  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 "qmljsglobal_p.h"
-#include "qmljsmemorypool_p.h"
-
-#include <QtCore/QHash>
-#include <QtCore/QString>
-
-QT_QML_BEGIN_NAMESPACE
-
-namespace QmlJS {
-
-namespace AST {
-class Node;
-} // namespace AST
-
-class Code;
-class CompilationUnit;
-class Engine;
-
-template <typename NodeType>
-inline NodeType *makeAstNode(MemoryPool *storage)
-{
-    NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType();
-    return node;
-}
-
-template <typename NodeType, typename Arg1>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1)
-{
-    NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1);
-    return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2)
-{
-    NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2);
-    return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2, typename Arg3>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3)
-{
-    NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3);
-    return node;
-}
-
-template <typename NodeType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
-{
-    NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3, arg4);
-    return node;
-}
-
-class QML_PARSER_EXPORT NodePool : public MemoryPool
-{
-public:
-    NodePool(const QString &fileName, Engine *engine);
-    virtual ~NodePool();
-
-    Code *createCompiledCode(AST::Node *node, CompilationUnit &compilation);
-
-    inline QString fileName() const { return m_fileName; }
-    inline Engine *engine() const { return m_engine; }
-#ifndef J_SCRIPT_NO_EVENT_NOTIFY
-    inline qint64 id() const { return m_id; }
-#endif
-
-private:
-    QHash<AST::Node*, Code*> m_codeCache;
-    QString m_fileName;
-    Engine *m_engine;
-#ifndef J_SCRIPT_NO_EVENT_NOTIFY
-    qint64 m_id;
-#endif
-
-private:
-    Q_DISABLE_COPY(NodePool)
-};
-
-} // namespace QmlJS
-
-QT_QML_END_NAMESPACE
-
-#endif
index 6293475..cf9ef24 100644 (file)
@@ -38,7 +38,7 @@
 #include "qmljsengine_p.h"
 #include "qmljslexer_p.h"
 #include "qmljsast_p.h"
-#include "qmljsnodepool_p.h"
+#include "qmljsmemorypool_p.h"
 
 
 
@@ -64,6 +64,7 @@ void Parser::reallocateStack()
     sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value)));
     state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
     location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
+    string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef)));
 }
 
 inline static bool automatic(Engine *driver, int token)
@@ -76,11 +77,13 @@ inline static bool automatic(Engine *driver, int token)
 
 Parser::Parser(Engine *engine):
     driver(engine),
+    pool(engine->pool()),
     tos(0),
     stack_size(0),
     sym_stack(0),
     state_stack(0),
     location_stack(0),
+    string_stack(0),
     first_token(0),
     last_token(0)
 {
@@ -92,6 +95,7 @@ Parser::~Parser()
         qFree(sym_stack);
         qFree(state_stack);
         qFree(location_stack);
+        qFree(string_stack);
     }
 }
 
@@ -100,14 +104,14 @@ static inline AST::SourceLocation location(Lexer *lexer)
     AST::SourceLocation loc;
     loc.offset = lexer->tokenOffset();
     loc.length = lexer->tokenLength();
-    loc.startLine = lexer->startLineNo();
-    loc.startColumn = lexer->startColumnNo();
+    loc.startLine = lexer->tokenStartLine();
+    loc.startColumn = lexer->tokenStartColumn();
     return loc;
 }
 
 AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
 {
-    QVarLengthArray<NameId *, 4> nameIds;
+    QVarLengthArray<QStringRef, 4> nameIds;
     QVarLengthArray<AST::SourceLocation, 4> locations;
 
     AST::ExpressionNode *it = expr;
@@ -118,12 +122,12 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
     }
 
     if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) {
-        AST::UiQualifiedId *q = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), idExpr->name);
+        AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name);
         q->identifierToken = idExpr->identifierToken;
 
         AST::UiQualifiedId *currentId = q;
         for (int i = nameIds.size() - 1; i != -1; --i) {
-            currentId = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), currentId, nameIds[i]);
+            currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]);
             currentId->identifierToken = locations[i];
         }
 
@@ -159,11 +163,13 @@ bool Parser::parse(int startToken)
 
             if (first_token == last_token) {
                 yytoken = lexer->lex();
-                yylval = lexer->dval();
+                yylval = lexer->tokenValue();
+                yytokenspell = lexer->tokenSpell();
                 yylloc = location(lexer);
             } else {
                 yytoken = first_token->token;
                 yylval = first_token->dval;
+                yytokenspell = first_token->spell;
                 yylloc = first_token->loc;
                 ++first_token;
             }
@@ -174,6 +180,7 @@ bool Parser::parse(int startToken)
             if (action != ACCEPT_STATE) {
                 yytoken = -1;
                 sym(1).dval = yylval;
+                stringRef(1) = yytokenspell;
                 loc(1) = yylloc;
             } else {
               --tos;
@@ -216,7 +223,7 @@ case 5: {
 } break;
 
 case 6: {
-  sym(1).UiProgram = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiImportList,
+  sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiImportList,
         sym(2).UiObjectMemberList->finish());
 } break;
 
@@ -225,12 +232,11 @@ case 8: {
 } break;
 
 case 9: {
-    sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(), sym(1).UiImport);
+    sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImport);
 } break;
 
 case 10: {
-    sym(1).Node = makeAstNode<AST::UiImportList> (driver->nodePool(),
-        sym(1).UiImportList, sym(2).UiImport);
+    sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImportList, sym(2).UiImport);
 } break;
 
 case 13: {
@@ -246,14 +252,14 @@ case 17: {
     sym(1).UiImport->versionToken = loc(2);
     sym(1).UiImport->asToken = loc(3);
     sym(1).UiImport->importIdToken = loc(4);
-    sym(1).UiImport->importId = sym(4).sval;
+    sym(1).UiImport->importId = stringRef(4);
     sym(1).UiImport->semicolonToken = loc(5);
 } break;
 
 case 19: {
     sym(1).UiImport->asToken = loc(2);
     sym(1).UiImport->importIdToken = loc(3);
-    sym(1).UiImport->importId = sym(3).sval;
+    sym(1).UiImport->importId = stringRef(3);
     sym(1).UiImport->semicolonToken = loc(4);
 } break;
 
@@ -261,10 +267,10 @@ case 20: {
     AST::UiImport *node = 0;
 
     if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
-        node = makeAstNode<AST::UiImport>(driver->nodePool(), importIdLiteral->value);
+        node = new (pool) AST::UiImport(importIdLiteral->value);
         node->fileNameToken = loc(2);
     } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
-        node = makeAstNode<AST::UiImport>(driver->nodePool(), qualifiedId);
+        node = new (pool) AST::UiImport(qualifiedId);
         node->fileNameToken = loc(2);
     }
 
@@ -285,52 +291,52 @@ case 21: {
 } break;
 
 case 22: {
-    sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
 } break;
 
 case 23: {
-    sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
 } break;
 
 case 24: {
-    AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(),
+    AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
         sym(1).UiObjectMemberList, sym(2).UiObjectMember);
     sym(1).Node = node;
 } break;
 
 case 25: {
-    sym(1).Node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(), sym(1).UiObjectMember);
+    sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
 } break;
 
 case 26: {
-    AST::UiArrayMemberList *node = makeAstNode<AST::UiArrayMemberList> (driver->nodePool(),
+    AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
         sym(1).UiArrayMemberList, sym(3).UiObjectMember);
     node->commaToken = loc(2);
     sym(1).Node = node;
 } break;
 
 case 27: {
-    AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), (AST::UiObjectMemberList*)0);
+    AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
     node->lbraceToken = loc(1);
     node->rbraceToken = loc(2);
     sym(1).Node = node;
 }   break;
 
 case 28: {
-    AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish());
+    AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
     node->lbraceToken = loc(1);
     node->rbraceToken = loc(3);
     sym(1).Node = node;
 }   break;
 
 case 29: {
-    AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).UiQualifiedId,
+    AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
         sym(2).UiObjectInitializer);
     sym(1).Node = node;
 }   break;
 
 case 31: {
-    AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+    AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
         sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
     node->colonToken = loc(2);
     node->lbracketToken = loc(3);
@@ -339,14 +345,14 @@ case 31: {
 }   break;
 
 case 32: {
-    AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
       sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
     node->colonToken = loc(2);
     sym(1).Node = node;
 } break;
 
 case 33: {
-    AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
       sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
     node->colonToken = loc(2);
     node->hasOnToken = true;
@@ -355,19 +361,12 @@ case 33: {
 
 case 38:
 {
-    AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(),
+    AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
         sym(1).UiQualifiedId, sym(3).Statement);
     node->colonToken = loc(2);
     sym(1).Node = node;
 }   break;
 
-case 39:
-
-case 40: {
-    sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-    break;
-}
-
 case 42: {
   sym(1).Node = 0;
 } break;
@@ -377,20 +376,20 @@ case 43: {
 } break;
 
 case 44: {
-  AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).sval, sym(2).sval);
+  AST::UiParameterList *node = new (pool) AST::UiParameterList(stringRef(1), stringRef(2));
   node->identifierToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 45: {
-  AST::UiParameterList *node = makeAstNode<AST::UiParameterList> (driver->nodePool(), sym(1).UiParameterList, sym(3).sval, sym(4).sval);
+  AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, stringRef(3), stringRef(4));
   node->commaToken = loc(2);
   node->identifierToken = loc(4);
   sym(1).Node = node;
 } break;
 
 case 47: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
     node->type = AST::UiPublicMember::Signal;
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -401,7 +400,7 @@ case 47: {
 }   break;
 
 case 49: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), (NameId *)0, sym(2).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(QStringRef(), stringRef(2));
     node->type = AST::UiPublicMember::Signal;
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -411,8 +410,8 @@ case 49: {
 }   break;
 
 case 51: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
-    node->typeModifier = sym(2).sval;
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+    node->typeModifier = stringRef(2);
     node->propertyToken = loc(1);
     node->typeModifierToken = loc(2);
     node->typeToken = loc(4);
@@ -422,7 +421,7 @@ case 51: {
 }   break;
 
 case 53: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
     node->identifierToken = loc(3);
@@ -431,7 +430,7 @@ case 53: {
 }   break;
 
 case 55: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
     node->isDefaultMember = true;
     node->defaultToken = loc(1);
     node->propertyToken = loc(2);
@@ -442,7 +441,7 @@ case 55: {
 }   break;
 
 case 56: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3),
         sym(5).Statement);
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
@@ -452,7 +451,7 @@ case 56: {
 }   break;
 
 case 57: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
         sym(6).Statement);
     node->isReadonlyMember = true;
     node->readonlyToken = loc(1);
@@ -464,7 +463,7 @@ case 57: {
 }   break;
 
 case 58: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(3).sval, sym(4).sval,
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4),
         sym(6).Statement);
     node->isDefaultMember = true;
     node->defaultToken = loc(1);
@@ -476,19 +475,19 @@ case 58: {
 }   break;
 
 case 59: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(4).sval, sym(6).sval);
-    node->typeModifier = sym(2).sval;
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(4), stringRef(6));
+    node->typeModifier = stringRef(2);
     node->propertyToken = loc(1);
     node->typeModifierToken = loc(2);
     node->typeToken = loc(4);
     node->identifierToken = loc(6);
     node->semicolonToken = loc(7); // insert a fake ';' before ':'
 
-    AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(6).sval);
+    AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
     propertyName->identifierToken = loc(6);
     propertyName->next = 0;
 
-    AST::UiArrayBinding *binding = makeAstNode<AST::UiArrayBinding> (driver->nodePool(),
+    AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
         propertyName, sym(9).UiArrayMemberList->finish());
     binding->colonToken = loc(7);
     binding->lbracketToken = loc(8);
@@ -500,17 +499,17 @@ case 59: {
 }   break;
 
 case 60: {
-    AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval);
+    AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(2), stringRef(3));
     node->propertyToken = loc(1);
     node->typeToken = loc(2);
     node->identifierToken = loc(3);
     node->semicolonToken = loc(4); // insert a fake ';' before ':'
 
-    AST::UiQualifiedId *propertyName = makeAstNode<AST::UiQualifiedId>(driver->nodePool(), sym(3).sval);
+    AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
     propertyName->identifierToken = loc(3);
     propertyName->next = 0;
 
-    AST::UiObjectBinding *binding = makeAstNode<AST::UiObjectBinding> (driver->nodePool(),
+    AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
       propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
     binding->colonToken = loc(4);
 
@@ -520,75 +519,51 @@ case 60: {
 }   break;
 
 case 61: {
-    sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+    sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
 }   break;
 
 case 62: {
-    sym(1).Node = makeAstNode<AST::UiSourceElement>(driver->nodePool(), sym(1).Node);
+    sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
 }   break;
 
-case 64: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_PROPERTY]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-
-case 65: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_SIGNAL]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-
-case 66: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_READONLY]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-
-case 67: {
-    QString s = QLatin1String(QmlJSGrammar::spell[T_ON]);
-    sym(1).sval = driver->intern(s.constData(), s.length());
-    break;
-}
-
 case 68: {
-  AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool());
+  AST::ThisExpression *node = new (pool) AST::ThisExpression();
   node->thisToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 69: {
-  AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 70: {
-  AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool());
+  AST::NullExpression *node = new (pool) AST::NullExpression();
   node->nullToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 71: {
-  AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool());
+  AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
   node->trueToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 72: {
-  AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool());
+  AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
   node->falseToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 73: {
-  AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval);
+  AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
 case 74:
 case 75: {
-  AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval);
+  AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -602,7 +577,8 @@ case 76: {
 
   loc(1).length = lexer->tokenLength();
 
-  AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+  AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+    driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -616,34 +592,35 @@ case 77: {
 
   loc(1).length = lexer->tokenLength();
 
-  AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags);
+  AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
+    driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
   node->literalToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 78: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), (AST::Elision *) 0);
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 79: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision->finish());
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 80: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ());
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
   node->lbracketToken = loc(1);
   node->rbracketToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 81: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
     (AST::Elision *) 0);
   node->lbracketToken = loc(1);
   node->commaToken = loc(3);
@@ -652,7 +629,7 @@ case 81: {
 } break;
 
 case 82: {
-  AST::ArrayLiteral *node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (),
+  AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
     sym(4).Elision->finish());
   node->lbracketToken = loc(1);
   node->commaToken = loc(3);
@@ -663,17 +640,17 @@ case 82: {
 case 83: {
   AST::ObjectLiteral *node = 0;
   if (sym(2).Node)
-    node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+    node = new (pool) AST::ObjectLiteral(
         sym(2).PropertyNameAndValueList->finish ());
   else
-    node = makeAstNode<AST::ObjectLiteral> (driver->nodePool());
+    node = new (pool) AST::ObjectLiteral();
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 84: {
-  AST::ObjectLiteral *node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(),
+  AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
     sym(2).PropertyNameAndValueList->finish ());
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(4);
@@ -681,7 +658,7 @@ case 84: {
 } break;
 
 case 85: {
-  AST::NestedExpression *node = makeAstNode<AST::NestedExpression>(driver->nodePool(), sym(2).Expression);
+  AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
   node->lparenToken = loc(1);
   node->rparenToken = loc(3);
   sym(1).Node = node;
@@ -708,48 +685,48 @@ case 86: {
 } break;
 
 case 87: {
-  sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), (AST::Elision *) 0, sym(1).Expression);
+  sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
 } break;
 
 case 88: {
-  sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision->finish(), sym(2).Expression);
+  sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
 } break;
 
 case 89: {
-  AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList,
+  AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
     (AST::Elision *) 0, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 90: {
-  AST::ElementList *node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision->finish(),
+  AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
     sym(4).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 91: {
-  AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool());
+  AST::Elision *node = new (pool) AST::Elision();
   node->commaToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 92: {
-  AST::Elision *node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision);
+  AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 93: {
-  AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+  AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
       sym(1).PropertyName, sym(3).Expression);
   node->colonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 94: {
-  AST::PropertyNameAndValueList *node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(),
+  AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
       sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
   node->commaToken = loc(2);
   node->colonToken = loc(4);
@@ -757,116 +734,51 @@ case 94: {
 } break;
 
 case 95: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 case 96:
 case 97: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()));
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 98: {
-  AST::StringLiteralPropertyName *node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 99: {
-  AST::NumericLiteralPropertyName *node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval);
+  AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 100: {
-  AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval);
+  AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
   node->propertyNameToken = loc(1);
   sym(1).Node = node;
 } break;
 
-case 101:
-
-case 102:
-
-case 103:
-
-case 104:
-
-case 105:
-
-case 106:
-
-case 107:
-
-case 108:
-
-case 109:
-
-case 110:
-
-case 111:
-
-case 112:
-
-case 113:
-
-case 114:
-
-case 115:
-
-case 116:
-
-case 117:
-
-case 118:
-
-case 119:
-
-case 120:
-
-case 121:
-
-case 122:
-
-case 123:
-
-case 124:
-
-case 125:
-
-case 126:
-
-case 127:
-
-case 128:
-
-case 129:
-
-case 130:
-
-case 131:
-{
-  sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount());
-} break;
-
 case 136: {
-  AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
   node->lbracketToken = loc(2);
   node->rbracketToken = loc(4);
   sym(1).Node = node;
 } break;
 
 case 137: {
-  AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+  AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
   node->dotToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 138: {
-  AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList);
+  AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
   node->newToken = loc(1);
   node->lparenToken = loc(3);
   node->rparenToken = loc(5);
@@ -874,34 +786,34 @@ case 138: {
 } break;
 
 case 140: {
-  AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression);
+  AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
   node->newToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 141: {
-  AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+  AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
   sym(1).Node = node;
 } break;
 
 case 142: {
-  AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList);
+  AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
   sym(1).Node = node;
 } break;
 
 case 143: {
-  AST::ArrayMemberExpression *node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
   node->lbracketToken = loc(2);
   node->rbracketToken = loc(4);
   sym(1).Node = node;
 } break;
 
 case 144: {
-  AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval);
+  AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
   node->dotToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
@@ -916,342 +828,342 @@ case 146: {
 } break;
 
 case 147: {
-  sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression);
+  sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
 } break;
 
 case 148: {
-  AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression);
+  AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 152: {
-  AST::PostIncrementExpression *node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression);
+  AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
   node->incrementToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 153: {
-  AST::PostDecrementExpression *node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression);
+  AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
   node->decrementToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 155: {
-  AST::DeleteExpression *node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression);
+  AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
   node->deleteToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 156: {
-  AST::VoidExpression *node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression);
+  AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
   node->voidToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 157: {
-  AST::TypeOfExpression *node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression);
+  AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
   node->typeofToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 158: {
-  AST::PreIncrementExpression *node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression);
+  AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
   node->incrementToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 159: {
-  AST::PreDecrementExpression *node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression);
+  AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
   node->decrementToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 160: {
-  AST::UnaryPlusExpression *node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression);
+  AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
   node->plusToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 161: {
-  AST::UnaryMinusExpression *node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression);
+  AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
   node->minusToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 162: {
-  AST::TildeExpression *node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression);
+  AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
   node->tildeToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 163: {
-  AST::NotExpression *node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression);
+  AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
   node->notToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 165: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Mul, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 166: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Div, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 167: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Mod, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 169: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Add, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 170: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Sub, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 172: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::LShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 173: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::RShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 174: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::URShift, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 176: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Lt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 177: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Gt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 178: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Le, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 179: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Ge, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 180: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::InstanceOf, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 181: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::In, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 183: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Lt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 184: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Gt, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 185: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Le, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 186: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
    QSOperator::Ge, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 187: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::InstanceOf, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 189: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Equal, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 190: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::NotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 191: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 192: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictNotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 194: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Equal, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 195: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::NotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 196: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 197: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::StrictNotEqual, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 199: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitAnd, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 201: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitAnd, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 203: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitXor, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 205: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitXor, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 207: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitOr, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 209: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::BitOr, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 211: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::And, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 213: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::And, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 215: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Or, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 217: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     QSOperator::Or, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 219: {
-  AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+  AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
     sym(3).Expression, sym(5).Expression);
   node->questionToken = loc(2);
   node->colonToken = loc(4);
@@ -1259,7 +1171,7 @@ case 219: {
 } break;
 
 case 221: {
-  AST::ConditionalExpression *node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression,
+  AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
     sym(3).Expression, sym(5).Expression);
   node->questionToken = loc(2);
   node->colonToken = loc(4);
@@ -1267,14 +1179,14 @@ case 221: {
 } break;
 
 case 223: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     sym(2).ival, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 225: {
-  AST::BinaryExpression *node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression,
+  AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
     sym(2).ival, sym(3).Expression);
   node->operatorToken = loc(2);
   sym(1).Node = node;
@@ -1329,7 +1241,7 @@ case 237: {
 } break;
 
 case 239: {
-  AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1339,7 +1251,7 @@ case 240: {
 } break;
 
 case 243: {
-  AST::Expression *node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression);
+  AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
@@ -1349,18 +1261,18 @@ case 244: {
 } break;
 
 case 261: {
-  AST::Block *node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList);
+  AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 262: {
-  sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement);
+  sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
 } break;
 
 case 263: {
-  sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement);
+  sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
 } break;
 
 case 264: {
@@ -1372,7 +1284,7 @@ case 265: {
 } break;
 
 case 267: {
-  AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(),
+  AST::VariableStatement *node = new (pool) AST::VariableStatement(
      sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
   node->declarationKindToken = loc(1);
   node->semicolonToken = loc(3);
@@ -1388,32 +1300,32 @@ case 269: {
 } break;
 
 case 270: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
 } break;
 
 case 271: {
-  AST::VariableDeclarationList *node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(),
+  AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
     sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
   node->commaToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 272: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
 } break;
 
 case 273: {
-  sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
+  sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
 } break;
 
 case 274: {
-  AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+  AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 275: {
-  AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression);
+  AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
@@ -1437,19 +1349,19 @@ case 280: {
 } break;
 
 case 282: {
-  AST::EmptyStatement *node = makeAstNode<AST::EmptyStatement> (driver->nodePool());
+  AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
   node->semicolonToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 284: {
-  AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression);
+  AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 285: {
-  AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement);
+  AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
   node->ifToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -1458,7 +1370,7 @@ case 285: {
 } break;
 
 case 286: {
-  AST::IfStatement *node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
   node->ifToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -1466,7 +1378,7 @@ case 286: {
 } break;
 
 case 288: {
-  AST::DoWhileStatement *node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression);
+  AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
   node->doToken = loc(1);
   node->whileToken = loc(3);
   node->lparenToken = loc(4);
@@ -1476,7 +1388,7 @@ case 288: {
 } break;
 
 case 289: {
-  AST::WhileStatement *node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
   node->whileToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -1484,7 +1396,7 @@ case 289: {
 } break;
 
 case 290: {
-  AST::ForStatement *node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression,
+  AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
     sym(5).Expression, sym(7).Expression, sym(9).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -1495,7 +1407,7 @@ case 290: {
 } break;
 
 case 291: {
-  AST::LocalForStatement *node = makeAstNode<AST::LocalForStatement> (driver->nodePool(),
+  AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
      sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
      sym(8).Expression, sym(10).Statement);
   node->forToken = loc(1);
@@ -1508,7 +1420,7 @@ case 291: {
 } break;
 
 case 292: {
-  AST:: ForEachStatement *node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression,
+  AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
     sym(5).Expression, sym(7).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -1518,7 +1430,7 @@ case 292: {
 } break;
 
 case 293: {
-  AST::LocalForEachStatement *node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(),
+  AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
     sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
   node->forToken = loc(1);
   node->lparenToken = loc(2);
@@ -1529,14 +1441,14 @@ case 293: {
 } break;
 
 case 295: {
-  AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool());
+  AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
   node->continueToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 297: {
-  AST::ContinueStatement *node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval);
+  AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
   node->continueToken = loc(1);
   node->identifierToken = loc(2);
   node->semicolonToken = loc(3);
@@ -1544,14 +1456,14 @@ case 297: {
 } break;
 
 case 299: {
-  AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool());
+  AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
   node->breakToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 301: {
-  AST::BreakStatement *node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval);
+  AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
   node->breakToken = loc(1);
   node->identifierToken = loc(2);
   node->semicolonToken = loc(3);
@@ -1559,14 +1471,14 @@ case 301: {
 } break;
 
 case 303: {
-  AST::ReturnStatement *node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression);
+  AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
   node->returnToken = loc(1);
   node->semicolonToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 304: {
-  AST::WithStatement *node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement);
+  AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
   node->withToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -1574,7 +1486,7 @@ case 304: {
 } break;
 
 case 305: {
-  AST::SwitchStatement *node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock);
+  AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
   node->switchToken = loc(1);
   node->lparenToken = loc(2);
   node->rparenToken = loc(4);
@@ -1582,25 +1494,25 @@ case 305: {
 } break;
 
 case 306: {
-  AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses);
+  AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 307: {
-  AST::CaseBlock *node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
+  AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
   node->lbraceToken = loc(1);
   node->rbraceToken = loc(5);
   sym(1).Node = node;
 } break;
 
 case 308: {
-  sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause);
+  sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
 } break;
 
 case 309: {
-  sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause);
+  sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
 } break;
 
 case 310: {
@@ -1612,60 +1524,60 @@ case 311: {
 } break;
 
 case 312: {
-  AST::CaseClause *node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList);
+  AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
   node->caseToken = loc(1);
   node->colonToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 313: {
-  AST::DefaultClause *node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList);
+  AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
   node->defaultToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
 } break;
 case 314:
 case 315: {
-  AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), driver->intern(lexer->characterBuffer(), lexer->characterCount()), sym(3).Statement);
+  AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
   node->identifierToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 316: {
-  AST::LabelledStatement *node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement);
+  AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
   node->identifierToken = loc(1);
   node->colonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 318: {
-  AST::ThrowStatement *node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression);
+  AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
   node->throwToken = loc(1);
   node->semicolonToken = loc(3);
   sym(1).Node = node;
 } break;
 
 case 319: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 320: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 321: {
-  AST::TryStatement *node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally);
+  AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
   node->tryToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 322: {
-  AST::Catch *node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Block);
+  AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
   node->catchToken = loc(1);
   node->lparenToken = loc(2);
   node->identifierToken = loc(3);
@@ -1674,20 +1586,20 @@ case 322: {
 } break;
 
 case 323: {
-  AST::Finally *node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Block);
+  AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
   node->finallyToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 325: {
-  AST::DebuggerStatement *node = makeAstNode<AST::DebuggerStatement> (driver->nodePool());
+  AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
   node->debuggerToken = loc(1);
   node->semicolonToken = loc(2);
   sym(1).Node = node;
 } break;
 
 case 326: {
-  AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+  AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
   node->functionToken = loc(1);
   node->identifierToken = loc(2);
   node->lparenToken = loc(3);
@@ -1698,9 +1610,9 @@ case 326: {
 } break;
 
 case 327: {
-  AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody);
+  AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
   node->functionToken = loc(1);
-  if (sym(2).sval)
+  if (! stringRef(2).isNull())
       node->identifierToken = loc(2);
   node->lparenToken = loc(3);
   node->rparenToken = loc(5);
@@ -1710,13 +1622,13 @@ case 327: {
 } break;
 
 case 328: {
-  AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval);
+  AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
   node->identifierToken = loc(1);
   sym(1).Node = node;
 } break;
 
 case 329: {
-  AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval);
+  AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
   node->commaToken = loc(2);
   node->identifierToken = loc(3);
   sym(1).Node = node;
@@ -1735,31 +1647,31 @@ case 332: {
 } break;
 
 case 334: {
-  sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ());
+  sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
 } break;
 
 case 335: {
-  sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ());
+  sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
 } break;
 
 case 336: {
-  sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement);
+  sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
 } break;
 
 case 337: {
-  sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement);
+  sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
 } break;
 
 case 338: {
-  sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement);
+  sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
 } break;
 
 case 339: {
-  sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration);
+  sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
 } break;
 
 case 340: {
-  sym(1).sval = 0;
+  stringRef(1) = QStringRef();
 } break;
 
 case 342: {
@@ -1779,6 +1691,7 @@ case 342: {
             SavedToken &tk = token_buffer[0];
             tk.token = yytoken;
             tk.dval = yylval;
+            tk.spell = yytokenspell;
             tk.loc = yylloc;
 
             yylloc = yyprevlloc;
@@ -1804,11 +1717,13 @@ case 342: {
 
         token_buffer[0].token = yytoken;
         token_buffer[0].dval = yylval;
+        token_buffer[0].spell = yytokenspell;
         token_buffer[0].loc = yylloc;
 
-        token_buffer[1].token = yytoken = lexer->lex();
-        token_buffer[1].dval  = yylval  = lexer->dval();
-        token_buffer[1].loc   = yylloc  = location(lexer);
+        token_buffer[1].token = yytoken       = lexer->lex();
+        token_buffer[1].dval  = yylval        = lexer->tokenValue();
+        token_buffer[1].spell = yytokenspell  = lexer->tokenSpell();
+        token_buffer[1].loc   = yylloc        = location(lexer);
 
         if (t_action(errorState, yytoken)) {
             QString msg;
index a59790b..7100c18 100644 (file)
@@ -63,7 +63,6 @@ QT_QML_BEGIN_NAMESPACE
 namespace QmlJS {
 
 class Engine;
-class NameId;
 
 class QML_PARSER_EXPORT Parser: protected QmlJSGrammar
 {
@@ -71,7 +70,6 @@ public:
     union Value {
       int ival;
       double dval;
-      NameId *sval;
       AST::ArgumentList *ArgumentList;
       AST::CaseBlock *CaseBlock;
       AST::CaseClause *CaseClause;
@@ -187,6 +185,9 @@ protected:
     inline Value &sym(int index)
     { return sym_stack [tos + index - 1]; }
 
+    inline QStringRef &stringRef(int index)
+    { return string_stack [tos + index - 1]; }
+
     inline AST::SourceLocation &loc(int index)
     { return location_stack [tos + index - 1]; }
 
@@ -194,11 +195,13 @@ protected:
 
 protected:
     Engine *driver;
+    MemoryPool *pool;
     int tos;
     int stack_size;
     Value *sym_stack;
     int *state_stack;
     AST::SourceLocation *location_stack;
+    QStringRef *string_stack;
 
     AST::Node *program;
 
@@ -209,9 +212,11 @@ protected:
        int token;
        double dval;
        AST::SourceLocation loc;
+       QStringRef spell;
     };
 
     double yylval;
+    QStringRef yytokenspell;
     AST::SourceLocation yylloc;
     AST::SourceLocation yyprevlloc;
 
diff --git a/src/libs/qmljs/parser/qmlutils_p.h b/src/libs/qmljs/parser/qmlutils_p.h
new file mode 100644 (file)
index 0000000..44a08b7
--- /dev/null
@@ -0,0 +1,82 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** 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.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+#ifndef QMLUTIL_P_H
+#define QMLUTIL_P_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace QmlUtils {
+
+inline bool isUpper(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return ((c >= 'A' && c <= 'Z') || (c > 127 && QChar::category(c) == QChar::Letter_Uppercase));
+}
+
+inline bool isLower(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return ((c >= 'a' && c <= 'z') || (c > 127 && QChar::category(c) == QChar::Letter_Lowercase));
+}
+
+inline bool isLetter(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c > 127 && qc.isLetter()));
+}
+
+inline bool isDigit(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return ((c >= '0' && c <= '9') || (c > 127 && qc.isDigit()));
+}
+
+inline bool isLetterOrNumber(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c > 127 && qc.isLetterOrNumber()));
+}
+
+inline bool isSpace(const QChar &qc)
+{
+    ushort c = qc.unicode();
+    return (c == 0x20 || (c >= 0x09 && c <= 0x0D) || c == 0x85 || (c > 127 && qc.isSpace()));
+}
+
+} // namespace Qml
+
+QT_END_NAMESPACE
+
+#endif // QMLUTIL_P_H