diff options
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 97 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 38 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtimecodegen.cpp | 2 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 4135 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 62 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 312 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastfwd_p.h | 10 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastvisitor_p.h | 22 | ||||
-rw-r--r-- | src/qml/parser/qqmljskeywords_p.h | 11 | ||||
-rw-r--r-- | src/qml/parser/qqmljslexer_p.h | 5 | ||||
-rw-r--r-- | tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp | 10 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 23 | ||||
-rw-r--r-- | tests/auto/qml/qmlmin/tst_qmlmin.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/data/property.4.errors.txt | 2 | ||||
-rw-r--r-- | tools/qmlmin/main.cpp | 104 |
20 files changed, 2570 insertions, 2304 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 4774095a38..9de27a2588 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1845,10 +1845,10 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil else name = QStringLiteral("%qml-expression-entry"); - QQmlJS::AST::SourceElements *body; - if (function) - body = function->body ? function->body->elements : nullptr; - else { + QQmlJS::AST::StatementList *body; + if (function) { + body = function->body; + } else { // Synthesize source elements. QQmlJS::MemoryPool *pool = jsEngine->pool(); @@ -1858,8 +1858,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil QQmlJS::AST::ExpressionNode *expr = node->expressionCast(); stmt = new (pool) QQmlJS::AST::ExpressionStatement(expr); } - QQmlJS::AST::SourceElement *element = new (pool) QQmlJS::AST::StatementSourceElement(stmt); - body = new (pool) QQmlJS::AST::SourceElements(element); + body = new (pool) QQmlJS::AST::StatementList(stmt); body = body->finish(); } @@ -1873,7 +1872,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil return runtimeFunctionIndices; } -int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::SourceElements *body) +int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::StatementList *body) { int qmlContextTemp = -1; int importedScriptsTemp = -1; diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 9845577e11..14f59dd7e8 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -621,7 +621,7 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen int defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, - AST::SourceElements *body) override; + AST::StatementList *body) override; protected: void beginFunctionBodyHook() override; diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 7c8bf05ce5..34c2c3ffc9 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -488,11 +488,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio } if (!functionDeclaration) { QQmlJS::AST::Statement *statement = static_cast<QQmlJS::AST::Statement*>(foe->node); - QQmlJS::AST::SourceElement *sourceElement = new (pool) QQmlJS::AST::StatementSourceElement(statement); - QQmlJS::AST::SourceElements *elements = new (pool) QQmlJS::AST::SourceElements(sourceElement); - elements = elements->finish(); - - QQmlJS::AST::FunctionBody *body = new (pool) QQmlJS::AST::FunctionBody(elements); + QQmlJS::AST::StatementList *body = new (pool) QQmlJS::AST::StatementList(statement); + body = body->finish(); functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(compiler->newStringRef(stringAt(binding->propertyNameIndex)), paramList, body); functionDeclaration->lbraceToken = functionDeclaration->functionToken diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 01ca3a6a5e..6c57cdba9e 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -125,7 +125,7 @@ void Codegen::generateFromProgram(const QString &fileName, if (hasError) return; - defineFunction(QStringLiteral("%entry"), node, nullptr, node->elements); + defineFunction(QStringLiteral("%entry"), node, nullptr, node->statements); } void Codegen::enterContext(Node *node) @@ -342,45 +342,10 @@ Codegen::Reference Codegen::expression(ExpressionNode *ast) return r.result(); } -Codegen::Result Codegen::sourceElement(SourceElement *ast) -{ - Result r(nx); - if (ast) { - qSwap(_expr, r); - accept(ast); - qSwap(_expr, r); - } - return r; -} - -void Codegen::functionBody(FunctionBody *ast) -{ - if (ast) - sourceElements(ast->elements); -} - void Codegen::program(Program *ast) { if (ast) { - sourceElements(ast->elements); - } -} - -void Codegen::sourceElements(SourceElements *ast) -{ - bool _requiresReturnValue = false; - qSwap(_requiresReturnValue, requiresReturnValue); - for (SourceElements *it = ast; it; it = it->next) { - if (!it->next) - qSwap(_requiresReturnValue, requiresReturnValue); - sourceElement(it->element); - if (hasError) - return; - if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(it->element)) { - if (AST::cast<ThrowStatement *>(sse->statement) || - AST::cast<ReturnStatement *>(sse->statement)) - return; - } + statementList(ast->statements); } } @@ -394,7 +359,10 @@ void Codegen::statementList(StatementList *ast) it->next->statement->kind == Statement::Kind_ContinueStatement || it->next->statement->kind == Statement::Kind_ReturnStatement) requiresReturnValue = _requiresReturnValue; - statement(it->statement); + if (FunctionDeclaration *decl = cast<FunctionDeclaration *>(it->statement)) + statement(decl); + else + statement(static_cast<Statement *>(it->statement)); requiresReturnValue = false; if (it->statement->kind == Statement::Kind_ThrowStatement || it->statement->kind == Statement::Kind_BreakStatement || @@ -551,19 +519,13 @@ bool Codegen::visit(FormalParameterList *) return false; } -bool Codegen::visit(FunctionBody *) -{ - Q_UNREACHABLE(); - return false; -} - bool Codegen::visit(Program *) { Q_UNREACHABLE(); return false; } -bool Codegen::visit(PropertyAssignmentList *) +bool Codegen::visit(PropertyDefinitionList *) { Q_UNREACHABLE(); return false; @@ -581,12 +543,6 @@ bool Codegen::visit(PropertyGetterSetter *) return false; } -bool Codegen::visit(SourceElements *) -{ - Q_UNREACHABLE(); - return false; -} - bool Codegen::visit(StatementList *) { Q_UNREACHABLE(); @@ -1672,7 +1628,7 @@ bool Codegen::visit(FunctionExpression *ast) RegisterScope scope(this); - int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr); + int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body); loadClosure(function); _expr.setResult(Reference::fromAccumulator(this)); return false; @@ -1880,7 +1836,7 @@ bool Codegen::visit(ObjectLiteral *ast) RegisterScope scope(this); - for (PropertyAssignmentList *it = ast->properties; it; it = it->next) { + for (PropertyDefinitionList *it = ast->properties; it; it = it->next) { QString name = it->assignment->name->asString(); if (PropertyNameAndValue *nv = AST::cast<AST::PropertyNameAndValue *>(it->assignment)) { Reference value = expression(nv->value); @@ -1896,7 +1852,7 @@ bool Codegen::visit(ObjectLiteral *ast) v.rvalue = value.storeOnStack(); } else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) { - const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : nullptr); + const int function = defineFunction(name, gs, gs->formals, gs->functionBody); ObjectPropertyValue &v = valueMap[name]; if (v.rvalue.isValid() || (gs->type == PropertyGetterSetter::Getter && v.hasGetter()) || @@ -2256,14 +2212,7 @@ static bool endsWithReturn(Node *node) if (AST::cast<ThrowStatement *>(node)) return true; if (Program *p = AST::cast<Program *>(node)) - return endsWithReturn(p->elements); - if (SourceElements *se = AST::cast<SourceElements *>(node)) { - while (se->next) - se = se->next; - return endsWithReturn(se->element); - } - if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(node)) - return endsWithReturn(sse->statement); + return endsWithReturn(p->statements); if (StatementList *sl = AST::cast<StatementList *>(node)) { while (sl->next) sl = sl->next; @@ -2278,7 +2227,7 @@ static bool endsWithReturn(Node *node) int Codegen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, - AST::SourceElements *body) + AST::StatementList *body) { enterContext(ast); @@ -2367,7 +2316,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, for (const Context::Member &member : qAsConst(_context->members)) { if (member.function) { const int function = defineFunction(member.function->name.toString(), member.function, member.function->formals, - member.function->body ? member.function->body->elements : nullptr); + member.function->body); loadClosure(function); if (! _context->parent) { Reference::fromName(this, member.function->name.toString()).storeConsumeAccumulator(); @@ -2416,7 +2365,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, beginFunctionBodyHook(); - sourceElements(body); + statementList(body); if (hasError || !endsWithReturn(body)) { bytecodeGenerator->setLocation(ast->lastSourceLocation()); @@ -2450,24 +2399,6 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast, return leaveContext(); } -bool Codegen::visit(FunctionSourceElement *ast) -{ - if (hasError) - return false; - - statement(ast->declaration); - return false; -} - -bool Codegen::visit(StatementSourceElement *ast) -{ - if (hasError) - return false; - - statement(ast->statement); - return false; -} - bool Codegen::visit(Block *ast) { if (hasError) diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index e708d56478..5ff0aa5c30 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -495,7 +495,7 @@ protected: // Returns index in _module->functions virtual int defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, - AST::SourceElements *body); + AST::StatementList *body); void statement(AST::Statement *ast); void statement(AST::ExpressionNode *ast); @@ -503,13 +503,10 @@ protected: const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition); Reference expression(AST::ExpressionNode *ast); - Result sourceElement(AST::SourceElement *ast); void accept(AST::Node *node); - void functionBody(AST::FunctionBody *ast); void program(AST::Program *ast); - void sourceElements(AST::SourceElements *ast); void statementList(AST::StatementList *ast); void variableDeclaration(AST::VariableDeclaration *ast); void variableDeclarationList(AST::VariableDeclarationList *ast); @@ -537,12 +534,10 @@ protected: bool visit(AST::Elision *ast) override; bool visit(AST::Finally *ast) override; bool visit(AST::FormalParameterList *ast) override; - bool visit(AST::FunctionBody *ast) override; bool visit(AST::Program *ast) override; bool visit(AST::PropertyNameAndValue *ast) override; - bool visit(AST::PropertyAssignmentList *ast) override; + bool visit(AST::PropertyDefinitionList *ast) override; bool visit(AST::PropertyGetterSetter *ast) override; - bool visit(AST::SourceElements *ast) override; bool visit(AST::StatementList *ast) override; bool visit(AST::UiArrayMemberList *ast) override; bool visit(AST::UiImport *ast) override; @@ -593,10 +588,6 @@ protected: bool visit(AST::VoidExpression *ast) override; bool visit(AST::FunctionDeclaration *ast) override; - // source elements - bool visit(AST::FunctionSourceElement *ast) override; - bool visit(AST::StatementSourceElement *ast) override; - // statements bool visit(AST::Block *ast) override; bool visit(AST::BreakStatement *ast) override; diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index c732e60b34..5b7103323e 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -95,25 +95,23 @@ void ScanFunctions::leaveEnvironment() _context = _contextStack.isEmpty() ? 0 : _contextStack.top(); } -void ScanFunctions::checkDirectivePrologue(SourceElements *ast) +void ScanFunctions::checkDirectivePrologue(StatementList *ast) { - for (SourceElements *it = ast; it; it = it->next) { - if (StatementSourceElement *stmt = cast<StatementSourceElement *>(it->element)) { - if (ExpressionStatement *expr = cast<ExpressionStatement *>(stmt->statement)) { - if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) { - // Use the source code, because the StringLiteral's - // value might have escape sequences in it, which is not - // allowed. - if (strLit->literalToken.length < 2) - continue; - QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2); - if (str == QLatin1String("use strict")) { - _context->isStrict = true; - } else { - // TODO: give a warning. - } + for (StatementList *it = ast; it; it = it->next) { + if (ExpressionStatement *expr = cast<ExpressionStatement *>(it->statement)) { + if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) { + // Use the source code, because the StringLiteral's + // value might have escape sequences in it, which is not + // allowed. + if (strLit->literalToken.length < 2) continue; + QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2); + if (str == QLatin1String("use strict")) { + _context->isStrict = true; + } else { + // TODO: give a warning. } + continue; } } @@ -141,7 +139,7 @@ void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc) bool ScanFunctions::visit(Program *ast) { enterEnvironment(ast, defaultProgramMode); - checkDirectivePrologue(ast->elements); + checkDirectivePrologue(ast->statements); return true; } @@ -273,7 +271,7 @@ void ScanFunctions::endVisit(FunctionExpression *) bool ScanFunctions::visit(ObjectLiteral *ast) { int argc = 0; - for (PropertyAssignmentList *it = ast->properties; it; it = it->next) { + for (PropertyDefinitionList *it = ast->properties; it; it = it->next) { QString key = it->assignment->name->asString(); if (QV4::String::toArrayIndex(key) != UINT_MAX) ++argc; @@ -392,7 +390,7 @@ bool ScanFunctions::visit(Block *ast) { return false; } -void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr) +void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, FunctionExpression *expr) { Context *outerContext = _context; enterEnvironment(ast, FunctionCode); @@ -419,7 +417,7 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete _context->formals = formals; if (body && !_context->isStrict) - checkDirectivePrologue(body->elements); + checkDirectivePrologue(body); bool isSimpleParameterList = formals->isSimpleParameterList(); diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index 0767b25094..940bd9f73a 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -95,7 +95,7 @@ protected: using Visitor::visit; using Visitor::endVisit; - void checkDirectivePrologue(AST::SourceElements *ast); + void checkDirectivePrologue(AST::StatementList *ast); void checkName(const QStringRef &name, const AST::SourceLocation &loc); @@ -136,7 +136,7 @@ protected: bool visit(AST::Block *ast) override; protected: - void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr); + void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::StatementList *body, AST::FunctionExpression *expr); void calcEscapingVariables(); // fields: diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp index 8080ef7344..93ca666c53 100644 --- a/src/qml/jsruntime/qv4runtimecodegen.cpp +++ b/src/qml/jsruntime/qv4runtimecodegen.cpp @@ -61,7 +61,7 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName, if (hasError) return; - int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr); + int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body); _module->rootContext = _module->functions.at(index); } diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 0f4b9de477..d49a07a664 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -40,8 +40,7 @@ %parser QQmlJSGrammar %decl qqmljsparser_p.h %impl qqmljsparser.cpp -%expect 5 -%expect-rr 2 +%expect 1 %token T_AND "&" T_AND_AND "&&" T_AND_EQ "&=" %token T_BREAK "break" T_CASE "case" T_CATCH "catch" @@ -64,7 +63,7 @@ %token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%" %token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")" %token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*" -%token T_STAR_EQ "*=" T_STRING_LITERAL "string literal" +%token T_STAR_STAR "**" T_STAR_EQ "*=" T_STRING_LITERAL "string literal" %token T_PROPERTY "property" T_SIGNAL "signal" T_READONLY "readonly" %token T_SWITCH "switch" T_THIS "this" T_THROW "throw" %token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof" @@ -77,22 +76,29 @@ %token T_MULTILINE_STRING_LITERAL "multiline string literal" %token T_COMMENT "comment" %token T_COMPATIBILITY_SEMICOLON +%token T_ARROW "=>" %token T_ENUM "enum" %token T_ELLIPSIS "..." %token T_YIELD "yield" +%token T_SUPER "super" +%token T_CLASS "class" +%token T_EXTENDS "extends" +%token T_STATIC "static" +%token T_EXPORT "export" +%token T_FROM "from" --- template strings -%token T_NO_SUBSTITUTION_TEMPLATE -%token T_TEMPLATE_HEAD -%token T_TEMPLATE_MIDDLE -%token T_TEMPLATE_TAIL +%token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)" +%token T_TEMPLATE_HEAD "(template head)" +%token T_TEMPLATE_MIDDLE "(template middle)" +%token T_TEMPLATE_TAIL "(template tail)" --- context keywords. %token T_PUBLIC "public" %token T_IMPORT "import" %token T_PRAGMA "pragma" %token T_AS "as" -%token T_ON "on" +%token T_OF "of" %token T_GET "get" %token T_SET "set" @@ -103,11 +109,16 @@ %token T_FEED_UI_OBJECT_MEMBER %token T_FEED_JS_STATEMENT %token T_FEED_JS_EXPRESSION -%token T_FEED_JS_SOURCE_ELEMENT -%token T_FEED_JS_PROGRAM +%token T_FEED_JS_SCRIPT +%token T_FEED_JS_MODULE -%nonassoc SHIFT_THERE -%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_YIELD +--- Lookahead handling +%token T_FORCE_DECLARATION "(force decl)" +%token T_FORCE_BLOCK "(force block)" +%token T_FOR_LOOKAHEAD_OK "(for lookahead ok)" + +--%left T_PLUS T_MINUS +%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_YIELD T_OF T_STATIC T_FROM %nonassoc REDUCE_HERE %start TopLevel @@ -261,19 +272,17 @@ public: AST::TemplateLiteral *Template; AST::Finally *Finally; AST::FormalParameterList *FormalParameterList; - AST::FunctionBody *FunctionBody; AST::FunctionDeclaration *FunctionDeclaration; AST::Node *Node; AST::PropertyName *PropertyName; - AST::PropertyAssignment *PropertyAssignment; - AST::PropertyAssignmentList *PropertyAssignmentList; - AST::SourceElement *SourceElement; - AST::SourceElements *SourceElements; + AST::PropertyDefinition *PropertyDefinition; + AST::PropertyDefinitionList *PropertyDefinitionList; AST::Statement *Statement; AST::StatementList *StatementList; AST::Block *Block; AST::VariableDeclaration *VariableDeclaration; AST::VariableDeclarationList *VariableDeclarationList; + AST::BindingPattern *BindingPattern; AST::BindingElement *BindingElement; AST::BindingPropertyList *BindingPropertyList; AST::BindingElementList *BindingElementList; @@ -302,12 +311,13 @@ public: ~Parser(); // parse a UI program - bool parse() { return parse(T_FEED_UI_PROGRAM); } + bool parse() { ++functionNestingLevel; bool r = parse(T_FEED_UI_PROGRAM); --functionNestingLevel; return r; } bool parseStatement() { return parse(T_FEED_JS_STATEMENT); } bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); } - bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); } - bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); } - bool parseProgram() { return parse(T_FEED_JS_PROGRAM); } + bool parseUiObjectMember() { ++functionNestingLevel; bool r = parse(T_FEED_UI_OBJECT_MEMBER); --functionNestingLevel; return r; } + bool parseProgram() { return parse(T_FEED_JS_SCRIPT); } + bool parseScript() { return parse(T_FEED_JS_SCRIPT); } + bool parseModule() { return parse(T_FEED_JS_MODULE); } AST::UiProgram *ast() const { return AST::cast<AST::UiProgram *>(program); } @@ -378,20 +388,27 @@ protected: AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr); + void pushToken(int token); + int lookaheadToken(Lexer *lexer); + + void syntaxError(const AST::SourceLocation &location, const char *message) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location, QLatin1String(message))); + } + protected: Engine *driver; MemoryPool *pool; - int tos; - int stack_size; - Value *sym_stack; - int *state_stack; - AST::SourceLocation *location_stack; - QStringRef *string_stack; + int tos = 0; + int stack_size = 0; + Value *sym_stack = nullptr; + int *state_stack = nullptr; + AST::SourceLocation *location_stack = nullptr; + QStringRef *string_stack = nullptr; - AST::Node *program; + AST::Node *program = nullptr; - // error recovery - enum { TOKEN_BUFFER_SIZE = 3 }; + // error recovery and lookahead handling + enum { TOKEN_BUFFER_SIZE = 5 }; struct SavedToken { int token; @@ -400,14 +417,17 @@ protected: QStringRef spell; }; - double yylval; + int yytoken = -1; + double yylval = 0.; QStringRef yytokenspell; AST::SourceLocation yylloc; AST::SourceLocation yyprevlloc; SavedToken token_buffer[TOKEN_BUFFER_SIZE]; - SavedToken *first_token; - SavedToken *last_token; + SavedToken *first_token = nullptr; + SavedToken *last_token = nullptr; + + int functionNestingLevel = 0; QList<DiagnosticMessage> diagnostic_messages; }; @@ -436,6 +456,8 @@ protected: // qlalr --no-debug --no-lines --qt qqmljs.g // +#define UNIMPLEMENTED syntaxError(loc(1), "Unimplemented"); return false + using namespace QQmlJS; QT_QML_BEGIN_NAMESPACE @@ -455,17 +477,7 @@ void Parser::reallocateStack() 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), - program(0), - yylval(0), - first_token(0), - last_token(0) + pool(engine->pool()) { } @@ -529,17 +541,38 @@ AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode return 0; } +void Parser::pushToken(int token) +{ + last_token->token = yytoken; + last_token->dval = yylval; + last_token->spell = yytokenspell; + last_token->loc = yylloc; + ++last_token; + yytoken = token; +} + +int Parser::lookaheadToken(Lexer *lexer) +{ + if (yytoken < 0) { + yytoken = lexer->lex(); + yylval = lexer->tokenValue(); + yytokenspell = lexer->tokenSpell(); + yylloc = location(lexer); + } + return yytoken; +} + bool Parser::parse(int startToken) { Lexer *lexer = driver->lexer(); bool hadErrors = false; - int yytoken = -1; + yytoken = -1; int action = 0; token_buffer[0].token = startToken; first_token = &token_buffer[0]; - if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) { + if (startToken == T_FEED_JS_SCRIPT && !lexer->qmlMode()) { Directives ignoreDirectives; Directives *directives = driver->directives(); if (!directives) @@ -582,9 +615,15 @@ bool Parser::parse(int startToken) yytokenspell = first_token->spell; yylloc = first_token->loc; ++first_token; + if (first_token == last_token) + first_token = last_token = &token_buffer[0]; } } +#ifdef PARSER_DEBUG + qDebug() << " current token" << yytoken << (yytoken >= 0 ? spell[yytoken] : "(null)"); +#endif + action = t_action(action, yytoken); if (action > 0) { if (action != ACCEPT_STATE) { @@ -600,6 +639,10 @@ bool Parser::parse(int startToken) const int r = -action - 1; tos -= rhs[r]; +#ifdef PARSER_DEBUG + qDebug() << " reducing through rule " << r; +#endif + switch (r) { ./ @@ -607,674 +650,733 @@ bool Parser::parse(int startToken) -- Declarative UI -------------------------------------------------------------------------------------------------------- -TopLevel: T_FEED_UI_PROGRAM UiProgram ; +TopLevel: T_FEED_UI_PROGRAM UiProgram; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_STATEMENT Statement ; +TopLevel: T_FEED_JS_STATEMENT Statement; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_EXPRESSION Expression ; +TopLevel: T_FEED_JS_EXPRESSION Expression; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_SOURCE_ELEMENT SourceElement ; +TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember ; +TopLevel: T_FEED_JS_SCRIPT Script; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_PROGRAM Program ; +TopLevel: T_FEED_JS_MODULE Module; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ + UiProgram: UiHeaderItemListOpt UiRootMember; /. -case $rule_number: { - sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, - sym(2).UiObjectMemberList->finish()); -} break; + case $rule_number: { + sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, sym(2).UiObjectMemberList->finish()); + } break; ./ -UiHeaderItemListOpt: Empty ; -UiHeaderItemListOpt: UiHeaderItemList ; +UiHeaderItemListOpt: Empty; +UiHeaderItemListOpt: UiHeaderItemList; /. -case $rule_number: { - sym(1).Node = sym(1).UiHeaderItemList->finish(); -} break; + case $rule_number: { + sym(1).Node = sym(1).UiHeaderItemList->finish(); + } break; ./ -UiHeaderItemList: UiPragma ; +UiHeaderItemList: UiPragma; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma); + } break; ./ -UiHeaderItemList: UiImport ; +UiHeaderItemList: UiImport; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport); + } break; ./ -UiHeaderItemList: UiHeaderItemList UiPragma ; +UiHeaderItemList: UiHeaderItemList UiPragma; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma); + } break; ./ -UiHeaderItemList: UiHeaderItemList UiImport ; +UiHeaderItemList: UiHeaderItemList UiImport; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport); + } break; ./ -PragmaId: MemberExpression ; +PragmaId: MemberExpression; -ImportId: MemberExpression ; +ImportId: MemberExpression; -UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON ; -UiPragma: UiPragmaHead T_SEMICOLON ; +UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON; +UiPragma: UiPragmaHead T_SEMICOLON; /. -case $rule_number: { - sym(1).UiPragma->semicolonToken = loc(2); -} break; + case $rule_number: { + sym(1).UiPragma->semicolonToken = loc(2); + } break; ./ -UiImport: UiImportHead T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_SEMICOLON ; +UiImport: UiImportHead T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->semicolonToken = loc(2); -} break; + case $rule_number: { + sym(1).UiImport->semicolonToken = loc(2); + } break; ./ -UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON ; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->versionToken = loc(2); - sym(1).UiImport->semicolonToken = loc(3); -} break; + case $rule_number: { + sym(1).UiImport->versionToken = loc(2); + sym(1).UiImport->semicolonToken = loc(3); + } break; ./ -UiImport: UiImportHead T_NUMERIC_LITERAL T_AS IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_NUMERIC_LITERAL T_AS IdentifierReference T_SEMICOLON ; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_SEMICOLON; /. -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 = stringRef(4); - sym(1).UiImport->semicolonToken = loc(5); -} break; + 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 = stringRef(4); + sym(1).UiImport->semicolonToken = loc(5); + } break; ./ -UiImport: UiImportHead T_AS IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_AS IdentifierReference T_SEMICOLON ; +UiImport: UiImportHead T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_AS QmlIdentifier T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->asToken = loc(2); - sym(1).UiImport->importIdToken = loc(3); - sym(1).UiImport->importId = stringRef(3); - sym(1).UiImport->semicolonToken = loc(4); -} break; + case $rule_number: { + sym(1).UiImport->asToken = loc(2); + sym(1).UiImport->importIdToken = loc(3); + sym(1).UiImport->importId = stringRef(3); + sym(1).UiImport->semicolonToken = loc(4); + } break; ./ -UiPragmaHead: T_PRAGMA PragmaId ; +UiPragmaHead: T_PRAGMA PragmaId; /. -case $rule_number: { - AST::UiPragma *node = 0; + case $rule_number: { + AST::UiPragma *node = 0; - if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) { - node = new (pool) AST::UiPragma(qualifiedId); - } + if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) + node = new (pool) AST::UiPragma(qualifiedId); - sym(1).Node = node; + sym(1).Node = node; - if (node) { - node->pragmaToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); + if (node) { + node->pragmaToken = loc(1); + } else { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), + QLatin1String("Expected a qualified name id"))); - return false; // ### remove me - } -} break; + return false; // ### remove me + } + } break; ./ -UiImportHead: T_IMPORT ImportId ; +UiImportHead: T_IMPORT ImportId; /. -case $rule_number: { - AST::UiImport *node = 0; - - if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) { - node = new (pool) AST::UiImport(importIdLiteral->value); - node->fileNameToken = loc(2); - } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) { - node = new (pool) AST::UiImport(qualifiedId); - node->fileNameToken = loc(2); - } + case $rule_number: { + AST::UiImport *node = 0; - sym(1).Node = node; + if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) { + node = new (pool) AST::UiImport(importIdLiteral->value); + node->fileNameToken = loc(2); + } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) { + node = new (pool) AST::UiImport(qualifiedId); + node->fileNameToken = loc(2); + } - if (node) { - node->importToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id or a string literal"))); + sym(1).Node = node; - return false; // ### remove me - } -} break; + if (node) { + node->importToken = loc(1); + } else { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), + QLatin1String("Expected a qualified name id or a string literal"))); + + return false; // ### remove me + } + } break; ./ Empty: ; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -UiRootMember: UiObjectDefinition ; +UiRootMember: UiObjectDefinition; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); + } break; ./ -UiObjectMemberList: UiObjectMember ; +UiObjectMemberList: UiObjectMember; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); + } break; ./ -UiObjectMemberList: UiObjectMemberList UiObjectMember ; +UiObjectMemberList: UiObjectMemberList UiObjectMember; /. -case $rule_number: { - AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList( - sym(1).UiObjectMemberList, sym(2).UiObjectMember); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember); + sym(1).Node = node; + } break; ./ -UiArrayMemberList: UiObjectDefinition ; +UiArrayMemberList: UiObjectDefinition; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember); + } break; ./ -UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ; +UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition; /. -case $rule_number: { - AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList( - sym(1).UiArrayMemberList, sym(3).UiObjectMember); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(sym(1).UiArrayMemberList, sym(3).UiObjectMember); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -UiObjectInitializer: T_LBRACE T_RBRACE ; +UiObjectInitializer: T_LBRACE T_RBRACE; /. -case $rule_number: { - AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0); - node->lbraceToken = loc(1); - node->rbraceToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0); + node->lbraceToken = loc(1); + node->rbraceToken = loc(2); + sym(1).Node = node; + } break; ./ -UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ; +UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE; /. -case $rule_number: { - 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 $rule_number: { + AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -UiObjectDefinition: UiQualifiedId UiObjectInitializer ; +UiObjectDefinition: UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, - sym(2).UiObjectInitializer); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, sym(2).UiObjectInitializer); + sym(1).Node = node; + } break; ./ -UiObjectMember: UiObjectDefinition ; +UiObjectMember: UiObjectDefinition; -UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ; +UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET; /. -case $rule_number: { - AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding( - sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish()); - node->colonToken = loc(2); - node->lbracketToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(sym(1).UiQualifiedId, sym(5).UiArrayMemberList->finish()); + node->colonToken = loc(2); + node->lbracketToken = loc(4); + node->rbracketToken = loc(6); + sym(1).Node = node; + } break; ./ -UiObjectMember: UiQualifiedId T_COLON UiQualifiedId UiObjectInitializer ; +UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - 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 $rule_number: { + AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( + sym(1).UiQualifiedId, sym(4).UiQualifiedId, sym(5).UiObjectInitializer); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer ; +UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( - sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer); - node->colonToken = loc(2); - node->hasOnToken = true; - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( + sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer); + node->colonToken = loc(2); + node->hasOnToken = true; + sym(1).Node = node; + } break; ./ -UiScriptStatement: Block ; -UiScriptStatement: EmptyStatement ; -UiScriptStatement: ExpressionStatement ; -UiScriptStatement: IfStatement ; -UiScriptStatement: WithStatement ; -UiScriptStatement: SwitchStatement ; -UiScriptStatement: TryStatement ; -UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ; +UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE; /. -case $rule_number: -{ - AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding( - sym(1).UiQualifiedId, sym(3).Statement); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ObjectLiteral *l = new (pool) AST::ObjectLiteral(sym(3).PropertyDefinitionList->finish()); + l->lbraceToken = loc(1); + l->rbraceToken = loc(4); + AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l); + sym(1).Node = node; + } break; ./ -UiPropertyType: T_VAR ; -/. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; -./ -UiPropertyType: T_RESERVED_WORD ; +UiScriptStatement: ExpressionStatementLookahead T_FORCE_DECLARATION ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK Block; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK UiObjectLiteral; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(3).Node; + } break; ./ -UiPropertyType: T_IDENTIFIER ; -/. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; -./ -UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER ; +UiScriptStatement: ExpressionStatementLookahead EmptyStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead IfStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead WithStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead SwitchStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead TryStatement; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3)); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + } break; ./ -UiParameterListOpt: ; +UiObjectMember: UiQualifiedId T_COLON UiScriptStatement; /. -case $rule_number: { - sym(1).Node = 0; -} break; +case $rule_number: +{ + AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(sym(1).UiQualifiedId, sym(3).Statement); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -UiParameterListOpt: UiParameterList ; +UiPropertyType: T_VAR; /. -case $rule_number: { - sym(1).Node = sym(1).UiParameterList->finish (); -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -UiParameterList: UiPropertyType IdentifierReference ; +UiPropertyType: T_RESERVED_WORD; /. -case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); - node->propertyTypeToken = loc(1); - node->identifierToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -UiParameterList: UiParameterList T_COMMA UiPropertyType IdentifierReference ; +UiPropertyType: T_IDENTIFIER; /. -case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); - node->propertyTypeToken = loc(3); - node->commaToken = loc(2); - node->identifierToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON ; +UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->parameters = sym(4).UiParameterList; - node->semicolonToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3)); + node->identifierToken = loc(3); + sym(1).Node = node; + } break; ./ -UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON ; +UiParameterListOpt: ; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT IdentifierReference T_SEMICOLON ; +UiParameterListOpt: UiParameterList; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), 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); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).UiParameterList->finish(); + } break; ./ -UiObjectMember: T_PROPERTY UiPropertyType IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_PROPERTY UiPropertyType IdentifierReference T_SEMICOLON ; +UiParameterList: UiPropertyType QmlIdentifier; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); - sym(1).Node = node; -} break; -./ + case $rule_number: { + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); + node->propertyTypeToken = loc(1); + node->identifierToken = loc(2); + sym(1).Node = node; + } break; +./ -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType IdentifierReference T_SEMICOLON ; +UiParameterList: UiParameterList T_COMMA UiPropertyType QmlIdentifier; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); - sym(1).Node = node; -} break; -./ - -UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT IdentifierReference T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT IdentifierReference T_SEMICOLON ; + case $rule_number: { + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); + node->propertyTypeToken = loc(3); + node->commaToken = loc(2); + node->identifierToken = loc(4); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->typeModifier = stringRef(3); - node->propertyToken = loc(2); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(7); - node->semicolonToken = loc(8); - sym(1).Node = node; -} break; -./ + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); + node->type = AST::UiPublicMember::Signal; + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(2); + node->parameters = sym(4).UiParameterList; + node->semicolonToken = loc(6); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); + node->type = AST::UiPublicMember::Signal; + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), 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); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); + sym(1).Node = node; + } break; +./ -UiObjectMember: T_PROPERTY UiPropertyType IdentifierReference T_COLON UiScriptStatement ; -/. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), - sym(5).Statement); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->colonToken = loc(4); - sym(1).Node = node; -} break; +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->semicolonToken = loc(5); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->typeModifier = stringRef(3); + node->propertyToken = loc(2); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(7); + node->semicolonToken = loc(8); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->colonToken = loc(5); + sym(1).Node = node; + } break; ./ -UiObjectMember: T_READONLY T_PROPERTY UiPropertyType IdentifierReference T_COLON UiScriptStatement ; +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->colonToken = loc(5); + sym(1).Node = node; + } break; ./ -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType IdentifierReference T_COLON UiScriptStatement ; +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; -./ + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), 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 ':' -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT IdentifierReference T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ; -/. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), 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 = new (pool) AST::UiQualifiedId(stringRef(6)); - propertyName->identifierToken = loc(6); - propertyName->next = 0; - - AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding( - propertyName, sym(9).UiArrayMemberList->finish()); - binding->colonToken = loc(7); - binding->lbracketToken = loc(8); - binding->rbracketToken = loc(10); - - node->binding = binding; + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6)); + propertyName->identifierToken = loc(6); + propertyName->next = 0; - sym(1).Node = node; -} break; + AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(9).UiArrayMemberList->finish()); + binding->colonToken = loc(7); + binding->lbracketToken = loc(8); + binding->rbracketToken = loc(10); + + node->binding = binding; + + sym(1).Node = node; + } break; ./ -UiObjectMember: T_PROPERTY UiPropertyType IdentifierReference T_COLON UiQualifiedId UiObjectInitializer ; +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); // insert a fake ';' before ':' + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), 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 = new (pool) AST::UiQualifiedId(stringRef(3)); - propertyName->identifierToken = loc(3); - propertyName->next = 0; + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3)); + propertyName->identifierToken = loc(3); + propertyName->next = 0; - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer); - binding->colonToken = loc(4); + AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( + propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); + binding->colonToken = loc(4); - node->binding = binding; + node->binding = binding; - sym(1).Node = node; -} break; + sym(1).Node = node; + } break; ./ -UiObjectMember: T_READONLY T_PROPERTY UiPropertyType IdentifierReference T_COLON UiQualifiedId UiObjectInitializer ; +UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); // insert a fake ';' before ':' + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->semicolonToken = loc(5); // insert a fake ';' before ':' - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4)); - propertyName->identifierToken = loc(4); - propertyName->next = 0; + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4)); + propertyName->identifierToken = loc(4); + propertyName->next = 0; - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); - binding->colonToken = loc(5); + AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( + propertyName, sym(7).UiQualifiedId, sym(8).UiObjectInitializer); + binding->colonToken = loc(5); - node->binding = binding; + node->binding = binding; - sym(1).Node = node; -} break; + sym(1).Node = node; + } break; ./ -UiObjectMember: FunctionDeclaration ; +UiObjectMember: FunctionDeclaration; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); + } break; ./ -UiObjectMember: VariableStatement ; +UiObjectMember: VariableStatement; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); + } break; +./ + +UiQualifiedId: MemberExpression; +/. + case $rule_number: { + if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, + QLatin1String("Ignored annotation"))); + + sym(1).Expression = mem->base; + } + + if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) { + sym(1).UiQualifiedId = qualifiedId; + } else { + sym(1).UiQualifiedId = 0; + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), + QLatin1String("Expected a qualified name id"))); + + return false; // ### recover + } + } break; ./ UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE; /. -case $rule_number: { - AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish()); - enumDeclaration->enumToken = loc(1); - enumDeclaration->rbraceToken = loc(5); - sym(1).Node = enumDeclaration; - break; -} + case $rule_number: { + AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish()); + enumDeclaration->enumToken = loc(1); + enumDeclaration->rbraceToken = loc(5); + sym(1).Node = enumDeclaration; + break; + } ./ EnumMemberList: T_IDENTIFIER; /. -case $rule_number: { - AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1)); - node->memberToken = loc(1); - sym(1).Node = node; - break; -} + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1)); + node->memberToken = loc(1); + sym(1).Node = node; + break; + } ./ EnumMemberList: T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval); - node->memberToken = loc(1); - node->valueToken = loc(3); - sym(1).Node = node; - break; -} + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval); + node->memberToken = loc(1); + node->valueToken = loc(3); + sym(1).Node = node; + break; + } ./ EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER; /. -case $rule_number: { - AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3)); - node->memberToken = loc(3); - sym(1).Node = node; - break; -} + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3)); + node->memberToken = loc(3); + sym(1).Node = node; + break; + } ./ EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval); - node->memberToken = loc(3); - node->valueToken = loc(5); - sym(1).Node = node; - break; -} + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval); + node->memberToken = loc(3); + node->valueToken = loc(5); + sym(1).Node = node; + break; + } ./ +QmlIdentifier: T_IDENTIFIER; +QmlIdentifier: T_PROPERTY; +QmlIdentifier: T_SIGNAL; +QmlIdentifier: T_READONLY; +QmlIdentifier: T_ON; +QmlIdentifier: T_GET; +QmlIdentifier: T_SET; +QmlIdentifier: T_FROM; +QmlIdentifier: T_OF; + JsIdentifier: T_IDENTIFIER; JsIdentifier: T_PROPERTY; JsIdentifier: T_SIGNAL; @@ -1282,1927 +1384,2219 @@ JsIdentifier: T_READONLY; JsIdentifier: T_ON; JsIdentifier: T_GET; JsIdentifier: T_SET; +JsIdentifier: T_FROM; +JsIdentifier: T_STATIC; +JsIdentifier: T_OF; IdentifierReference: JsIdentifier; -IdentifierReference: T_YIELD; - -IdentifierReference_Yield: JsIdentifier; +BindingIdentifier: IdentifierReference; -------------------------------------------------------------------------------------------------------- -- Expressions -------------------------------------------------------------------------------------------------------- -PrimaryExpression: T_THIS ; +PrimaryExpression: T_THIS; /. -case $rule_number: { - AST::ThisExpression *node = new (pool) AST::ThisExpression(); - node->thisToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ThisExpression *node = new (pool) AST::ThisExpression(); + node->thisToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: IdentifierReference ; +PrimaryExpression: IdentifierReference; /. -case $rule_number: { - AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_NULL ; -/. -case $rule_number: { - AST::NullExpression *node = new (pool) AST::NullExpression(); - node->nullToken = loc(1); - sym(1).Node = node; -} break; -./ +PrimaryExpression: Literal; +PrimaryExpression: ArrayLiteral; +PrimaryExpression: ObjectLiteral; +PrimaryExpression: FunctionExpression; +PrimaryExpression: ClassExpression; +PrimaryExpression: GeneratorExpression; +PrimaryExpression: RegularExpressionLiteral; +PrimaryExpression: TemplateLiteral; -PrimaryExpression: T_TRUE ; -/. -case $rule_number: { - AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); - node->trueToken = loc(1); - sym(1).Node = node; -} break; -./ +PrimaryExpression: CoverParenthesizedExpressionAndArrowParameterList; -PrimaryExpression: T_FALSE ; +-- ### Further restricted parsing of the CoverParenthesizedExpressionAndArrowParameterList to the one rule below when this is parsed as a primary expression! +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_RPAREN; /. -case $rule_number: { - AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); - node->falseToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); + node->lparenToken = loc(1); + node->rparenToken = loc(3); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_NUMERIC_LITERAL ; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_RPAREN; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_ELLIPSIS BindingIdentifier T_RPAREN; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_ELLIPSIS BindingPattern T_RPAREN; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA T_ELLIPSIS BindingIdentifier T_RPAREN; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA T_ELLIPSIS BindingPattern T_RPAREN; + +Literal: T_NULL; /. -case $rule_number: { - AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NullExpression *node = new (pool) AST::NullExpression(); + node->nullToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_MULTILINE_STRING_LITERAL ; -/.case $rule_number:./ - -PrimaryExpression: T_STRING_LITERAL ; +Literal: T_TRUE; /. -case $rule_number: { - AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); + node->trueToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: TemplateLiteral ; +Literal: T_FALSE; /. -case $rule_number: - // nothing that needs to be done here - break; + case $rule_number: { + AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); + node->falseToken = loc(1); + sym(1).Node = node; + } break; ./ -TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE ; -/. case $rule_number: ./ - -TemplateSpans: T_TEMPLATE_TAIL ; +Literal: T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), nullptr); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -TemplateSpans: T_TEMPLATE_MIDDLE Expression TemplateSpans; -/. case $rule_number: ./ +Literal: T_MULTILINE_STRING_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ -TemplateLiteral: T_TEMPLATE_HEAD Expression TemplateSpans ; -/. case $rule_number: { - AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), sym(2).Expression); - node->next = sym(3).Template; - node->literalToken = loc(1); - sym(1).Node = node; -} break; +Literal: T_STRING_LITERAL; +/. + case $rule_number: { + AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_DIVIDE_ ; +RegularExpressionLiteral: T_DIVIDE_; /: #define J_SCRIPT_REGEXPLITERAL_RULE1 $rule_number :/ /. -case $rule_number: { - bool rx = lexer->scanRegExp(Lexer::NoPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; // ### remove me - } - - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token - - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; +{ + Lexer::RegExpBodyPrefix prefix; + case $rule_number: + prefix = Lexer::NoPrefix; + goto scan_regexp; ./ -PrimaryExpression: T_DIVIDE_EQ ; +RegularExpressionLiteral: T_DIVIDE_EQ; /: #define J_SCRIPT_REGEXPLITERAL_RULE2 $rule_number :/ /. -case $rule_number: { - bool rx = lexer->scanRegExp(Lexer::EqualPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; - } + case $rule_number: + prefix = Lexer::EqualPrefix; + goto scan_regexp; - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token + scan_regexp: { + bool rx = lexer->scanRegExp(prefix); + if (!rx) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); + return false; + } - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; -./ + loc(1).length = lexer->tokenLength(); + yylloc = loc(1); // adjust the location of the current token -PrimaryExpression: T_LBRACKET T_RBRACKET ; -/. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0); - node->lbracketToken = loc(1); - node->rbracketToken = loc(2); - sym(1).Node = node; -} break; + AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); + node->literalToken = loc(1); + sym(1).Node = node; + } break; +} ./ -PrimaryExpression: T_LBRACKET Elision T_RBRACKET ; -/. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish()); - node->lbracketToken = loc(1); - node->rbracketToken = loc(3); - sym(1).Node = node; -} break; -./ -PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ; +ArrayLiteral: T_LBRACKET ElisionOpt T_RBRACKET; /. -case $rule_number: { - 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 $rule_number: { + AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision); + node->lbracketToken = loc(1); + node->rbracketToken = loc(3); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET ElementList T_COMMA T_RBRACKET ; +ArrayLiteral: T_LBRACKET ElementList T_RBRACKET; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - (AST::Elision *) 0); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish()); + node->lbracketToken = loc(1); + node->rbracketToken = loc(3); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET ElementList T_COMMA Elision T_RBRACKET ; +ArrayLiteral: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - sym(4).Elision->finish()); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish(), sym(4).Elision); + node->lbracketToken = loc(1); + node->commaToken = loc(3); + node->rbracketToken = loc(5); + sym(1).Node = node; + } break; ./ --- PrimaryExpression: T_LBRACE T_RBRACE ; --- /. --- case $rule_number: { --- sym(1).Node = new (pool) AST::ObjectLiteral(); --- } break; --- ./ - -PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ; +ElementList: AssignmentExpression_In; /. -case $rule_number: { - AST::ObjectLiteral *node = 0; - if (sym(2).Node) - node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - else - node = new (pool) AST::ObjectLiteral(); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::ElementList(nullptr, sym(1).Expression); + } break; ./ -PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ; +ElementList: Elision AssignmentExpression_In; /. -case $rule_number: { - AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - node->lbraceToken = loc(1); - node->rbraceToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression); + } break; ./ -PrimaryExpression: T_LPAREN Expression T_RPAREN ; +ElementList: ElisionOpt SpreadElement; + +ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression_In; /. -case $rule_number: { - AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); - node->lparenToken = loc(1); - node->rparenToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision, sym(4).Expression); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ +ElementList: ElementList T_COMMA ElisionOpt SpreadElement; -UiQualifiedId: MemberExpression ; +Elision: T_COMMA; /. -case $rule_number: { - if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, - QLatin1String("Ignored annotation"))); - - sym(1).Expression = mem->base; - } - - if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) { - sym(1).UiQualifiedId = qualifiedId; - } else { - sym(1).UiQualifiedId = 0; - - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); - - return false; // ### recover - } -} break; + case $rule_number: { + AST::Elision *node = new (pool) AST::Elision(); + node->commaToken = loc(1); + sym(1).Node = node; + } break; ./ -ElementList: AssignmentExpression ; +Elision: Elision T_COMMA; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression); -} break; + case $rule_number: { + AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -ElementList: Elision AssignmentExpression ; +ElisionOpt: ; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression); -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -ElementList: ElementList T_COMMA AssignmentExpression ; +ElisionOpt: Elision; /. -case $rule_number: { - 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 $rule_number: { + sym(1).Node = sym(1).Elision->finish(); + } break; ./ -ElementList: ElementList T_COMMA Elision AssignmentExpression ; -/. -case $rule_number: { - 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; -./ +SpreadElement: T_ELLIPSIS AssignmentExpression; +/. case $rule_number: { UNIMPLEMENTED; } ./ -Elision: T_COMMA ; +ObjectLiteral: T_LBRACE T_RBRACE; /. -case $rule_number: { - AST::Elision *node = new (pool) AST::Elision(); - node->commaToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(); + node->lbraceToken = loc(1); + node->rbraceToken = loc(2); + sym(1).Node = node; + } break; ./ -Elision: Elision T_COMMA ; +ObjectLiteral: T_LBRACE PropertyDefinitionList T_RBRACE; /. -case $rule_number: { - AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(sym(2).PropertyDefinitionList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -ElisionOpt: ; +ObjectLiteral: T_LBRACE PropertyDefinitionList T_COMMA T_RBRACE; /. -case $rule_number: { - sym(1).Node = nullptr; -} break; + case $rule_number: { + AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(sym(2).PropertyDefinitionList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(4); + sym(1).Node = node; + } break; ./ -ElisionOpt: Elision ; + +UiPropertyDefinitionList: UiPropertyDefinition; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinitionList: PropertyDefinition; /. -case $rule_number: { - sym(1).Node = sym(1).Elision->finish(); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::PropertyDefinitionList(sym(1).PropertyDefinition); + } break; ./ -PropertyAssignment: PropertyName T_COLON AssignmentExpression ; +UiPropertyDefinitionList: UiPropertyDefinitionList T_COMMA UiPropertyDefinition; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinitionList: PropertyDefinitionList T_COMMA PropertyDefinition; /. -case $rule_number: { - AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue( - sym(1).PropertyName, sym(3).Expression); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PropertyDefinitionList *node = new (pool) AST::PropertyDefinitionList(sym(1).PropertyDefinitionList, sym(3).PropertyDefinition); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +PropertyDefinition: IdentifierReference; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +PropertyDefinition: CoverInitializedName; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +UiPropertyDefinition: UiPropertyName T_COLON AssignmentExpression_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinition: PropertyName T_COLON AssignmentExpression_In; /. -case $rule_number: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(6).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(sym(1).PropertyName, sym(3).Expression); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameters T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +PropertyDefinition: MethodDefinition; + +PropertyName: LiteralPropertyName; +PropertyName: ComputedPropertyName; + +LiteralPropertyName: IdentifierName; /. -case $rule_number: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; ./ -PropertyAssignmentList: PropertyAssignment ; +UiPropertyName: T_STRING_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LiteralPropertyName: T_STRING_LITERAL; /. -case $rule_number: { - sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment); -} break; + case $rule_number: { + AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; ./ -PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ; +UiPropertyName: T_NUMERIC_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LiteralPropertyName: T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList( - sym(1).PropertyAssignmentList, sym(3).PropertyAssignment); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; ./ -PropertyName: IdentifierReference %prec SHIFT_THERE ; +IdentifierName: IdentifierReference; +IdentifierName: ReservedIdentifier; + +ReservedIdentifier: T_BREAK; +ReservedIdentifier: T_CASE; +ReservedIdentifier: T_CATCH; +ReservedIdentifier: T_CONTINUE; +ReservedIdentifier: T_DEFAULT; +ReservedIdentifier: T_DELETE; +ReservedIdentifier: T_DO; +ReservedIdentifier: T_ELSE; +ReservedIdentifier: T_ENUM; +ReservedIdentifier: T_FALSE; +ReservedIdentifier: T_FINALLY; +ReservedIdentifier: T_FOR; +ReservedIdentifier: T_FUNCTION; +ReservedIdentifier: T_IF; +ReservedIdentifier: T_IN; +ReservedIdentifier: T_INSTANCEOF; +ReservedIdentifier: T_NEW; +ReservedIdentifier: T_NULL; +ReservedIdentifier: T_RETURN; +ReservedIdentifier: T_SWITCH; +ReservedIdentifier: T_THIS; +ReservedIdentifier: T_THROW; +ReservedIdentifier: T_TRUE; +ReservedIdentifier: T_TRY; +ReservedIdentifier: T_TYPEOF; +ReservedIdentifier: T_VAR; +ReservedIdentifier: T_VOID; +ReservedIdentifier: T_WHILE; +ReservedIdentifier: T_CONST; +ReservedIdentifier: T_LET; +ReservedIdentifier: T_DEBUGGER; +ReservedIdentifier: T_RESERVED_WORD; +ReservedIdentifier: T_SUPER; +ReservedIdentifier: T_WITH; +ReservedIdentifier: T_CLASS; +ReservedIdentifier: T_EXTENDS; +ReservedIdentifier: T_EXPORT; + +ComputedPropertyName: T_LBRACKET AssignmentExpression_In T_RBRACKET; +/. case $rule_number: { UNIMPLEMENTED; } ./ + + +CoverInitializedName: IdentifierReference Initializer_In; + +Initializer: T_EQ AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Initializer_In: T_EQ AssignmentExpression_In; /. case $rule_number: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; + sym(1) = sym(2); } break; ./ -PropertyName: T_STRING_LITERAL ; + +InitializerOpt: ; +/. case $rule_number: Q_FALLTHROUGH(); ./ +InitializerOpt_In: ; /. -case $rule_number: { - AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -PropertyName: T_NUMERIC_LITERAL ; +InitializerOpt: Initializer; +InitializerOpt_In: Initializer_In; + +TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE; +/. case $rule_number: Q_FALLTHROUGH(); ./ + +TemplateSpans: T_TEMPLATE_TAIL; /. -case $rule_number: { - AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), nullptr); + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -PropertyName: ReservedIdentifier ; +TemplateSpans: T_TEMPLATE_MIDDLE Expression TemplateSpans; +/. case $rule_number: Q_FALLTHROUGH(); ./ + +TemplateLiteral: T_TEMPLATE_HEAD Expression TemplateSpans; /. -case $rule_number: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), sym(2).Expression); + node->next = sym(3).Template; + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -ReservedIdentifier: T_BREAK ; -ReservedIdentifier: T_CASE ; -ReservedIdentifier: T_CATCH ; -ReservedIdentifier: T_CONTINUE ; -ReservedIdentifier: T_DEFAULT ; -ReservedIdentifier: T_DELETE ; -ReservedIdentifier: T_DO ; -ReservedIdentifier: T_ELSE ; -ReservedIdentifier: T_ENUM ; -ReservedIdentifier: T_FALSE ; -ReservedIdentifier: T_FINALLY ; -ReservedIdentifier: T_FOR ; -ReservedIdentifier: T_FUNCTION ; -ReservedIdentifier: T_IF ; -ReservedIdentifier: T_IN ; -ReservedIdentifier: T_INSTANCEOF ; -ReservedIdentifier: T_NEW ; -ReservedIdentifier: T_NULL ; -ReservedIdentifier: T_RETURN ; -ReservedIdentifier: T_SWITCH ; -ReservedIdentifier: T_THIS ; -ReservedIdentifier: T_THROW ; -ReservedIdentifier: T_TRUE ; -ReservedIdentifier: T_TRY ; -ReservedIdentifier: T_TYPEOF ; -ReservedIdentifier: T_VAR ; -ReservedIdentifier: T_VOID ; -ReservedIdentifier: T_WHILE ; -ReservedIdentifier: T_CONST ; -ReservedIdentifier: T_LET ; -ReservedIdentifier: T_DEBUGGER ; -ReservedIdentifier: T_RESERVED_WORD ; -ReservedIdentifier: T_WITH ; - -PropertyIdentifier: IdentifierReference ; -PropertyIdentifier: ReservedIdentifier ; - -MemberExpression: PrimaryExpression ; -MemberExpression: FunctionExpression ; - -MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ; + +MemberExpression: PrimaryExpression; + +MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -MemberExpression: MemberExpression T_DOT PropertyIdentifier ; +MemberExpression: MemberExpression T_DOT IdentifierName; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -CallExpression: CallExpression TemplateLiteral; -/. case $rule_number: ./ +MemberExpression: SuperProperty; +/. case $rule_number: { UNIMPLEMENTED; } ./ -MemberExpression: MemberExpression TemplateLiteral ; -/. -case $rule_number: { - AST::TaggedTemplate *node = new (pool) AST::TaggedTemplate(sym(1).Expression, sym(2).Template); - sym(1).Node = node; -} break; -./ +MemberExpression: MetaProperty; +/. case $rule_number: { UNIMPLEMENTED; } ./ -MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; +MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - 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); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + sym(1).Node = node; + } break; ./ -NewExpression: MemberExpression ; +SuperProperty: T_SUPER T_LBRACKET Expression_In T_RBRACKET; + +SuperProperty: T_SUPER T_DOT IdentifierName; + +MetaProperty: NewTarget; -NewExpression: T_NEW NewExpression ; +NewTarget: T_NEW T_DOT T_IDENTIFIER; -- ### the identifier has to be "target"; + +NewExpression: MemberExpression; + +NewExpression: T_NEW NewExpression; /. -case $rule_number: { + case $rule_number: { AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression); node->newToken = loc(1); sym(1).Node = node; -} break; + } break; ./ -CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; + +CallExpression: CallExpression TemplateLiteral; +/. case $rule_number: Q_FALLTHROUGH(); ./ +MemberExpression: MemberExpression TemplateLiteral; /. -case $rule_number: { - 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 $rule_number: { + AST::TaggedTemplate *node = new (pool) AST::TaggedTemplate(sym(1).Expression, sym(2).Template); + sym(1).Node = node; + } break; ./ -CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ; +CallExpression: MemberExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ; +CallExpression: SuperCall; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +CallExpression: CallExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -CallExpression: CallExpression T_DOT PropertyIdentifier ; +CallExpression: CallExpression T_LBRACKET Expression_In T_RBRACKET; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -ArgumentListOpt: ; +CallExpression: CallExpression T_DOT IdentifierName; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + 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; ./ -ArgumentListOpt: ArgumentList ; +SuperCall: T_SUPER T_LPAREN Arguments T_RPAREN; + +Arguments: ; /. -case $rule_number: { - sym(1).Node = sym(1).ArgumentList->finish(); -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -ArgumentList: AssignmentExpression ; +Arguments: ArgumentList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Arguments: ArgumentList T_COMMA; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); -} break; + case $rule_number: { + sym(1).Node = sym(1).ArgumentList->finish(); + } break; ./ -ArgumentList: ArgumentList T_COMMA AssignmentExpression ; +ArgumentList: AssignmentExpression_In; /. -case $rule_number: { - AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); + } break; ./ -LeftHandSideExpression: NewExpression ; -LeftHandSideExpression: CallExpression ; -PostfixExpression: LeftHandSideExpression ; +ArgumentList: T_ELLIPSIS AssignmentExpression_In; +/. case $rule_number: { UNIMPLEMENTED; } ./ -PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ; +ArgumentList: ArgumentList T_COMMA AssignmentExpression_In; /. -case $rule_number: { - AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); - node->incrementToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ; +ArgumentList: ArgumentList T_COMMA T_ELLIPSIS AssignmentExpression_In; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +LeftHandSideExpression: NewExpression; +LeftHandSideExpression: CallExpression; + +UpdateExpression: LeftHandSideExpression; + +UpdateExpression: LeftHandSideExpression T_PLUS_PLUS; /. -case $rule_number: { - AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); - node->decrementToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); + node->incrementToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: PostfixExpression ; +UpdateExpression: LeftHandSideExpression T_MINUS_MINUS; +/. + case $rule_number: { + AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); + node->decrementToken = loc(2); + sym(1).Node = node; + } break; +./ -UnaryExpression: T_DELETE UnaryExpression ; +UpdateExpression: T_PLUS_PLUS UnaryExpression; /. -case $rule_number: { - AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); - node->deleteToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); + node->incrementToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_VOID UnaryExpression ; +UpdateExpression: T_MINUS_MINUS UnaryExpression; /. -case $rule_number: { - AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); - node->voidToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); + node->decrementToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_TYPEOF UnaryExpression ; +UnaryExpression: UpdateExpression; + +UnaryExpression: T_DELETE UnaryExpression; /. -case $rule_number: { - AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); - node->typeofToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); + node->deleteToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_PLUS_PLUS UnaryExpression ; +UnaryExpression: T_VOID UnaryExpression; /. -case $rule_number: { - AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); - node->incrementToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); + node->voidToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_MINUS_MINUS UnaryExpression ; +UnaryExpression: T_TYPEOF UnaryExpression; /. -case $rule_number: { - AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); - node->decrementToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); + node->typeofToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_PLUS UnaryExpression ; +UnaryExpression: T_PLUS UnaryExpression; /. -case $rule_number: { - AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); - node->plusToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); + node->plusToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_MINUS UnaryExpression ; +UnaryExpression: T_MINUS UnaryExpression; /. -case $rule_number: { - AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); - node->minusToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); + node->minusToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_TILDE UnaryExpression ; +UnaryExpression: T_TILDE UnaryExpression; /. -case $rule_number: { - AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); - node->tildeToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); + node->tildeToken = loc(1); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_NOT UnaryExpression ; +UnaryExpression: T_NOT UnaryExpression; /. -case $rule_number: { - AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); - node->notToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); + node->notToken = loc(1); + sym(1).Node = node; + } break; ./ -MultiplicativeExpression: UnaryExpression ; +ExponentiationExpression: UnaryExpression; + +ExponentiationExpression: UpdateExpression T_STAR_STAR ExponentiationExpression; +/. case $rule_number: { UNIMPLEMENTED; } ./ -MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ; +MultiplicativeExpression: ExponentiationExpression; + +MultiplicativeExpression: MultiplicativeExpression MultiplicativeOperator ExponentiationExpression; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ; +MultiplicativeOperator: T_STAR; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Mul; + } break; ./ -MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ; +MultiplicativeOperator: T_DIVIDE_; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Div; + } break; +./ + +MultiplicativeOperator: T_REMAINDER; +/. + case $rule_number: { + sym(1).ival = QSOperator::Mod; + } break; ./ -AdditiveExpression: MultiplicativeExpression ; +AdditiveExpression: MultiplicativeExpression; -AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ; +AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Add, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ; +AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Sub, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: AdditiveExpression ; +ShiftExpression: AdditiveExpression; -ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ; +ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::LShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ; +ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::RShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ; +ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::URShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -RelationalExpression: ShiftExpression ; -RelationalExpressionNotIn: ShiftExpression ; - -RelationalExpression: RelationalExpression T_LT ShiftExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +RelationalExpression_In: ShiftExpression; +RelationalExpression: ShiftExpression; -RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ; +RelationalExpression_In: RelationalExpression_In RelationalOperator ShiftExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +RelationalExpression: RelationalExpression RelationalOperator ShiftExpression; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -RelationalExpression: RelationalExpression T_GT ShiftExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ; +RelationalOperator: T_LT; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Lt; + } break; ./ - -RelationalExpression: RelationalExpression T_LE ShiftExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ; +RelationalOperator: T_GT; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Gt; + } break; ./ - -RelationalExpression: RelationalExpression T_GE ShiftExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ; +RelationalOperator: T_LE; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Le; + } break; ./ - -RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ; +RelationalOperator: T_GE; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Ge; + } break; ./ - -RelationalExpression: RelationalExpression T_IN ShiftExpression ; +RelationalOperator: T_INSTANCEOF; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::InstanceOf; + } break; ./ -EqualityExpression: RelationalExpression ; -EqualityExpressionNotIn: RelationalExpressionNotIn ; - -EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ; +RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::In, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +EqualityExpression_In: RelationalExpression_In; +EqualityExpression: RelationalExpression; -EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn; +EqualityExpression_In: EqualityExpression_In EqualityOperator RelationalExpression_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +EqualityExpression: EqualityExpression EqualityOperator RelationalExpression; /. -case $rule_number: { - 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 $rule_number: { + 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; ./ -EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ; +EqualityOperator: T_EQ_EQ; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::Equal; + } break; ./ - -EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ; +EqualityOperator: T_NOT_EQ; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::NotEqual; + } break; +./ +EqualityOperator: T_EQ_EQ_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::StrictEqual; + } break; +./ +EqualityOperator: T_NOT_EQ_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::StrictNotEqual; + } break; ./ -BitwiseANDExpression: EqualityExpression ; -BitwiseANDExpressionNotIn: EqualityExpressionNotIn ; - -BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +BitwiseANDExpression: EqualityExpression; +XitwiseANDExpression_In: EqualityExpression_In; -BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ; +BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +XitwiseANDExpression_In: XitwiseANDExpression_In T_AND EqualityExpression_In; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -BitwiseXORExpression: BitwiseANDExpression ; -BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ; +BitwiseXORExpression: BitwiseANDExpression; +BitwiseXORExpression_In: XitwiseANDExpression_In; -BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ - -BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ; +BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BitwiseXORExpression_In: BitwiseXORExpression_In T_XOR XitwiseANDExpression_In; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitXor, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -BitwiseORExpression: BitwiseXORExpression ; -BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ; - -BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +BitwiseORExpression: BitwiseXORExpression; +BitwiseORExpression_In: BitwiseXORExpression_In; -BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ; +BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BitwiseORExpression_In: BitwiseORExpression_In T_OR BitwiseXORExpression_In; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitOr, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -LogicalANDExpression: BitwiseORExpression ; -LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ; +LogicalANDExpression: BitwiseORExpression; +LogicalANDExpression_In: BitwiseORExpression_In; -LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LogicalANDExpression_In: LogicalANDExpression_In T_AND_AND BitwiseORExpression_In; +/. + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; +./ -LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ; +LogicalORExpression: LogicalANDExpression; +LogicalORExpression_In: LogicalANDExpression_In; + +LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In; /. -case $rule_number: { - 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 $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Or, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -LogicalORExpression: LogicalANDExpression ; -LogicalORExpressionNotIn: LogicalANDExpressionNotIn ; -LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +ConditionalExpression: LogicalORExpression; +ConditionalExpression_In: LogicalORExpression_In; -LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ; +ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In; /. -case $rule_number: { - 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 $rule_number: { + AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); + node->questionToken = loc(2); + node->colonToken = loc(4); + sym(1).Node = node; + } break; ./ +AssignmentExpression: ConditionalExpression; +AssignmentExpression_In: ConditionalExpression_In; -ConditionalExpression: LogicalORExpression ; -ConditionalExpressionNotIn: LogicalORExpressionNotIn ; +AssignmentExpression: YieldExpression; +AssignmentExpression_In: YieldExpression_In; -ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +AssignmentExpression: ArrowFunction; +AssignmentExpression_In: ArrowFunction_In; -ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ; +-- ### Use AssignmentPattern in some cases for LHSexpression +AssignmentExpression: LeftHandSideExpression T_EQ AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In; /. -case $rule_number: { - AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, - sym(3).Expression, sym(5).Expression); - node->questionToken = loc(2); - node->colonToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Assign, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -AssignmentExpression: ConditionalExpression ; -AssignmentExpressionNotIn: ConditionalExpressionNotIn ; - -AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +AssignmentExpression_In: LeftHandSideExpression AssignmentOperator AssignmentExpression_In; +/. + case $rule_number: { + 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; +./ -AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ; +AssignmentOperator: T_STAR_EQ; /. -case $rule_number: { - 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 $rule_number: { + sym(1).ival = QSOperator::InplaceMul; + } break; ./ -AssignmentOperator: T_EQ ; +AssignmentOperator: T_DIVIDE_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::Assign; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceDiv; + } break; ./ -AssignmentOperator: T_STAR_EQ ; +AssignmentOperator: T_REMAINDER_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceMul; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceMod; + } break; ./ -AssignmentOperator: T_DIVIDE_EQ ; +AssignmentOperator: T_PLUS_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceDiv; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceAdd; + } break; ./ -AssignmentOperator: T_REMAINDER_EQ ; +AssignmentOperator: T_MINUS_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceMod; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceSub; + } break; ./ -AssignmentOperator: T_PLUS_EQ ; +AssignmentOperator: T_LT_LT_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceAdd; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceLeftShift; + } break; ./ -AssignmentOperator: T_MINUS_EQ ; +AssignmentOperator: T_GT_GT_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceSub; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceRightShift; + } break; ./ -AssignmentOperator: T_LT_LT_EQ ; +AssignmentOperator: T_GT_GT_GT_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceLeftShift; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceURightShift; + } break; ./ -AssignmentOperator: T_GT_GT_EQ ; +AssignmentOperator: T_AND_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceRightShift; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceAnd; + } break; ./ -AssignmentOperator: T_GT_GT_GT_EQ ; +AssignmentOperator: T_XOR_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceURightShift; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceXor; + } break; ./ -AssignmentOperator: T_AND_EQ ; +AssignmentOperator: T_OR_EQ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceAnd; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceOr; + } break; ./ -AssignmentOperator: T_XOR_EQ ; +Expression: AssignmentExpression; +Expression_In: AssignmentExpression_In; + +Expression: Expression T_COMMA AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Expression_In: Expression_In T_COMMA AssignmentExpression_In; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceXor; -} break; + case $rule_number: { + AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_OR_EQ ; +ExpressionOpt: ; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ExpressionOpt_In: ; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceOr; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -Expression: AssignmentExpression ; -ExpressionNotIn: AssignmentExpressionNotIn ; +ExpressionOpt: Expression; +ExpressionOpt_In: Expression_In; -Expression: Expression T_COMMA AssignmentExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +-- Statements -ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ; +Statement: ExpressionStatementLookahead T_FORCE_BLOCK BlockStatement; /. -case $rule_number: { - AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(3).Node; + } break; ./ -ExpressionOpt: ; -/.case $rule_number: Q_FALLTHROUGH();./ - -ExpressionNotInOpt: ; +Statement: ExpressionStatementLookahead VariableStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead EmptyStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead IfStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead BreakableStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ContinueStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead BreakStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ReturnStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead WithStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead LabelledStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ThrowStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead TryStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead DebuggerStatement; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + } break; ./ -ExpressionOpt: Expression ; -ExpressionNotInOpt: ExpressionNotIn ; +Declaration: HoistableDeclaration; +Declaration: ClassDeclaration; +Declaration: LexicalDeclaration_In; + +HoistableDeclaration: FunctionDeclaration; +HoistableDeclaration: GeneratorDeclaration; -Statement: Block ; -Statement: VariableStatement ; -Statement: EmptyStatement ; -Statement: ExpressionStatement ; -Statement: IfStatement ; -Statement: IterationStatement ; -Statement: ContinueStatement ; -Statement: BreakStatement ; -Statement: ReturnStatement ; -Statement: WithStatement ; -Statement: LabelledStatement ; -Statement: SwitchStatement ; -Statement: ThrowStatement ; -Statement: TryStatement ; -Statement: DebuggerStatement ; +HoistableDeclaration_Default: FunctionDeclaration_Default; +HoistableDeclaration_Default: GeneratorDeclaration_Default; +BreakableStatement: IterationStatement; +BreakableStatement: SwitchStatement; -Block: T_LBRACE StatementListOpt T_RBRACE ; +BlockStatement: Block; + +Block: T_LBRACE StatementListOpt T_RBRACE; /. -case $rule_number: { - AST::Block *node = new (pool) AST::Block(sym(2).StatementList); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Block *node = new (pool) AST::Block(sym(2).StatementList); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; +./ + +StatementList: StatementListItem; + +StatementList: StatementList StatementListItem; +/. + case $rule_number: { + sym(1).StatementList = sym(1).StatementList->append(sym(2).StatementList); + } break; ./ -StatementList: Statement ; +StatementListItem: Statement; /. -case $rule_number: { - sym(1).Node = new (pool) AST::StatementList(sym(1).Statement); -} break; + case $rule_number: { + sym(1).StatementList = new (pool) AST::StatementList(sym(1).Statement); + } break; ./ -StatementList: StatementList Statement ; +StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_AUTOMATIC_SEMICOLON; +StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_SEMICOLON; /. -case $rule_number: { - sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::StatementList(sym(3).FunctionDeclaration); + } break; ./ StatementListOpt: ; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -StatementListOpt: StatementList ; +StatementListOpt: StatementList; /. -case $rule_number: { - sym(1).Node = sym(1).StatementList->finish (); -} break; + case $rule_number: { + sym(1).Node = sym(1).StatementList->finish(); + } break; ./ -VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ; +LetOrConst: T_LET; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - if (sym(1).ival == T_LET) - s = AST::VariableDeclaration::BlockScope; - else if (sym(1).ival == T_CONST) - s = AST::VariableDeclaration::ReadOnlyBlockScope; - - AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s)); - node->declarationKindToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = AST::VariableDeclaration::BlockScope; + } break; ./ - -VariableDeclarationKind: T_LET ; +LetOrConst: T_CONST; /. -case $rule_number: { - sym(1).ival = T_LET; -} break; + case $rule_number: { + sym(1).ival = AST::VariableDeclaration::ReadOnlyBlockScope; + } break; ./ -VariableDeclarationKind: T_CONST ; +Var: T_VAR; /. -case $rule_number: { - sym(1).ival = T_CONST; -} break; + case $rule_number: { + sym(1).ival = AST::VariableDeclaration::FunctionScope; + } break; ./ -VariableDeclarationKind: T_VAR ; +LexicalDeclaration: LetOrConst BindingList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalDeclaration_In: LetOrConst BindingList_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VarDeclaration: Var VariableDeclarationList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VarDeclaration_In: Var VariableDeclarationList_In; /. -case $rule_number: { - sym(1).ival = T_VAR; -} break; + case $rule_number: { + AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::VariableScope(sym(1).ival); + AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s)); + node->declarationKindToken = loc(1); + sym(1).Node = node; + } break; ./ -VariableDeclarationList: VariableDeclaration ; -/.case $rule_number: Q_FALLTHROUGH();./ +VariableStatement: VarDeclaration_In T_AUTOMATIC_SEMICOLON; +VariableStatement: VarDeclaration_In T_SEMICOLON; -VariableDeclarationListNotIn: VariableDeclarationNotIn ; +BindingList: LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BindingList_In: LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList: VariableDeclaration; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList_In: VariableDeclaration_In; /. -case $rule_number: { + case $rule_number: { sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); -} break; + } break; ./ -VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ; -/.case $rule_number: Q_FALLTHROUGH();./ - -VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ; +BindingList: BindingList T_COMMA LexicalBinding; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BindingList_In: BindingList_In T_COMMA LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList_In: VariableDeclarationList_In T_COMMA VariableDeclaration_In; /. -case $rule_number: { - AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList( - sym(1).VariableDeclarationList, sym(3).VariableDeclaration); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -VariableDeclaration: IdentifierReference InitializerOpt ; -/.case $rule_number: Q_FALLTHROUGH();./ - -VariableDeclarationNotIn: IdentifierReference InitializerNotInOpt ; +LexicalBinding: BindingIdentifier InitializerOpt; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalBinding_In: BindingIdentifier InitializerOpt_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration: BindingIdentifier InitializerOpt; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration_In: BindingIdentifier InitializerOpt_In; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; + AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ --- VariableDeclaration: BindingPattern InitializerOpt ; --- VariableDeclarationNotIn: BindingPattern InitializerNotInOpt ; - -Initializer: T_EQ AssignmentExpression ; -/.case $rule_number: Q_FALLTHROUGH();./ +LexicalBinding: BindingPattern Initializer; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalBinding_In: BindingPattern Initializer_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration: BindingPattern InitializerOpt; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration_In: BindingPattern Initializer_In; +/. case $rule_number: { UNIMPLEMENTED; } ./ -InitializerNotIn: T_EQ AssignmentExpressionNotIn ; +BindingPattern: T_LBRACE ObjectBindingPattern T_RBRACE; /. -case $rule_number: { - // ### TODO: AST for initializer - sym(1) = sym(2); -} break; + case $rule_number: { + auto *node = new (pool) AST::ObjectBindingPattern(sym(2).BindingPropertyList); + node->first = loc(1); + node->last = loc(3); + sym(1).Node = node; + } break; ./ -InitializerOpt: ; -/.case $rule_number: Q_FALLTHROUGH();./ - -InitializerNotInOpt: ; +BindingPattern: T_LBRACKET ArrayBindingPattern T_RBRACKET; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + auto *node = new (pool) AST::ArrayBindingPattern(sym(2).BindingElementList); + node->first = loc(1); + node->last = loc(3); + sym(1).Node = node; + } break; ./ -InitializerOpt: Initializer ; -InitializerNotInOpt: InitializerNotIn ; +ObjectBindingPattern: ; +/. + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ -EmptyStatement: T_SEMICOLON ; +ObjectBindingPattern: BindingPropertyList; +/. case $rule_number: ./ +ObjectBindingPattern: BindingPropertyList T_COMMA; /. -case $rule_number: { - AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); - node->semicolonToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).BindingPropertyList->finish(); + } break; ./ -ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ExpressionStatement: Expression T_SEMICOLON ; +ArrayBindingPattern: ElisionOpt BindingRestElementOpt; /. -case $rule_number: { - AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + if (sym(3).Elision || sym(4).Node) { + auto *l = new (pool) AST::BindingElementList(sym(1).Elision, sym(2).Node); + sym(1).Node = l->finish(); + } else { + sym(1).Node = nullptr; + } + } break; ./ -IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ; +ArrayBindingPattern: BindingElementList; /. -case $rule_number: { - 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); - node->elseToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).BindingElementList->finish(); + } break; ./ -IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ; +ArrayBindingPattern: BindingElementList T_COMMA ElisionOpt BindingRestElementOpt; /. -case $rule_number: { - 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); - sym(1).Node = node; -} break; + case $rule_number: { + if (sym(3).Elision || sym(4).Node) { + auto *l = new (pool) AST::BindingElementList(sym(3).Elision, sym(4).Node); + l = sym(1).BindingElementList->append(l); + sym(1).Node = l; + } + sym(1).Node = sym(1).BindingElementList->finish(); + } break; ./ +BindingPropertyList: BindingProperty; -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_COMPATIBILITY_SEMICOLON ; -- for JSC/V8 compatibility -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ; +BindingPropertyList: BindingPropertyList T_COMMA BindingProperty; /. -case $rule_number: { - 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); - node->rparenToken = loc(6); - node->semicolonToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).BindingPropertyList->append(sym(3).BindingPropertyList); + } break; ./ -IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ; +BindingElementList: BindingElisionElement; + +BindingElementList: BindingElementList T_COMMA BindingElisionElement; /. -case $rule_number: { - 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); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).BindingElementList->append(sym(3).BindingElementList); + } break; ./ -IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; +BindingElisionElement: ElisionOpt BindingElement; /. -case $rule_number: { - 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); - node->firstSemicolonToken = loc(4); - node->secondSemicolonToken = loc(6); - node->rparenToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::BindingElementList(sym(1).Elision, sym(2).BindingElement); + } break; ./ -IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; + +BindingProperty: BindingIdentifier InitializerOpt_In; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::LocalForStatement *node = new (pool) AST::LocalForStatement( - sym(4).VariableDeclarationList->finish(s), sym(6).Expression, - sym(8).Expression, sym(10).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->firstSemicolonToken = loc(5); - node->secondSemicolonToken = loc(7); - node->rparenToken = loc(9); - sym(1).Node = node; -} break; + case $rule_number: { + AST::StringLiteralPropertyName *name = new (pool) AST::StringLiteralPropertyName(stringRef(1)); + AST::BindingElement *e = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression); + AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(name, e); + sym(1).Node = node; + } break; ./ -IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ; +BindingProperty: PropertyName T_COLON BindingElement; /. -case $rule_number: { - AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, - sym(5).Expression, sym(7).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->inToken = loc(4); - node->rparenToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(sym(1).PropertyName, sym(3).BindingElement); + sym(1).Node = node; + } break; ./ -IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ; +BindingElement: BindingIdentifier InitializerOpt_In; /. -case $rule_number: { - AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement( - sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->inToken = loc(5); - node->rparenToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BindingElement *node = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ContinueStatement: T_CONTINUE T_SEMICOLON ; +BindingElement: BindingPattern InitializerOpt_In; /. -case $rule_number: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); - node->continueToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BindingElement *node = new (pool) AST::BindingElement(sym(1).BindingPattern, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -ContinueStatement: T_CONTINUE IdentifierReference T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ContinueStatement: T_CONTINUE IdentifierReference T_SEMICOLON ; +BindingRestElement: T_ELLIPSIS BindingIdentifier; /. -case $rule_number: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); - node->continueToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BindingRestElement *node = new (pool) AST::BindingRestElement(stringRef(2)); + node->identifierToken = loc(2); + sym(1).Node = node; + } break; ./ -BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -BreakStatement: T_BREAK T_SEMICOLON ; +BindingRestElement: T_ELLIPSIS BindingPattern; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +BindingRestElementOpt: ; /. -case $rule_number: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); - node->breakToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -BreakStatement: T_BREAK IdentifierReference T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -BreakStatement: T_BREAK IdentifierReference T_SEMICOLON ; +BindingRestElementOpt: BindingRestElement; + + +EmptyStatement: T_SEMICOLON; /. -case $rule_number: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); - node->breakToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); + node->semicolonToken = loc(1); + sym(1).Node = node; + } break; ./ -ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ; +-- Spec says it should have a "[lookahead ∉ { {, function, class, let [ }]" before the Expression statement. +-- This is implemented with the rule below that is run before any statement and inserts a T_EXPRESSION_STATEMENT_OK +-- token if it's ok to parse as an expression statement. +ExpressionStatementLookahead: ; +/: +#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); - node->returnToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + int token = lookaheadToken(lexer); + if (token == T_LBRACE) + pushToken(T_FORCE_BLOCK); + else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST) + pushToken(T_FORCE_DECLARATION); + } break; +./ + +ExpressionStatement: Expression_In T_AUTOMATIC_SEMICOLON; +ExpressionStatement: Expression_In T_SEMICOLON; +/. + case $rule_number: { + AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ - -WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ; + +IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement T_ELSE Statement; +/. + case $rule_number: { + 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); + node->elseToken = loc(6); + sym(1).Node = node; + } break; +./ + +IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - 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); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + sym(1).Node = node; + } break; +./ + + +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_AUTOMATIC_SEMICOLON; +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_COMPATIBILITY_SEMICOLON; -- for JSC/V8 compatibility +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_SEMICOLON; +/. + case $rule_number: { + 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); + node->rparenToken = loc(6); + node->semicolonToken = loc(7); + sym(1).Node = node; + } break; ./ -SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ; +IterationStatement: T_WHILE T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - 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); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + sym(1).Node = node; + } break; ./ -CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ; +IterationStatement: T_FOR T_LPAREN ExpressionOpt T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; -- [lookahead != { let [ }] /. -case $rule_number: { - AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + node->firstSemicolonToken = loc(4); + node->secondSemicolonToken = loc(6); + node->rparenToken = loc(8); + sym(1).Node = node; + } break; ./ -CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ; +IterationStatement: T_FOR T_LPAREN VarDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +IterationStatement: T_FOR T_LPAREN LexicalDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; /. -case $rule_number: { - 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 $rule_number: { + // ### get rid of the static_cast! + AST::LocalForStatement *node = new (pool) AST::LocalForStatement( + static_cast<AST::VariableStatement *>(sym(3).Node)->declarations, sym(5).Expression, + sym(7).Expression, sym(9).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->varToken = loc(3); + node->firstSemicolonToken = loc(4); + node->secondSemicolonToken = loc(6); + node->rparenToken = loc(8); + sym(1).Node = node; + } break; ./ -CaseClauses: CaseClause ; +IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); -} break; + case $rule_number: { + AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->inToken = loc(4); + node->rparenToken = loc(6); + sym(1).Node = node; + } break; ./ -CaseClauses: CaseClauses CaseClause ; +IterationStatement: T_FOR T_LPAREN ForDeclaration T_IN Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); -} break; + case $rule_number: { + AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(sym(3).VariableDeclaration, sym(5).Expression, sym(7).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->varToken = loc(3); + node->inToken = loc(4); + node->rparenToken = loc(6); + sym(1).Node = node; + } break; ./ -CaseClausesOpt: ; + +IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_OF AssignmentExpression_In T_RPAREN Statement; -- [lookahead ≠ let] +/. case $rule_number: { UNIMPLEMENTED; } ./ +IterationStatement: T_FOR T_LPAREN ForDeclaration T_OF Expression_In T_RPAREN Statement; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +ForDeclaration: LetOrConst ForBinding; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ForDeclaration: Var ForBinding; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::VariableScope(sym(1).ival); + auto *node = new (pool) AST::VariableDeclaration(stringRef(2), nullptr, s); + node->identifierToken = loc(2); + sym(1).Node = node; + } break; ./ - -CaseClausesOpt: CaseClauses ; + +ForBinding: BindingIdentifier; + +ForBinding: BindingPattern; +/. case $rule_number: UNIMPLEMENTED; ./ + +ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON; +ContinueStatement: T_CONTINUE T_SEMICOLON; /. -case $rule_number: { - sym(1).Node = sym(1).CaseClauses->finish (); -} break; + case $rule_number: { + AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); + node->continueToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ -CaseClause: T_CASE Expression T_COLON StatementListOpt ; +ContinueStatement: T_CONTINUE IdentifierReference T_AUTOMATIC_SEMICOLON; +ContinueStatement: T_CONTINUE IdentifierReference T_SEMICOLON; /. -case $rule_number: { - 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 $rule_number: { + AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); + node->continueToken = loc(1); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ - -DefaultClause: T_DEFAULT T_COLON StatementListOpt ; + +BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON; +BreakStatement: T_BREAK T_SEMICOLON; /. -case $rule_number: { - AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); - node->defaultToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); + node->breakToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ -LabelledStatement: IdentifierReference T_COLON Statement ; +BreakStatement: T_BREAK IdentifierReference T_AUTOMATIC_SEMICOLON; +BreakStatement: T_BREAK IdentifierReference T_SEMICOLON; /. -case $rule_number: { - 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 $rule_number: { + AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); + node->breakToken = loc(1); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ -ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ThrowStatement: T_THROW Expression T_SEMICOLON ; +ReturnStatement: T_RETURN ExpressionOpt_In T_AUTOMATIC_SEMICOLON; +ReturnStatement: T_RETURN ExpressionOpt_In T_SEMICOLON; /. -case $rule_number: { - AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); - node->throwToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + if (!functionNestingLevel) { + syntaxError(loc(1), "Return statement not allowed outside of Function declaration."); + return false; + } + AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); + node->returnToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ -TryStatement: T_TRY Block Catch ; +WithStatement: T_WITH T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); - node->tryToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + sym(1).Node = node; + } break; ./ -TryStatement: T_TRY Block Finally ; +SwitchStatement: T_SWITCH T_LPAREN Expression_In T_RPAREN CaseBlock; /. -case $rule_number: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); - node->tryToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + 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); + sym(1).Node = node; + } break; ./ -TryStatement: T_TRY Block Catch Finally ; +CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE; /. -case $rule_number: { - 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 $rule_number: { + AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -Catch: T_CATCH T_LPAREN IdentifierReference T_RPAREN Block ; +CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE; /. -case $rule_number: { - AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block); - node->catchToken = loc(1); - node->lparenToken = loc(2); - node->identifierToken = loc(3); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + 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; ./ -Finally: T_FINALLY Block ; +CaseClauses: CaseClause; /. -case $rule_number: { - AST::Finally *node = new (pool) AST::Finally(sym(2).Block); - node->finallyToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); + } break; ./ -DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -DebuggerStatement: T_DEBUGGER T_SEMICOLON ; +CaseClauses: CaseClauses CaseClause; /. -case $rule_number: { - AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); - node->debuggerToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); + } break; ./ --- tell the parser to prefer function declarations to function expressions. --- That is, the `Function' symbol is used to mark the start of a function --- declaration. -Function: T_FUNCTION %prec REDUCE_HERE ; - -FunctionDeclaration: Function IdentifierReference T_LPAREN FormalParameters T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +CaseClausesOpt: ; /. -case $rule_number: { - 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); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -FunctionExpression: T_FUNCTION IdentifierReference T_LPAREN FormalParameters T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +CaseClausesOpt: CaseClauses; /. -case $rule_number: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); - node->functionToken = loc(1); - if (! stringRef(2).isNull()) - node->identifierToken = loc(2); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).CaseClauses->finish(); + } break; ./ -FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +CaseClause: T_CASE Expression_In T_COLON StatementListOpt; /. -case $rule_number: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody); - node->functionToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + 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; ./ -FormalParameters : ; +DefaultClause: T_DEFAULT T_COLON StatementListOpt; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); + node->defaultToken = loc(1); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -FormalParameters: FormalParameterList ; +LabelledStatement: IdentifierReference T_COLON LabelledItem; /. -case $rule_number: { - sym(1).Node = sym(1).FormalParameterList->finish (); -} break; + case $rule_number: { + 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; ./ -FormalsList: BindingElement ; -/. case $rule_number: ./ +LabelledItem: Statement; -FormalParameterList: BindingRestElement ; +LabelledItem: ExpressionStatementLookahead T_FORCE_DECLARATION FunctionDeclaration; /. -case $rule_number: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(nullptr, sym(1).Node); - sym(1).Node = node; -} break; + case $rule_number: { + syntaxError(loc(3), "FunctionDeclarations are not allowed after a label."); + return false; + } break; ./ -FormalParameterList: FormalsList ; - -FormalParameterList: FormalsList T_COMMA BindingRestElement ; -/. case $rule_number: ./ - -FormalsList: FormalsList T_COMMA BindingElement ; +ThrowStatement: T_THROW Expression_In T_AUTOMATIC_SEMICOLON; +ThrowStatement: T_THROW Expression_In T_SEMICOLON; /. -case $rule_number: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, sym(3).Node); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); + node->throwToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ -BindingRestElement: T_ELLIPSIS BindingIdentifier ; +TryStatement: T_TRY Block Catch; /. -case $rule_number: { - AST::BindingRestElement *node = new (pool) AST::BindingRestElement(stringRef(2)); - node->identifierToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); + node->tryToken = loc(1); + sym(1).Node = node; + } break; ./ -BindingRestElementOpt: ; -BindingRestElementOpt: BindingRestElement ; +TryStatement: T_TRY Block Finally; +/. + case $rule_number: { + AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); + node->tryToken = loc(1); + sym(1).Node = node; + } break; +./ -BindingElement: BindingIdentifier InitializerOpt ; +TryStatement: T_TRY Block Catch Finally; /. -case $rule_number: { - AST::BindingElement *node = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + 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; ./ -BindingElement: BindingPattern InitializerOpt ; +Catch: T_CATCH T_LPAREN CatchParameter T_RPAREN Block; /. -case $rule_number: { - AST::BindingElement *node = new (pool) AST::BindingElement(sym(1).Node, sym(2).Expression); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block); + node->catchToken = loc(1); + node->lparenToken = loc(2); + node->identifierToken = loc(3); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -BindingPattern: ObjectBindingPattern ; +Finally: T_FINALLY Block; +/. + case $rule_number: { + AST::Finally *node = new (pool) AST::Finally(sym(2).Block); + node->finallyToken = loc(1); + sym(1).Node = node; + } break; +./ -BindingPattern: ArrayBindingPattern ; +CatchParameter: BindingIdentifier; +CatchParameter: BindingPattern; -ObjectBindingPattern: T_LBRACE T_RBRACE ; +DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON; -- automatic semicolon +DebuggerStatement: T_DEBUGGER T_SEMICOLON; /. -case $rule_number: { - sym(1).Node = nullptr; -} break; + case $rule_number: { + AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); + node->debuggerToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ -ObjectBindingPattern: T_LBRACE BindingPropertyList T_RBRACE ; -/. case $rule_number: ./ -ObjectBindingPattern: T_LBRACE BindingPropertyList T_COMMA T_RBRACE ; +-- tell the parser to prefer function declarations to function expressions. +-- That is, the `Function' symbol is used to mark the start of a function +-- declaration. +-- This is still required for parsing QML, where MemberExpression and FunctionDeclaration would +-- otherwise conflict. +Function: T_FUNCTION %prec REDUCE_HERE; + +FunctionDeclaration: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - sym(1).Node = sym(2).BindingPropertyList->finish(); -} break; + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + node->identifierToken = loc(2); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + sym(1).Node = node; + } break; ./ -ArrayBindingPattern: T_LBRACKET ElisionOpt BindingRestElementOpt T_RBRACKET ; + +FunctionDeclaration_Default: FunctionDeclaration; +FunctionDeclaration_Default: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::BindingElementList *l = new (pool) AST::BindingElementList(sym(4).Elision, sym(5).Node); - sym(1).Node = l->finish(); -} break; + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList); + node->functionToken = loc(1); + node->identifierToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; + } break; ./ -ArrayBindingPattern: T_LBRACKET BindingElementList T_RBRACKET ; +FunctionExpression: T_FUNCTION BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - sym(1).Node = sym(2).BindingElementList->finish(); -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + if (! stringRef(2).isNull()) + node->identifierToken = loc(2); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + sym(1).Node = node; + } break; ./ -ArrayBindingPattern: T_LBRACKET BindingElementList T_COMMA ElisionOpt BindingRestElementOpt T_RBRACKET ; +FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::BindingElementList *l = new (pool) AST::BindingElementList(sym(4).Elision, sym(5).Node); - l = sym(2).BindingElementList->append(l); - sym(1).Node = l->finish(); -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList); + node->functionToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; + } break; ./ -BindingPropertyList: BindingProperty ; +StrictFormalParameters: FormalParameters; -BindingPropertyList: BindingPropertyList T_COMMA BindingProperty ; +FormalParameters: ; /. -case $rule_number: { - sym(1).Node = sym(1).BindingPropertyList->append(sym(3).BindingPropertyList); -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -BindingElementList: BindingElisionElement ; -BindingElementList: BindingElementList T_COMMA BindingElisionElement ; +FormalParameters: FormalParameterList; /. -case $rule_number: { - sym(1).BindingElementList->append(sym(3).BindingElementList); -} break; + case $rule_number: { + sym(1).Node = sym(1).FormalParameterList->finish(); + } break; ./ -BindingElisionElement: ElisionOpt BindingElement ; +FormalsList: BindingElement; +/. case $rule_number: ./ + +FormalParameterList: BindingRestElement; /. -case $rule_number: { - sym(1).Node = new (pool) AST::BindingElementList(sym(1).Elision, sym(2).BindingElement); -} break; + case $rule_number: { + AST::FormalParameterList *node = new (pool) AST::FormalParameterList(nullptr, sym(1).Node); + sym(1).Node = node; + } break; ./ +FormalParameterList: FormalsList; -BindingProperty: BindingIdentifier InitializerOpt ; +FormalParameterList: FormalsList T_COMMA BindingRestElement; +/. case $rule_number: ./ + +FormalsList: FormalsList T_COMMA BindingElement; /. -case $rule_number: { - AST::StringLiteralPropertyName *name = new (pool) AST::StringLiteralPropertyName(stringRef(1)); - AST::BindingElement *e = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression); - AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(name, e); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, sym(3).Node); + sym(1).Node = node; + } break; ./ -BindingProperty: PropertyName T_COLON BindingElement ; +FormalParameter: BindingElement; + +FunctionLBrace: T_LBRACE; /. -case $rule_number: { - AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(sym(1).PropertyName, sym(3).BindingElement); - sym(1).Node = node; -} break; + case $rule_number: { + ++functionNestingLevel; + } break; ./ -BindingIdentifier: IdentifierReference; +FunctionRBrace: T_RBRACE; +/. + case $rule_number: { + --functionNestingLevel; + } break; +./ + + +FunctionBody: FunctionStatementList; +FunctionStatementList: StatementListOpt; -FunctionBodyOpt: ; +ArrowFunction: ArrowParameters T_ARROW ConciseBody; +/. case $rule_number: { UNIMPLEMENTED; } ./ +ArrowFunction_In: ArrowParameters T_ARROW ConciseBody_In; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +ArrowParameters: BindingIdentifier; + +ArrowParameters: CoverParenthesizedExpressionAndArrowParameterList; + +-- ### CoverParenthesizedExpressionAndArrowParameterList for ArrowParameters refined to: +-- ArrowFormalParameters[Yield]: (StrictFormalParameters[?Yield]) + +ConciseBodyLookahead: ; +/: +#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + if (lookaheadToken(lexer) == T_LBRACE) + pushToken(T_FORCE_BLOCK); + } break; ./ -FunctionBodyOpt: FunctionBody ; +ConciseBody: ConciseBodyLookahead AssignmentExpression; -- [lookahead ≠ {] +ConciseBody_In: ConciseBodyLookahead AssignmentExpression_In; -- [lookahead ≠ {] +ConciseBody: ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace; +ConciseBody_In: ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace; + +MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +MethodDefinition: GeneratorMethod; -FunctionBody: SourceElements ; +MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ()); -} break; + case $rule_number: { + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(sym(2).PropertyName, sym(6).StatementList); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; + } break; +./ + +MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; +/. + case $rule_number: { + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( + sym(2).PropertyName, sym(4).FormalParameterList, sym(7).StatementList); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + sym(1).Node = node; + } break; ./ -Program: Empty ; -Program: SourceElements ; +PropertySetParameterList: FormalParameter; /. -case $rule_number: { - sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ()); -} break; + case $rule_number: { + AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(nullptr, sym(1).Node))->finish(); + sym(1).Node = node; + } break; ./ -SourceElements: SourceElement ; +GeneratorLBrace: T_LBRACE; /. -case $rule_number: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement); -} break; + case $rule_number: { + ++functionNestingLevel; + lexer->enterGeneratorBody(); + } break; ./ -SourceElements: SourceElements SourceElement ; +GeneratorRBrace: T_RBRACE; /. -case $rule_number: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement); -} break; + case $rule_number: { + --functionNestingLevel; + lexer->leaveGeneratorBody(); + } break; ./ -SourceElement: Statement ; +GeneratorMethod: T_STAR PropertyName T_LPAREN StrictFormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +GeneratorDeclaration: T_FUNCTION T_STAR BindingIdentifier T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +GeneratorDeclaration_Default: GeneratorDeclaration; +GeneratorDeclaration_Default: T_FUNCTION T_STAR T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +GeneratorExpression: T_FUNCTION T_STAR BindingIdentifier T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ +GeneratorExpression: T_FUNCTION T_STAR T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +GeneratorBody: FunctionBody; + +YieldExpression: T_YIELD T_STAR AssignmentExpression; +YieldExpression_In: T_YIELD T_STAR AssignmentExpression_In; +YieldExpression: T_YIELD AssignmentExpression; +YieldExpression_In: T_YIELD AssignmentExpression_In; + + +ClassDeclaration: T_CLASS BindingIdentifier ClassTail; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +ClassDeclaration_Default: ClassDeclaration; +ClassDeclaration_Default: T_CLASS ClassTail; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +ClassExpression: T_CLASS BindingIdentifier ClassTail; + +ClassExpression: T_CLASS ClassTail; + +ClassTail: T_LBRACE ClassBodyOpt T_RBRACE; +ClassTail: ClassHeritage T_LBRACE ClassBodyOpt T_RBRACE; + +ClassHeritage: T_EXTENDS LeftHandSideExpression; + +ClassBody: ClassElementList; + +ClassBodyOpt: ; + +ClassBodyOpt: ClassBody; + +ClassElementList: ClassElement; +ClassElementList: ClassElementList ClassElement; + +ClassElement: MethodDefinition; +ClassElement: T_STATIC MethodDefinition; +ClassElement: T_SEMICOLON; + +-- Scripts and Modules + +Script: ; /. -case $rule_number: { - sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement); -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -SourceElement: FunctionDeclaration ; +Script: ScriptBody; + +ScriptBody: StatementList; /. -case $rule_number: { - sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::Program(sym(1).StatementList->finish()); + } break; ./ -PropertyAssignmentListOpt: ; +Module: ModuleBodyOpt; +/. case $rule_number: { UNIMPLEMENTED; } ./ + +ModuleBody: ModuleItemList; + +ModuleBodyOpt: ; +ModuleBodyOpt: ModuleBody; + +ModuleItemList: ModuleItem; +ModuleItemList: ModuleItemList ModuleItem; + +ModuleItem: ImportDeclaration T_AUTOMATIC_SEMICOLON; +ModuleItem: ImportDeclaration T_SEMICOLON; +ModuleItem: ExportDeclaration T_AUTOMATIC_SEMICOLON; +ModuleItem: ExportDeclaration T_SEMICOLON; +ModuleItem: StatementListItem; + +ImportDeclaration: T_IMPORT ImportClause FromClause; +ImportDeclaration: T_IMPORT ModuleSpecifier; + +ImportClause: ImportedDefaultBinding; +ImportClause: NameSpaceImport; +ImportClause: NamedImports; +ImportClause: ImportedDefaultBinding T_COMMA NameSpaceImport; +ImportClause: ImportedDefaultBinding T_COMMA NamedImports; + +ImportedDefaultBinding: ImportedBinding; + +NameSpaceImport: T_STAR T_AS ImportedBinding; + +NamedImports: T_LBRACE T_RBRACE; +NamedImports: T_LBRACE ImportsList T_RBRACE; +NamedImports: T_LBRACE ImportsList T_COMMA T_RBRACE; + +FromClause: T_FROM ModuleSpecifier; + +ImportsList: ImportSpecifier; +ImportsList: ImportsList T_COMMA ImportSpecifier; + +ImportSpecifier: ImportedBinding; +ImportSpecifier: IdentifierName T_AS ImportedBinding; + +ModuleSpecifier: T_STRING_LITERAL; + +ImportedBinding: BindingIdentifier; + +ExportDeclarationLookahead: ; +/: +#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + int token = lookaheadToken(lexer); + if (token == T_FUNCTION || token == T_CLASS) + pushToken(T_FORCE_DECLARATION); + } break; ./ -PropertyAssignmentListOpt: PropertyAssignmentList ; +ExportDeclaration: T_EXPORT T_STAR FromClause; +ExportDeclaration: T_EXPORT ExportClause FromClause; +ExportDeclaration: T_EXPORT ExportClause; +ExportDeclaration: T_EXPORT VariableStatement; +ExportDeclaration: T_EXPORT Declaration; +ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION HoistableDeclaration_Default; +ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION ClassDeclaration_Default; +ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead AssignmentExpression_In; -- [lookahead ∉ { function, class }] + +ExportClause: T_LBRACE T_RBRACE; +ExportClause: T_LBRACE ExportsList T_RBRACE; +ExportClause: T_LBRACE ExportsList T_COMMA T_RBRACE; + +ExportsList: ExportSpecifier; +ExportsList: ExportsList T_COMMA ExportSpecifier; + +ExportSpecifier: IdentifierName; +ExportSpecifier: IdentifierName T_AS IdentifierName; + +-- Old top level code /. + // ------------ end of switch statement } // switch action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT); } // if @@ -3303,8 +3697,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ; for (int tk = 1; tk < TERMINAL_COUNT; ++tk) { if (tk == T_AUTOMATIC_SEMICOLON || tk == T_FEED_UI_PROGRAM || - tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION || - tk == T_FEED_JS_SOURCE_ELEMENT) + tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION) continue; int a = t_action(errorState, tk); diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index 8b253abbef..f78e48e66a 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -242,10 +242,10 @@ void PropertyGetterSetter::accept0(Visitor *visitor) visitor->endVisit(this); } -void PropertyAssignmentList::accept0(Visitor *visitor) +void PropertyDefinitionList::accept0(Visitor *visitor) { if (visitor->visit(this)) { - for (PropertyAssignmentList *it = this; it; it = it->next) { + for (PropertyDefinitionList *it = this; it; it = it->next) { accept(it->assignment, visitor); } } @@ -823,48 +823,10 @@ FormalParameterList *FormalParameterList::finish() return front; } -void FunctionBody::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - accept(elements, visitor); - } - - visitor->endVisit(this); -} - void Program::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(elements, visitor); - } - - visitor->endVisit(this); -} - -void SourceElements::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - for (SourceElements *it = this; it; it = it->next) { - accept(it->element, visitor); - } - } - - visitor->endVisit(this); -} - -void FunctionSourceElement::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - accept(declaration, visitor); - } - - visitor->endVisit(this); -} - -void StatementSourceElement::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - accept(statement, visitor); + accept(statements, visitor); } visitor->endVisit(this); @@ -1115,6 +1077,24 @@ void BindingPropertyList::boundNames(QStringList *names) it->binding->boundNames(names); } +void ObjectBindingPattern::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(properties, visitor); + } + + visitor->endVisit(this); +} + +void ArrayBindingPattern::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(elements, visitor); + } + + visitor->endVisit(this); +} + } } // namespace QQmlJS::AST QT_QML_END_NAMESPACE diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 52f6aeb1a2..6c8a5c7af6 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -156,7 +156,6 @@ public: Kind_FunctionBody, Kind_FunctionDeclaration, Kind_FunctionExpression, - Kind_FunctionSourceElement, Kind_IdentifierExpression, Kind_IdentifierPropertyName, Kind_IfStatement, @@ -175,16 +174,13 @@ public: Kind_PreDecrementExpression, Kind_PreIncrementExpression, Kind_Program, - Kind_PropertyAssignmentList, + Kind_PropertyDefinitionList, Kind_PropertyGetterSetter, Kind_PropertyName, Kind_PropertyNameAndValue, Kind_RegExpLiteral, Kind_ReturnStatement, - Kind_SourceElement, - Kind_SourceElements, Kind_StatementList, - Kind_StatementSourceElement, Kind_StringLiteral, Kind_StringLiteralPropertyName, Kind_SwitchStatement, @@ -205,6 +201,8 @@ public: Kind_WhileStatement, Kind_WithStatement, Kind_NestedExpression, + Kind_ArrayBindingPattern, + Kind_ObjectBindingPattern, Kind_BindingElement, Kind_BindingElementList, Kind_BindingPropertyList, @@ -447,14 +445,14 @@ public: { return literalToken; } SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : literalToken; } + { return next ? next->lastSourceLocation() : (expression ? expression->lastSourceLocation() : literalToken); } void accept0(Visitor *visitor) override; QStringRef value; ExpressionNode *expression; - SourceLocation literalToken; TemplateLiteral *next; + SourceLocation literalToken; }; class QML_PARSER_EXPORT RegExpLiteral: public ExpressionNode @@ -520,7 +518,7 @@ public: ObjectLiteral() { kind = K; } - ObjectLiteral(PropertyAssignmentList *plist): + ObjectLiteral(PropertyDefinitionList *plist): properties (plist) { kind = K; } void accept0(Visitor *visitor) override; @@ -532,7 +530,7 @@ public: { return rbraceToken; } // attributes - PropertyAssignmentList *properties = nullptr; + PropertyDefinitionList *properties = nullptr; SourceLocation lbraceToken; SourceLocation rbraceToken; }; @@ -638,27 +636,34 @@ public: SourceLocation propertyNameToken; }; -class QML_PARSER_EXPORT PropertyAssignment: public Node +class QML_PARSER_EXPORT PropertyDefinition: public Node { public: - PropertyAssignment(PropertyName *n) + PropertyDefinition(PropertyName *n) : name(n) {} + + SourceLocation firstSourceLocation() const override + { return name->firstSourceLocation(); } + + SourceLocation lastSourceLocation() const override + { return name->lastSourceLocation(); } + // attributes PropertyName *name; }; -class QML_PARSER_EXPORT PropertyAssignmentList: public Node +class QML_PARSER_EXPORT PropertyDefinitionList: public Node { public: - QQMLJS_DECLARE_AST_NODE(PropertyAssignmentList) + QQMLJS_DECLARE_AST_NODE(PropertyDefinitionList) - PropertyAssignmentList(PropertyAssignment *assignment) + PropertyDefinitionList(PropertyDefinition *assignment) : assignment(assignment) , next(this) { kind = K; } - PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment) + PropertyDefinitionList(PropertyDefinitionList *previous, PropertyDefinition *assignment) : assignment(assignment) { kind = K; @@ -666,9 +671,9 @@ public: previous->next = this; } - inline PropertyAssignmentList *finish () + inline PropertyDefinitionList *finish () { - PropertyAssignmentList *front = next; + PropertyDefinitionList *front = next; next = nullptr; return front; } @@ -682,18 +687,18 @@ public: { return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); } // attributes - PropertyAssignment *assignment; - PropertyAssignmentList *next; + PropertyDefinition *assignment; + PropertyDefinitionList *next; SourceLocation commaToken; }; -class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment +class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyDefinition { public: QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue) PropertyNameAndValue(PropertyName *n, ExpressionNode *v) - : PropertyAssignment(n), value(v) + : PropertyDefinition(n), value(v) { kind = K; } void accept0(Visitor *visitor) override; @@ -710,7 +715,7 @@ public: SourceLocation commaToken; }; -class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment +class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyDefinition { public: QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter) @@ -720,12 +725,12 @@ public: Setter }; - PropertyGetterSetter(PropertyName *n, FunctionBody *b) - : PropertyAssignment(n), type(Getter), formals(nullptr), functionBody (b) + PropertyGetterSetter(PropertyName *n, StatementList *b) + : PropertyDefinition(n), type(Getter), formals(nullptr), functionBody(b) { kind = K; } - PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b) - : PropertyAssignment(n), type(Setter), formals(f), functionBody (b) + PropertyGetterSetter(PropertyName *n, FormalParameterList *f, StatementList *b) + : PropertyDefinition(n), type(Setter), formals(f), functionBody(b) { kind = K; } void accept0(Visitor *visitor) override; @@ -743,7 +748,7 @@ public: FormalParameterList *formals; SourceLocation rparenToken; SourceLocation lbraceToken; - FunctionBody *functionBody; + StatementList *functionBody; SourceLocation rbraceToken; }; @@ -1308,22 +1313,21 @@ class QML_PARSER_EXPORT StatementList: public Node public: QQMLJS_DECLARE_AST_NODE(StatementList) - StatementList(Statement *stmt): - statement (stmt), next (this) - { kind = K; } + // ### This should be a Statement, but FunctionDeclaration currently doesn't inherit it. + StatementList(Node *stmt) + : statement(stmt), next (this) + { kind = K; } - StatementList(StatementList *previous, Statement *stmt): - statement (stmt) - { - kind = K; - next = previous->next; - previous->next = this; + StatementList *append(StatementList *n) { + n->next = next; + next = n; + return n; } void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override - { return statement->firstSourceLocation(); } + { return statement ? statement->firstSourceLocation() : statement->firstSourceLocation(); } SourceLocation lastSourceLocation() const override { return next ? next->lastSourceLocation() : statement->lastSourceLocation(); } @@ -1336,33 +1340,10 @@ public: } // attributes - Statement *statement; + Node *statement = nullptr; StatementList *next; }; -class QML_PARSER_EXPORT VariableStatement: public Statement -{ -public: - QQMLJS_DECLARE_AST_NODE(VariableStatement) - - VariableStatement(VariableDeclarationList *vlist): - declarations (vlist) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return declarationKindToken; } - - SourceLocation lastSourceLocation() const override - { return semicolonToken; } - -// attributes - VariableDeclarationList *declarations; - SourceLocation declarationKindToken; - SourceLocation semicolonToken; -}; - class QML_PARSER_EXPORT VariableDeclaration: public Node { public: @@ -1441,6 +1422,28 @@ public: SourceLocation commaToken; }; +class QML_PARSER_EXPORT VariableStatement: public Statement +{ +public: + QQMLJS_DECLARE_AST_NODE(VariableStatement) + + VariableStatement(VariableDeclarationList *vlist): + declarations (vlist) + { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return declarationKindToken; } + + SourceLocation lastSourceLocation() const override + { return declarations->lastSourceLocation(); } + +// attributes + VariableDeclarationList *declarations; + SourceLocation declarationKindToken; +}; + class QML_PARSER_EXPORT EmptyStatement: public Statement { public: @@ -1474,7 +1477,7 @@ public: { return expression->firstSourceLocation(); } SourceLocation lastSourceLocation() const override - { return semicolonToken; } + { return expression->lastSourceLocation(); } // attributes ExpressionNode *expression; @@ -2044,7 +2047,7 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode public: QQMLJS_DECLARE_AST_NODE(FunctionExpression) - FunctionExpression(const QStringRef &n, FormalParameterList *f, FunctionBody *b): + FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b): name (n), formals (f), body (b) { kind = K; } @@ -2059,7 +2062,7 @@ public: // attributes QStringRef name; FormalParameterList *formals; - FunctionBody *body; + StatementList *body; SourceLocation functionToken; SourceLocation identifierToken; SourceLocation lparenToken; @@ -2090,6 +2093,48 @@ public: QStringRef name; }; +class QML_PARSER_EXPORT BindingPattern : public Node +{ +public: + + SourceLocation firstSourceLocation() const override + { return first; } + + SourceLocation lastSourceLocation() const override + { return last; } + + SourceLocation first; + SourceLocation last; +}; + +class QML_PARSER_EXPORT ObjectBindingPattern : public BindingPattern +{ +public: + QQMLJS_DECLARE_AST_NODE(ObjectBindingPattern) + + ObjectBindingPattern(BindingPropertyList *p) + : properties(p) + { kind = K; } + + void accept0(Visitor *visitor) override; + + BindingPropertyList *properties; +}; + +class QML_PARSER_EXPORT ArrayBindingPattern : public BindingPattern +{ +public: + QQMLJS_DECLARE_AST_NODE(ArrayBindingPattern) + + ArrayBindingPattern(BindingElementList *e) + : elements(e) + { kind = K; } + + void accept0(Visitor *visitor) override; + + BindingElementList *elements; +}; + class QML_PARSER_EXPORT BindingElement : public Node { public: @@ -2099,7 +2144,7 @@ public: : name(n.toString()), initializer(i) { kind = K; } - BindingElement(Node *binding, ExpressionNode *i = nullptr) + BindingElement(BindingPattern *binding, ExpressionNode *i = nullptr) : binding(binding), initializer(i) { kind = K; } @@ -2111,14 +2156,20 @@ public: SourceLocation lastSourceLocation() const override { return initializer ? initializer->lastSourceLocation() : (binding ? binding->lastSourceLocation() : identifierToken); } - BindingElementList *elementList() const { return cast<BindingElementList *>(binding); } - BindingPropertyList *propertyList() const { return cast<BindingPropertyList *>(binding); } + BindingElementList *elementList() const { + ArrayBindingPattern *p = cast<ArrayBindingPattern *>(binding); + return p ? p->elements : nullptr; + } + BindingPropertyList *propertyList() const { + ObjectBindingPattern *p = cast<ObjectBindingPattern *>(binding); + return p ? p->properties : nullptr; + } void boundNames(QStringList *names); // attributes SourceLocation identifierToken; - Node *binding = nullptr; + BindingPattern *binding = nullptr; QString name; ExpressionNode *initializer = nullptr; }; @@ -2161,7 +2212,7 @@ public: { return elision ? elision->firstSourceLocation() : param->firstSourceLocation(); } SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : param->lastSourceLocation(); } + { return next ? next->lastSourceLocation() : (param ? param->lastSourceLocation() : elision->lastSourceLocation()); } Elision *elision = nullptr; Node *param = nullptr; @@ -2210,7 +2261,7 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression public: QQMLJS_DECLARE_AST_NODE(FunctionDeclaration) - FunctionDeclaration(const QStringRef &n, FormalParameterList *f, FunctionBody *b): + FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b): FunctionExpression(n, f, b) { kind = K; } @@ -2296,134 +2347,25 @@ public: FormalParameterList *next; }; -class QML_PARSER_EXPORT SourceElement: public Node -{ -public: - QQMLJS_DECLARE_AST_NODE(SourceElement) - - inline SourceElement() - { kind = K; } -}; - -class QML_PARSER_EXPORT SourceElements: public Node -{ -public: - QQMLJS_DECLARE_AST_NODE(SourceElements) - - SourceElements(SourceElement *elt): - element (elt), next (this) - { kind = K; } - - SourceElements(SourceElements *previous, SourceElement *elt): - element (elt) - { - kind = K; - next = previous->next; - previous->next = this; - } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return element->firstSourceLocation(); } - - SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : element->lastSourceLocation(); } - - inline SourceElements *finish () - { - SourceElements *front = next; - next = nullptr; - return front; - } - -// attributes - SourceElement *element; - SourceElements *next; -}; - -class QML_PARSER_EXPORT FunctionBody: public Node -{ -public: - QQMLJS_DECLARE_AST_NODE(FunctionBody) - - FunctionBody(SourceElements *elts): - elements (elts) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return elements ? elements->firstSourceLocation() : SourceLocation(); } - - SourceLocation lastSourceLocation() const override - { return elements ? elements->lastSourceLocation() : SourceLocation(); } - -// attributes - SourceElements *elements; -}; - class QML_PARSER_EXPORT Program: public Node { public: QQMLJS_DECLARE_AST_NODE(Program) - Program(SourceElements *elts): - elements (elts) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return elements ? elements->firstSourceLocation() : SourceLocation(); } - - SourceLocation lastSourceLocation() const override - { return elements ? elements->lastSourceLocation() : SourceLocation(); } - -// attributes - SourceElements *elements; -}; - -class QML_PARSER_EXPORT FunctionSourceElement: public SourceElement -{ -public: - QQMLJS_DECLARE_AST_NODE(FunctionSourceElement) - - FunctionSourceElement(FunctionDeclaration *f): - declaration (f) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return declaration->firstSourceLocation(); } - - SourceLocation lastSourceLocation() const override - { return declaration->lastSourceLocation(); } - -// attributes - FunctionDeclaration *declaration; -}; - -class QML_PARSER_EXPORT StatementSourceElement: public SourceElement -{ -public: - QQMLJS_DECLARE_AST_NODE(StatementSourceElement) - - StatementSourceElement(Statement *stmt): - statement (stmt) - { kind = K; } + Program(StatementList *statements) + : statements(statements) + { kind = K; } void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override - { return statement->firstSourceLocation(); } + { return statements ? statements->firstSourceLocation() : SourceLocation(); } SourceLocation lastSourceLocation() const override - { return statement->lastSourceLocation(); } + { return statements ? statements->lastSourceLocation() : SourceLocation(); } // attributes - Statement *statement; + StatementList *statements; }; class QML_PARSER_EXPORT DebuggerStatement: public Statement diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h index 7a8bdf1b63..89245f4884 100644 --- a/src/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/parser/qqmljsastfwd_p.h @@ -97,7 +97,7 @@ class ArrayLiteral; class ObjectLiteral; class ElementList; class Elision; -class PropertyAssignmentList; +class PropertyDefinitionList; class PropertyGetterSetter; class PropertyNameAndValue; class PropertyName; @@ -156,14 +156,12 @@ class Finally; class FunctionDeclaration; class FunctionExpression; class FormalParameterList; -class FunctionBody; class Program; -class SourceElements; -class SourceElement; -class FunctionSourceElement; -class StatementSourceElement; class DebuggerStatement; class NestedExpression; +class BindingPattern; +class ArrayBindingPattern; +class ObjectBindingPattern; class BindingElement; class BindingElementList; class BindingPropertyList; diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h index d0b9cc24bc..1c11ee9c02 100644 --- a/src/qml/parser/qqmljsastvisitor_p.h +++ b/src/qml/parser/qqmljsastvisitor_p.h @@ -146,8 +146,8 @@ public: virtual bool visit(Elision *) { return true; } virtual void endVisit(Elision *) {} - virtual bool visit(PropertyAssignmentList *) { return true; } - virtual void endVisit(PropertyAssignmentList *) {} + virtual bool visit(PropertyDefinitionList *) { return true; } + virtual void endVisit(PropertyDefinitionList *) {} virtual bool visit(PropertyNameAndValue *) { return true; } virtual void endVisit(PropertyNameAndValue *) {} @@ -320,6 +320,12 @@ public: virtual bool visit(FunctionExpression *) { return true; } virtual void endVisit(FunctionExpression *) {} + virtual bool visit(ObjectBindingPattern *) { return true; } + virtual void endVisit(ObjectBindingPattern *) {} + + virtual bool visit(ArrayBindingPattern *) { return true; } + virtual void endVisit(ArrayBindingPattern *) {} + virtual bool visit(BindingElement *) { return true; } virtual void endVisit(BindingElement *) {} @@ -335,21 +341,9 @@ public: virtual bool visit(FormalParameterList *) { return true; } virtual void endVisit(FormalParameterList *) {} - virtual bool visit(FunctionBody *) { return true; } - virtual void endVisit(FunctionBody *) {} - virtual bool visit(Program *) { return true; } virtual void endVisit(Program *) {} - virtual bool visit(SourceElements *) { return true; } - virtual void endVisit(SourceElements *) {} - - virtual bool visit(FunctionSourceElement *) { return true; } - virtual void endVisit(FunctionSourceElement *) {} - - virtual bool visit(StatementSourceElement *) { return true; } - virtual void endVisit(StatementSourceElement *) {} - virtual bool visit(DebuggerStatement *) { return true; } virtual void endVisit(DebuggerStatement *) {} }; diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h index f20f341b7b..e2ae66d796 100644 --- a/src/qml/parser/qqmljskeywords_p.h +++ b/src/qml/parser/qqmljskeywords_p.h @@ -186,6 +186,15 @@ static inline int classify4(const QChar *s, int parseModeFlags) { } } } + else if (s[0].unicode() == 'f') { + if (s[1].unicode() == 'r') { + if (s[2].unicode() == 'o') { + if (s[3].unicode() == 'm') { + return int(Lexer::T_FROM); + } + } + } + } else if (s[0].unicode() == 'g') { if (s[1].unicode() == 'o') { if (s[2].unicode() == 't') { @@ -334,7 +343,7 @@ static inline int classify5(const QChar *s, int parseModeFlags) { if (s[2].unicode() == 'p') { if (s[3].unicode() == 'e') { if (s[4].unicode() == 'r') { - return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD); + return int(Lexer::T_SUPER); } } } diff --git a/src/qml/parser/qqmljslexer_p.h b/src/qml/parser/qqmljslexer_p.h index 112f3b169a..3dc1339cd1 100644 --- a/src/qml/parser/qqmljslexer_p.h +++ b/src/qml/parser/qqmljslexer_p.h @@ -73,10 +73,7 @@ public: 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_EXPORT = T_RESERVED_WORD, - T_EXTENDS = T_RESERVED_WORD, T_FINAL = T_RESERVED_WORD, T_FLOAT = T_RESERVED_WORD, T_GOTO = T_RESERVED_WORD, @@ -89,8 +86,6 @@ public: 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, diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp index 4ce0f9fd89..17a99d6a43 100644 --- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp +++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp @@ -481,7 +481,7 @@ void tst_qv4debugger::conditionalBreakPoint() QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 2); + QCOMPARE(frame0.size(), 3); QVERIFY(frame0.contains("i")); QCOMPARE(frame0.value("i").toInt(), 11); } @@ -540,7 +540,7 @@ void tst_qv4debugger::readArguments() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 4); + QCOMPARE(frame0.size(), 5); QVERIFY(frame0.contains(QStringLiteral("a"))); QCOMPARE(frame0.type(QStringLiteral("a")), QStringLiteral("number")); QCOMPARE(frame0.value(QStringLiteral("a")).toDouble(), 1.0); @@ -567,7 +567,7 @@ void tst_qv4debugger::readLocals() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 4); // locals and parameters + QCOMPARE(frame0.size(), 5); // locals and parameters QVERIFY(frame0.contains("c")); QCOMPARE(frame0.type("c"), QStringLiteral("number")); QCOMPARE(frame0.value("c").toDouble(), 3.0); @@ -592,7 +592,7 @@ void tst_qv4debugger::readObject() QVERIFY(m_debuggerAgent->m_wasPaused); QVERIFY(m_debuggerAgent->m_capturedScope.size() > 1); const TestAgent::NamedRefs &frame0 = m_debuggerAgent->m_capturedScope.at(0); - QCOMPARE(frame0.size(), 2); + QCOMPARE(frame0.size(), 3); QVERIFY(frame0.contains("b")); QCOMPARE(frame0.type("b"), QStringLiteral("object")); QJsonObject b = frame0.rawValue("b"); @@ -657,7 +657,7 @@ void tst_qv4debugger::readContextInAllFrames() for (int i = 0; i < 12; ++i) { const TestAgent::NamedRefs &scope = m_debuggerAgent->m_capturedScope.at(i); - QCOMPARE(scope.size(), 2); + QCOMPARE(scope.size(), 3); QVERIFY(scope.contains("n")); QCOMPARE(scope.type("n"), QStringLiteral("number")); QCOMPARE(scope.value("n").toDouble(), i + 1.0); diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index 589f25d174..19cec5d294 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -22,12 +22,23 @@ S15.4.4.3_A3_T1 failing S15.5.4.11_A5_T1 failing S15.2.4.4_A14 failing -# Function declarations in conditionals. We allow them, because the real -# world requires them. -Sbp_12.5_A9_T3 failing -Sbp_12.6.1_A13_T3 failing -Sbp_12.6.2_A13_T3 failing -Sbp_12.6.4_A13_T3 failing +# Function declarations in conditionals. ES6 allows them, but the test +# is buggy (using a function declaration without a name) +Sbp_12.5_A9_T3 +Sbp_12.6.1_A13_T3 +Sbp_12.6.2_A13_T3 +Sbp_12.6.4_A13_T3 + +# Function declarations in blocks, allowed in ES6 +Sbp_A1_T1 failing +Sbp_A2_T1 failing +Sbp_A2_T2 failing +Sbp_A3_T1 failing +Sbp_A3_T2 failing +Sbp_A4_T1 failing +Sbp_A4_T2 failing +Sbp_A5_T2 failing + # es6: function length attributes are configurable, wasn't in es5 S15.1.2.2_A9.2 failing diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp index 5941385c80..e1ba6d12c0 100644 --- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp @@ -125,6 +125,8 @@ void tst_qmlmin::initTestCase() invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.6.qml"; invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.1.qml"; invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.2.qml"; + invalidFiles << "tests/auto/qml/parserstress/tests/ecma_3/FunExpr/fe-001.js"; + invalidFiles << "tests/auto/qml/qjsengine/script/com/trolltech/syntaxerror/__init__.js"; } QStringList tst_qmlmin::findFiles(const QDir &d) diff --git a/tests/auto/qml/qqmllanguage/data/property.4.errors.txt b/tests/auto/qml/qqmllanguage/data/property.4.errors.txt index b447186849..2807384ec4 100644 --- a/tests/auto/qml/qqmllanguage/data/property.4.errors.txt +++ b/tests/auto/qml/qqmllanguage/data/property.4.errors.txt @@ -1 +1 @@ -5:1:Syntax error +5:1:Expected token `:' diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp index 5641e6348e..26833d2a08 100644 --- a/tools/qmlmin/main.cpp +++ b/tools/qmlmin/main.cpp @@ -57,15 +57,48 @@ class QmlminLexer: protected Lexer, public Directives QString _fileName; QString _directives; +protected: + QVector<int> _stateStack; + QList<int> _tokens; + QList<QString> _tokenStrings; + int yytoken = -1; + QString yytokentext; + + void lex() { + if (_tokens.isEmpty()) { + _tokens.append(Lexer::lex()); + _tokenStrings.append(tokenText()); + } + + yytoken = _tokens.takeFirst(); + yytokentext = _tokenStrings.takeFirst(); + } + + int lookaheadToken() + { + if (yytoken < 0) + lex(); + return yytoken; + } + + void pushToken(int token) + { + _tokens.prepend(yytoken); + _tokenStrings.prepend(yytokentext); + yytoken = token; + yytokentext = QString(); + } + public: - QmlminLexer(): Lexer(&_engine) {} + QmlminLexer() + : Lexer(&_engine), _stateStack(128) {} virtual ~QmlminLexer() {} QString fileName() const { return _fileName; } bool operator()(const QString &fileName, const QString &code) { - int startToken = T_FEED_JS_PROGRAM; + int startToken = T_FEED_JS_SCRIPT; const QFileInfo fileInfo(fileName); if (fileInfo.suffix().toLower() == QLatin1String("qml")) startToken = T_FEED_UI_PROGRAM; @@ -154,6 +187,24 @@ protected: ruleno == J_SCRIPT_REGEXPLITERAL_RULE2; } + void handleLookaheads(int ruleno) { + if (ruleno == J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE) { + int token = lookaheadToken(); + if (token == T_LBRACE) + pushToken(T_FORCE_BLOCK); + else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST) + pushToken(T_FORCE_DECLARATION); + } else if (ruleno == J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE) { + int token = lookaheadToken(); + if (token == T_LBRACE) + pushToken(T_FORCE_BLOCK); + } else if (ruleno == J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE) { + int token = lookaheadToken(); + if (token == T_FUNCTION || token == T_CLASS) + pushToken(T_FORCE_DECLARATION); + } + } + bool scanRestOfRegExp(int ruleno, QString *restOfRegExp) { if (! scanRegExp(ruleno == J_SCRIPT_REGEXPLITERAL_RULE1 ? Lexer::NoPrefix : Lexer::EqualPrefix)) @@ -187,9 +238,6 @@ protected: class Minify: public QmlminLexer { - QVector<int> _stateStack; - QList<int> _tokens; - QList<QString> _tokenStrings; QString _minifiedCode; int _maxWidth; int _width; @@ -206,7 +254,7 @@ protected: }; Minify::Minify(int maxWidth) - : _stateStack(128), _maxWidth(maxWidth), _width(0) + : _maxWidth(maxWidth), _width(0) { } @@ -250,16 +298,14 @@ void Minify::escape(const QChar &ch, QString *out) bool Minify::parse(int startToken) { int yyaction = 0; - int yytoken = -1; int yytos = -1; - QString yytokentext; QString assembled; _minifiedCode.clear(); _tokens.append(startToken); _tokenStrings.append(QString()); - if (startToken == T_FEED_JS_PROGRAM) { + if (startToken == T_FEED_JS_SCRIPT) { // parse optional pragma directive DiagnosticMessage error; if (scanDirectives(this, &error)) { @@ -282,15 +328,8 @@ bool Minify::parse(int startToken) _stateStack[yytos] = yyaction; again: - if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) { - if (_tokens.isEmpty()) { - _tokens.append(lex()); - _tokenStrings.append(tokenText()); - } - - yytoken = _tokens.takeFirst(); - yytokentext = _tokenStrings.takeFirst(); - } + if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) + lex(); yyaction = t_action(yyaction, yytoken); if (yyaction > 0) { @@ -366,6 +405,8 @@ bool Minify::parse(int startToken) const int ruleno = -yyaction - 1; yytos -= rhs[ruleno]; + handleLookaheads(ruleno); + if (isRegExpRule(ruleno)) { QString restOfRegExp; @@ -398,13 +439,10 @@ bool Minify::parse(int startToken) class Tokenize: public QmlminLexer { - QVector<int> _stateStack; - QList<int> _tokens; - QList<QString> _tokenStrings; QStringList _minifiedCode; public: - Tokenize(); + Tokenize() {} QStringList tokenStream() const; @@ -412,11 +450,6 @@ protected: bool parse(int startToken) override; }; -Tokenize::Tokenize() - : _stateStack(128) -{ -} - QStringList Tokenize::tokenStream() const { return _minifiedCode; @@ -425,15 +458,13 @@ QStringList Tokenize::tokenStream() const bool Tokenize::parse(int startToken) { int yyaction = 0; - int yytoken = -1; int yytos = -1; - QString yytokentext; _minifiedCode.clear(); _tokens.append(startToken); _tokenStrings.append(QString()); - if (startToken == T_FEED_JS_PROGRAM) { + if (startToken == T_FEED_JS_SCRIPT) { // parse optional pragma directive DiagnosticMessage error; if (scanDirectives(this, &error)) { @@ -457,15 +488,8 @@ bool Tokenize::parse(int startToken) _stateStack[yytos] = yyaction; again: - if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) { - if (_tokens.isEmpty()) { - _tokens.append(lex()); - _tokenStrings.append(tokenText()); - } - - yytoken = _tokens.takeFirst(); - yytokentext = _tokenStrings.takeFirst(); - } + if (yytoken == -1 && action_index[yyaction] != -TERMINAL_COUNT) + lex(); yyaction = t_action(yyaction, yytoken); if (yyaction > 0) { @@ -484,6 +508,8 @@ bool Tokenize::parse(int startToken) const int ruleno = -yyaction - 1; yytos -= rhs[ruleno]; + handleLookaheads(ruleno); + if (isRegExpRule(ruleno)) { QString restOfRegExp; |