diff options
25 files changed, 11272 insertions, 1 deletions
diff --git a/src/declarative/qml/parser/javascript.g b/src/declarative/qml/parser/javascript.g new file mode 100644 index 0000000..24467dd --- /dev/null +++ b/src/declarative/qml/parser/javascript.g @@ -0,0 +1,2265 @@ +---------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +-- Contact: Qt Software Information (qt-info@nokia.com) +-- +-- This file is part of the QtScript module of the Qt Toolkit. +-- +-- $QT_BEGIN_LICENSE:LGPL$ +-- No Commercial Usage +-- This file contains pre-release code and may not be distributed. +-- You may use this file in accordance with the terms and conditions +-- contained in the either Technology Preview License Agreement or the +-- Beta Release License Agreement. +-- +-- GNU Lesser General Public License Usage +-- Alternatively, this file may be used under the terms of the GNU Lesser +-- General Public License version 2.1 as published by the Free Software +-- Foundation and appearing in the file LICENSE.LGPL included in the +-- packaging of this file. Please review the following information to +-- ensure the GNU Lesser General Public License version 2.1 requirements +-- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +-- +-- In addition, as a special exception, Nokia gives you certain +-- additional rights. These rights are described in the Nokia Qt LGPL +-- Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +-- package. +-- +-- GNU General Public License Usage +-- Alternatively, this file may be used under the terms of the GNU +-- General Public License version 3.0 as published by the Free Software +-- Foundation and appearing in the file LICENSE.GPL included in the +-- packaging of this file. Please review the following information to +-- ensure the GNU General Public License version 3.0 requirements will be +-- met: http://www.gnu.org/copyleft/gpl.html. +-- +-- If you are unsure which license is appropriate for your use, please +-- contact the sales department at qt-sales@nokia.com. +-- $QT_END_LICENSE$ +-- +-- This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +-- WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- +---------------------------------------------------------------------------- + +%parser JavaScriptGrammar +%decl javascriptparser_p.h +%impl javascriptparser.cpp +%expect 3 +%expect-rr 1 + +%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&=" +%token T_BREAK "break" T_CASE "case" T_CATCH "catch" +%token T_COLON ":" T_COMMA ";" T_CONTINUE "continue" +%token T_DEFAULT "default" T_DELETE "delete" T_DIVIDE_ "/" +%token T_DIVIDE_EQ "/=" T_DO "do" T_DOT "." +%token T_ELSE "else" T_EQ "=" T_EQ_EQ "==" +%token T_EQ_EQ_EQ "===" T_FINALLY "finally" T_FOR "for" +%token T_FUNCTION "function" T_GE ">=" T_GT ">" +%token T_GT_GT ">>" T_GT_GT_EQ ">>=" T_GT_GT_GT ">>>" +%token T_GT_GT_GT_EQ ">>>=" T_IDENTIFIER "identifier" T_IF "if" +%token T_IN "in" T_INSTANCEOF "instanceof" T_LBRACE "{" +%token T_LBRACKET "[" T_LE "<=" T_LPAREN "(" +%token T_LT "<" T_LT_LT "<<" T_LT_LT_EQ "<<=" +%token T_MINUS "-" T_MINUS_EQ "-=" T_MINUS_MINUS "--" +%token T_NEW "new" T_NOT "!" T_NOT_EQ "!=" +%token T_NOT_EQ_EQ "!==" T_NUMERIC_LITERAL "numeric literal" T_OR "|" +%token T_OR_EQ "|=" T_OR_OR "||" T_PLUS "+" +%token T_PLUS_EQ "+=" T_PLUS_PLUS "++" T_QUESTION "?" +%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_SWITCH "switch" T_THIS "this" T_THROW "throw" +%token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof" +%token T_VAR "var" T_VOID "void" T_WHILE "while" +%token T_WITH "with" T_XOR "^" T_XOR_EQ "^=" +%token T_NULL "null" T_TRUE "true" T_FALSE "false" +%token T_CONST "const" +%token T_DEBUGGER "debugger" +%token T_RESERVED_WORD "reserved word" + +--- context keywords. +%token T_PUBLIC "public" + +%nonassoc SHIFT_THERE +%nonassoc T_IDENTIFIER T_COLON +%nonassoc REDUCE_HERE + +%start Program + +/. +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtDebug> + +#include <string.h> + +#include "javascriptengine_p.h" +#include "javascriptlexer_p.h" +#include "javascriptast_p.h" +#include "javascriptnodepool_p.h" + +./ + +/: +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// +// This file is automatically generated from javascript.g. +// Changes will be lost. +// + +#ifndef JAVASCRIPTPARSER_P_H +#define JAVASCRIPTPARSER_P_H + +#include "javascriptgrammar_p.h" +#include "javascriptast_p.h" +#include <QtCore/QList> + +QT_BEGIN_NAMESPACE + +class QString; +class JavaScriptEnginePrivate; +class JavaScriptNameIdImpl; + +class JavaScriptParser: protected $table +{ +public: + union Value { + int ival; + double dval; + JavaScriptNameIdImpl *sval; + JavaScript::AST::ArgumentList *ArgumentList; + JavaScript::AST::CaseBlock *CaseBlock; + JavaScript::AST::CaseClause *CaseClause; + JavaScript::AST::CaseClauses *CaseClauses; + JavaScript::AST::Catch *Catch; + JavaScript::AST::DefaultClause *DefaultClause; + JavaScript::AST::ElementList *ElementList; + JavaScript::AST::Elision *Elision; + JavaScript::AST::ExpressionNode *Expression; + JavaScript::AST::Finally *Finally; + JavaScript::AST::FormalParameterList *FormalParameterList; + JavaScript::AST::FunctionBody *FunctionBody; + JavaScript::AST::FunctionDeclaration *FunctionDeclaration; + JavaScript::AST::Node *Node; + JavaScript::AST::PropertyName *PropertyName; + JavaScript::AST::PropertyNameAndValueList *PropertyNameAndValueList; + JavaScript::AST::SourceElement *SourceElement; + JavaScript::AST::SourceElements *SourceElements; + JavaScript::AST::Statement *Statement; + JavaScript::AST::StatementList *StatementList; + JavaScript::AST::VariableDeclaration *VariableDeclaration; + JavaScript::AST::VariableDeclarationList *VariableDeclarationList; + + JavaScript::AST::UiProgram *UiProgram; + JavaScript::AST::UiPublicMember *UiPublicMember; + JavaScript::AST::UiObjectDefinition *UiObjectDefinition; + JavaScript::AST::UiObjectInitializer *UiObjectInitializer; + JavaScript::AST::UiObjectBinding *UiObjectBinding; + JavaScript::AST::UiScriptBinding *UiScriptBinding; + JavaScript::AST::UiArrayBinding *UiArrayBinding; + JavaScript::AST::UiObjectMember *UiObjectMember; + JavaScript::AST::UiObjectMemberList *UiObjectMemberList; + JavaScript::AST::UiQualifiedId *UiQualifiedId; + }; + + struct DiagnosticMessage { + enum Kind { Warning, Error }; + + DiagnosticMessage() + : kind(Error), line(0), column(0) {} + + DiagnosticMessage(Kind kind, int line, int column, const QString &message) + : kind(kind), line(line), column(column), message(message) {} + + bool isWarning() const + { return kind == Warning; } + + bool isError() const + { return kind == Error; } + + Kind kind; + int line; + int column; + QString message; + }; + +public: + JavaScriptParser(); + ~JavaScriptParser(); + + bool parse(JavaScriptEnginePrivate *driver); + + JavaScript::AST::UiProgram *ast() + { return sym(1).UiProgram; } + + QList<DiagnosticMessage> diagnosticMessages() const + { return diagnostic_messages; } + + inline DiagnosticMessage diagnosticMessage() const + { + foreach (const DiagnosticMessage &d, diagnostic_messages) { + if (! d.kind == DiagnosticMessage::Warning) + return d; + } + + return DiagnosticMessage(); + } + + inline QString errorMessage() const + { return diagnosticMessage().message; } + + inline int errorLineNumber() const + { return diagnosticMessage().line; } + + inline int errorColumnNumber() const + { return diagnosticMessage().column; } + +protected: + void reallocateStack(); + + inline Value &sym(int index) + { return sym_stack [tos + index - 1]; } + + inline JavaScript::AST::SourceLocation &loc(int index) + { return location_stack [tos + index - 1]; } + +protected: + int tos; + int stack_size; + Value *sym_stack; + int *state_stack; + JavaScript::AST::SourceLocation *location_stack; + + // error recovery + enum { TOKEN_BUFFER_SIZE = 3 }; + + struct SavedToken { + int token; + double dval; + JavaScript::AST::SourceLocation loc; + }; + + double yylval; + JavaScript::AST::SourceLocation yylloc; + JavaScript::AST::SourceLocation yyprevlloc; + + SavedToken token_buffer[TOKEN_BUFFER_SIZE]; + SavedToken *first_token; + SavedToken *last_token; + + QList<DiagnosticMessage> diagnostic_messages; +}; + +:/ + + +/. + +#include "javascriptparser_p.h" + +// +// This file is automatically generated from javascript.g. +// Changes will be lost. +// + +using namespace JavaScript; + +QT_BEGIN_NAMESPACE + +void JavaScriptParser::reallocateStack() +{ + if (! stack_size) + stack_size = 128; + else + stack_size <<= 1; + + sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); + state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int))); + location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation))); +} + +inline static bool automatic(JavaScriptEnginePrivate *driver, int token) +{ + return token == $table::T_RBRACE + || token == 0 + || driver->lexer()->prevTerminator(); +} + + +JavaScriptParser::JavaScriptParser(): + tos(0), + stack_size(0), + sym_stack(0), + state_stack(0), + location_stack(0), + first_token(0), + last_token(0) +{ +} + +JavaScriptParser::~JavaScriptParser() +{ + if (stack_size) { + qFree(sym_stack); + qFree(state_stack); + qFree(location_stack); + } +} + +static inline AST::SourceLocation location(Lexer *lexer) +{ + AST::SourceLocation loc; + loc.offset = lexer->tokenOffset(); + loc.length = lexer->tokenLength(); + loc.startLine = lexer->startLineNo(); + loc.startColumn = lexer->startColumnNo(); + return loc; +} + +bool JavaScriptParser::parse(JavaScriptEnginePrivate *driver) +{ + Lexer *lexer = driver->lexer(); + bool hadErrors = false; + int yytoken = -1; + int action = 0; + + first_token = last_token = 0; + + tos = -1; + + do { + if (++tos == stack_size) + reallocateStack(); + + state_stack[tos] = action; + + _Lcheck_token: + if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) { + yyprevlloc = yylloc; + + if (first_token == last_token) { + yytoken = lexer->lex(); + yylval = lexer->dval(); + yylloc = location(lexer); + } else { + yytoken = first_token->token; + yylval = first_token->dval; + yylloc = first_token->loc; + ++first_token; + } + } + + action = t_action(action, yytoken); + if (action > 0) { + if (action != ACCEPT_STATE) { + yytoken = -1; + sym(1).dval = yylval; + loc(1) = yylloc; + } else { + --tos; + return ! hadErrors; + } + } else if (action < 0) { + const int r = -action - 1; + tos -= rhs[r]; + + switch (r) { +./ + +-------------------------------------------------------------------------------------------------------- +-- Declarative UI +-------------------------------------------------------------------------------------------------------- +Program: UiObjectMemberList ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiObjectMemberList->finish()); +} break; +./ + +Empty: ; + +UiObjectMemberList: UiObjectMember ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember); +} break; +./ + +UiObjectMemberList: UiObjectMemberList Empty UiObjectMember ; +/.case $rule_number:./ +UiObjectMemberList: UiObjectMemberList T_COMMA UiObjectMember ; +/. +case $rule_number: { + AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(), + sym(1).UiObjectMemberList, sym(3).UiObjectMember); + sym(1).Node = node; +} break; +./ + +UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ; +/. +case $rule_number: { + AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; +} break; +./ + +UiObjectMember: UiQualifiedId T_COLON T_IDENTIFIER UiObjectInitializer ; +/. +case $rule_number: { + AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(3).sval, sym(4).UiObjectInitializer); + node->colonToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; +./ + +UiObjectMember: T_IDENTIFIER UiObjectInitializer ; +/. +case $rule_number: { + AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).sval, + sym(2).UiObjectInitializer); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiObjectMemberList T_RBRACKET ; +/. +case $rule_number: { + AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(4).UiObjectMemberList->finish()); + node->colonToken = loc(2); + node->lbracketToken = loc(3); + node->rbraceToken = loc(5); + sym(1).Node = node; +} break; +./ + +UiObjectMember: UiQualifiedId T_COLON Statement ; +/. +case $rule_number: { + AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(3).Statement); + node->colonToken = loc(2); + sym(1).Node = node; +} break; +./ + +UiObjectMember: T_PUBLIC T_IDENTIFIER T_IDENTIFIER T_COLON Expression UiObjectInitializer ; +/. +case $rule_number: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval, + sym(5).Expression, sym(6).UiObjectInitializer); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; +} break; +./ + +UiObjectMember: T_PUBLIC T_IDENTIFIER T_IDENTIFIER ; +/. +case $rule_number: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; +./ + +UiObjectMember: T_PUBLIC T_IDENTIFIER T_IDENTIFIER T_COLON Expression ; +/. +case $rule_number: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval, + sym(5).Expression, static_cast<AST::UiObjectInitializer *>(0)); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; +} break; +./ + + +UiQualifiedId: T_IDENTIFIER ; +/. +case $rule_number: { + AST::UiQualifiedId *node = makeAstNode<AST::UiQualifiedId> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +UiQualifiedId: UiQualifiedId T_DOT T_IDENTIFIER ; +/. +case $rule_number: + AST::UiQualifiedId *node = makeAstNode<AST::UiQualifiedId> (driver->nodePool(), sym(1).UiQualifiedId, sym(3).sval); + node->identifierToken = loc(3); + sym(1).Node = node; + break; +./ + + +-------------------------------------------------------------------------------------------------------- +-- Expressions +-------------------------------------------------------------------------------------------------------- +PrimaryExpression: T_THIS ; +/. +case $rule_number: { + AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool()); + node->thisToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_IDENTIFIER ; +/. +case $rule_number: { + AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_NULL ; +/. +case $rule_number: { + AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool()); + node->nullToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_TRUE ; +/. +case $rule_number: { + AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool()); + node->trueToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_FALSE ; +/. +case $rule_number: { + AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool()); + node->falseToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_NUMERIC_LITERAL ; +/. +case $rule_number: { + AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval); + node->literalToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_STRING_LITERAL ; +/. +case $rule_number: { + AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval); + node->literalToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: 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, lexer->startLineNo(), + lexer->startColumnNo(), lexer->errorMessage())); + return false; + } + AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags); + node->literalToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: 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, lexer->startLineNo(), + lexer->startColumnNo(), lexer->errorMessage())); + return false; + } + AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags); + node->literalToken = loc(1); + sym(1).Node = node; +} break; +./ + +PrimaryExpression: T_LBRACKET ElisionOpt T_RBRACKET ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision); +} break; +./ + +PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ()); +} break; +./ + +PrimaryExpression: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (), sym(4).Elision); +} break; +./ + +-- PrimaryExpression: T_LBRACE T_RBRACE ; +-- /. +-- case $rule_number: { +-- sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool()); +-- } break; +-- ./ + +PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ; +/. +case $rule_number: { + if (sym(2).Node) + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ()); + else + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool()); +} break; +./ + +PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ()); +} break; +./ + +PrimaryExpression: T_LPAREN Expression T_RPAREN ; +/. +case $rule_number: { + sym(1) = sym(2); +} break; +./ + +ElementList: ElisionOpt AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision, sym(2).Expression); +} break; +./ + +ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision, sym(4).Expression); +} break; +./ + +Elision: T_COMMA ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Elision> (driver->nodePool()); +} break; +./ + +Elision: Elision T_COMMA ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision); +} break; +./ + +ElisionOpt: %prec SHIFT_THERE ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +ElisionOpt: Elision ; +/. +case $rule_number: { + sym(1).Elision = sym(1).Elision->finish (); +} break; +./ + +PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyName, sym(3).Expression); +} break; +./ + +PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression); +} break; +./ + +PropertyName: T_IDENTIFIER %prec REDUCE_HERE ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval); +} break; +./ + +PropertyName: T_STRING_LITERAL ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval); +} break; +./ + +PropertyName: T_NUMERIC_LITERAL ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval); +} break; +./ + +PropertyName: ReservedIdentifier ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval); +} break; +./ + +ReservedIdentifier: T_BREAK ; +/. +case $rule_number: +./ +ReservedIdentifier: T_CASE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_CATCH ; +/. +case $rule_number: +./ +ReservedIdentifier: T_CONTINUE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_DEFAULT ; +/. +case $rule_number: +./ +ReservedIdentifier: T_DELETE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_DO ; +/. +case $rule_number: +./ +ReservedIdentifier: T_ELSE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_FALSE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_FINALLY ; +/. +case $rule_number: +./ +ReservedIdentifier: T_FOR ; +/. +case $rule_number: +./ +ReservedIdentifier: T_FUNCTION ; +/. +case $rule_number: +./ +ReservedIdentifier: T_IF ; +/. +case $rule_number: +./ +ReservedIdentifier: T_IN ; +/. +case $rule_number: +./ +ReservedIdentifier: T_INSTANCEOF ; +/. +case $rule_number: +./ +ReservedIdentifier: T_NEW ; +/. +case $rule_number: +./ +ReservedIdentifier: T_NULL ; +/. +case $rule_number: +./ +ReservedIdentifier: T_RETURN ; +/. +case $rule_number: +./ +ReservedIdentifier: T_SWITCH ; +/. +case $rule_number: +./ +ReservedIdentifier: T_THIS ; +/. +case $rule_number: +./ +ReservedIdentifier: T_THROW ; +/. +case $rule_number: +./ +ReservedIdentifier: T_TRUE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_TRY ; +/. +case $rule_number: +./ +ReservedIdentifier: T_TYPEOF ; +/. +case $rule_number: +./ +ReservedIdentifier: T_VAR ; +/. +case $rule_number: +./ +ReservedIdentifier: T_VOID ; +/. +case $rule_number: +./ +ReservedIdentifier: T_WHILE ; +/. +case $rule_number: +./ +ReservedIdentifier: T_CONST ; +/. +case $rule_number: +./ +ReservedIdentifier: T_DEBUGGER ; +/. +case $rule_number: +./ +ReservedIdentifier: T_RESERVED_WORD ; +/. +case $rule_number: +./ +ReservedIdentifier: T_WITH ; +/. +case $rule_number: +{ + sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount()); +} break; +./ + +PropertyIdentifier: T_IDENTIFIER ; +PropertyIdentifier: ReservedIdentifier ; + +MemberExpression: PrimaryExpression ; +MemberExpression: FunctionExpression ; + +MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; +./ + +MemberExpression: MemberExpression T_DOT PropertyIdentifier ; +/. +case $rule_number: { + AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; +./ + +MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; +/. +case $rule_number: { + AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList); + node->newToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + sym(1).Node = node; +} break; +./ + +NewExpression: MemberExpression ; + +NewExpression: T_NEW NewExpression ; +/. +case $rule_number: { + AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression); + node->newToken = loc(1); + sym(1).Node = node; +} break; +./ + +CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; +/. +case $rule_number: { + AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; +} break; +./ + +CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ; +/. +case $rule_number: { + AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), 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 ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; +./ + +CallExpression: CallExpression T_DOT PropertyIdentifier ; +/. +case $rule_number: { + AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; +./ + +ArgumentListOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +ArgumentListOpt: ArgumentList ; +/. +case $rule_number: { + sym(1).Node = sym(1).ArgumentList->finish(); +} break; +./ + +ArgumentList: AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression); +} break; +./ + +ArgumentList: ArgumentList T_COMMA AssignmentExpression ; +/. +case $rule_number: { + AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; +} break; +./ + +LeftHandSideExpression: NewExpression ; +LeftHandSideExpression: CallExpression ; +PostfixExpression: LeftHandSideExpression ; + +PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression); +} break; +./ + +PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression); +} break; +./ + +UnaryExpression: PostfixExpression ; + +UnaryExpression: T_DELETE UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_VOID UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_TYPEOF UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_PLUS_PLUS UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_MINUS_MINUS UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_PLUS UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_MINUS UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_TILDE UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +UnaryExpression: T_NOT UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression); +} break; +./ + +MultiplicativeExpression: UnaryExpression ; + +MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mul, sym(3).Expression); +} break; +./ + +MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Div, sym(3).Expression); +} break; +./ + +MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mod, sym(3).Expression); +} break; +./ + +AdditiveExpression: MultiplicativeExpression ; + +AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Add, sym(3).Expression); +} break; +./ + +AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Sub, sym(3).Expression); +} break; +./ + +ShiftExpression: AdditiveExpression ; + +ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::LShift, sym(3).Expression); +} break; +./ + +ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::RShift, sym(3).Expression); +} break; +./ + +ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::URShift, sym(3).Expression); +} break; +./ + +RelationalExpression: ShiftExpression ; + +RelationalExpression: RelationalExpression T_LT ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); +} break; +./ + +RelationalExpression: RelationalExpression T_GT ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); +} break; +./ + +RelationalExpression: RelationalExpression T_LE ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); +} break; +./ + +RelationalExpression: RelationalExpression T_GE ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); +} break; +./ + +RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); +} break; +./ + +RelationalExpression: RelationalExpression T_IN ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::In, sym(3).Expression); +} break; +./ + +RelationalExpressionNotIn: ShiftExpression ; + +RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); +} break; +./ + +RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); +} break; +./ + +RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); +} break; +./ + +RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); +} break; +./ + +RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); +} break; +./ + +EqualityExpression: RelationalExpression ; + +EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); +} break; +./ + +EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); +} break; +./ + +EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); +} break; +./ + +EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); +} break; +./ + +EqualityExpressionNotIn: RelationalExpressionNotIn ; + +EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); +} break; +./ + +EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); +} break; +./ + +EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); +} break; +./ + +EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); +} break; +./ + +BitwiseANDExpression: EqualityExpression ; + +BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); +} break; +./ + +BitwiseANDExpressionNotIn: EqualityExpressionNotIn ; + +BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); +} break; +./ + +BitwiseXORExpression: BitwiseANDExpression ; + +BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression); +} break; +./ + +BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ; + +BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression); +} break; +./ + +BitwiseORExpression: BitwiseXORExpression ; + +BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression); +} break; +./ + +BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ; + +BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression); +} break; +./ + +LogicalANDExpression: BitwiseORExpression ; + +LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression); +} break; +./ + +LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ; + +LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression); +} break; +./ + +LogicalORExpression: LogicalANDExpression ; + +LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression); +} break; +./ + +LogicalORExpressionNotIn: LogicalANDExpressionNotIn ; + +LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression); +} break; +./ + +ConditionalExpression: LogicalORExpression ; + +ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); +} break; +./ + +ConditionalExpressionNotIn: LogicalORExpressionNotIn ; + +ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); +} break; +./ + +AssignmentExpression: ConditionalExpression ; + +AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); +} break; +./ + +AssignmentExpressionNotIn: ConditionalExpressionNotIn ; + +AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); +} break; +./ + +AssignmentOperator: T_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::Assign; +} break; +./ + +AssignmentOperator: T_STAR_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceMul; +} break; +./ + +AssignmentOperator: T_DIVIDE_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceDiv; +} break; +./ + +AssignmentOperator: T_REMAINDER_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceMod; +} break; +./ + +AssignmentOperator: T_PLUS_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceAdd; +} break; +./ + +AssignmentOperator: T_MINUS_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceSub; +} break; +./ + +AssignmentOperator: T_LT_LT_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceLeftShift; +} break; +./ + +AssignmentOperator: T_GT_GT_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceRightShift; +} break; +./ + +AssignmentOperator: T_GT_GT_GT_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceURightShift; +} break; +./ + +AssignmentOperator: T_AND_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceAnd; +} break; +./ + +AssignmentOperator: T_XOR_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceXor; +} break; +./ + +AssignmentOperator: T_OR_EQ ; +/. +case $rule_number: { + sym(1).ival = QSOperator::InplaceOr; +} break; +./ + +Expression: AssignmentExpression ; + +Expression: Expression T_COMMA AssignmentExpression ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; +./ + +ExpressionOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +ExpressionOpt: Expression ; + +ExpressionNotIn: AssignmentExpressionNotIn ; + +ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; +./ + +ExpressionNotInOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +ExpressionNotInOpt: ExpressionNotIn ; + +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 ; + + +Block: T_LBRACE StatementListOpt T_RBRACE ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList); +} break; +./ + +StatementList: Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement); +} break; +./ + +StatementList: StatementList Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement); +} break; +./ + +StatementListOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +StatementListOpt: StatementList ; +/. +case $rule_number: { + sym(1).Node = sym(1).StatementList->finish (); +} break; +./ + +VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ; +/. +case $rule_number: { + AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(), sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST)); + node->declarationKindToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; +} break; +./ + +VariableDeclarationKind: T_CONST ; +/. +case $rule_number: { + sym(1).ival = T_CONST; +} break; +./ + +VariableDeclarationKind: T_VAR ; +/. +case $rule_number: { + sym(1).ival = T_VAR; +} break; +./ + +VariableDeclarationList: VariableDeclaration ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration); +} break; +./ + +VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); +} break; +./ + +VariableDeclarationListNotIn: VariableDeclarationNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration); +} break; +./ + +VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); +} break; +./ + +VariableDeclaration: T_IDENTIFIER InitialiserOpt ; +/. +case $rule_number: { + AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +VariableDeclarationNotIn: T_IDENTIFIER InitialiserNotInOpt ; +/. +case $rule_number: { + AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +Initialiser: T_EQ AssignmentExpression ; +/. +case $rule_number: { + sym(1) = sym(2); +} break; +./ + +InitialiserOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +InitialiserOpt: Initialiser ; + +InitialiserNotIn: T_EQ AssignmentExpressionNotIn ; +/. +case $rule_number: { + sym(1) = sym(2); +} break; +./ + +InitialiserNotInOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +InitialiserNotInOpt: InitialiserNotIn ; + +EmptyStatement: T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::EmptyStatement> (driver->nodePool()); +} break; +./ + +ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +ExpressionStatement: Expression T_SEMICOLON ; +/. +case $rule_number: { + AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression); + node->semicolonToken = loc(2); + sym(1).Node = node; +} break; +./ + +IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement); +} break; +./ + +IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; +./ + + +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_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression); +} break; +./ + +IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; +./ + +IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement); +} break; +./ + +IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::LocalForStatement> (driver->nodePool(), sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression, sym(8).Expression, sym(10).Statement); +} break; +./ + +IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Statement); +} break; +./ + +IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(), sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); +} break; +./ + +ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +ContinueStatement: T_CONTINUE T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ContinueStatement> (driver->nodePool()); +} break; +./ + +ContinueStatement: T_CONTINUE T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +ContinueStatement: T_CONTINUE T_IDENTIFIER T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval); +} break; +./ + +BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +BreakStatement: T_BREAK T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BreakStatement> (driver->nodePool()); +} break; +./ + +BreakStatement: T_BREAK T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +BreakStatement: T_BREAK T_IDENTIFIER T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval); +} break; +./ + +ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression); +} break; +./ + +WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; +./ + +SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock); +} break; +./ + +CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses); +} break; +./ + +CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); +} break; +./ + +CaseClauses: CaseClause ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause); +} break; +./ + +CaseClauses: CaseClauses CaseClause ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause); +} break; +./ + +CaseClausesOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +CaseClausesOpt: CaseClauses ; +/. +case $rule_number: { + sym(1).Node = sym(1).CaseClauses->finish (); +} break; +./ + +CaseClause: T_CASE Expression T_COLON StatementListOpt ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList); +} break; +./ + +DefaultClause: T_DEFAULT T_COLON StatementListOpt ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList); +} break; +./ + +LabelledStatement: T_IDENTIFIER T_COLON Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement); +} break; +./ + +ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +ThrowStatement: T_THROW Expression T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression); +} break; +./ + +TryStatement: T_TRY Block Catch ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch); +} break; +./ + +TryStatement: T_TRY Block Finally ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally); +} break; +./ + +TryStatement: T_TRY Block Catch Finally ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally); +} break; +./ + +Catch: T_CATCH T_LPAREN T_IDENTIFIER T_RPAREN Block ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Statement); +} break; +./ + +Finally: T_FINALLY Block ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Statement); +} break; +./ + +DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon +DebuggerStatement: T_DEBUGGER T_SEMICOLON ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::DebuggerStatement> (driver->nodePool()); +} break; +./ + +FunctionDeclaration: T_FUNCTION T_IDENTIFIER T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +/. +case $rule_number: { + AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody); + 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; +./ + +FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +/. +case $rule_number: { + AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody); + node->functionToken = loc(1); + if (sym(2).sval) + 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; +./ + +FormalParameterList: T_IDENTIFIER ; +/. +case $rule_number: { + AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; +./ + +FormalParameterList: FormalParameterList T_COMMA T_IDENTIFIER ; +/. +case $rule_number: { + AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval); + node->commaToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; +./ + +FormalParameterListOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +FormalParameterListOpt: FormalParameterList ; +/. +case $rule_number: { + sym(1).Node = sym(1).FormalParameterList->finish (); +} break; +./ + +FunctionBodyOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +FunctionBodyOpt: FunctionBody ; + +FunctionBody: SourceElements ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ()); +} break; +./ + +--JavaScriptProgram: SourceElements ; +--/. +--case $rule_number: { +-- sym(1).Node = makeAstNode<AST::Program> (driver->nodePool(), sym(1).SourceElements->finish ()); +-- driver->changeAbstractSyntaxTree(sym(1).Node); +--} break; +--./ + +SourceElements: SourceElement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement); +} break; +./ + +SourceElements: SourceElements SourceElement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement); +} break; +./ + +SourceElement: Statement ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement); +} break; +./ + +SourceElement: FunctionDeclaration ; +/. +case $rule_number: { + sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration); +} break; +./ + +IdentifierOpt: ; +/. +case $rule_number: { + sym(1).sval = 0; +} break; +./ + +IdentifierOpt: T_IDENTIFIER ; + +PropertyNameAndValueListOpt: ; +/. +case $rule_number: { + sym(1).Node = 0; +} break; +./ + +PropertyNameAndValueListOpt: PropertyNameAndValueList ; + +/. + } // switch + action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT); + } // if + } while (action != 0); + + if (first_token == last_token) { + const int errorState = state_stack[tos]; + + // automatic insertion of `;' + if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && automatic(driver, yytoken)) { + SavedToken &tk = token_buffer[0]; + tk.token = yytoken; + tk.dval = yylval; + tk.loc = yylloc; + + const QString msg = QString::fromUtf8("Missing `;'"); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, + yyprevlloc.startLine, yyprevlloc.startColumn, msg)); + + first_token = &token_buffer[0]; + last_token = &token_buffer[1]; + + yytoken = T_SEMICOLON; + yylval = 0; + + action = errorState; + + goto _Lcheck_token; + } + + hadErrors = true; + + token_buffer[0].token = yytoken; + token_buffer[0].dval = yylval; + token_buffer[0].loc = yylloc; + + token_buffer[1].token = yytoken = lexer->lex(); + token_buffer[1].dval = yylval = lexer->dval(); + token_buffer[1].loc = yylloc = location(lexer); + + if (t_action(errorState, yytoken)) { + const QString msg = QString::fromUtf8("Removed token: `%1'").arg(spell[token_buffer[0].token]); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + action = errorState; + goto _Lcheck_token; + } + + static int tokens[] = { + T_PLUS, + T_EQ, + + T_COMMA, + T_COLON, + T_SEMICOLON, + + T_RPAREN, T_RBRACKET, T_RBRACE, + + T_NUMERIC_LITERAL, + T_IDENTIFIER, + + T_LPAREN, T_LBRACKET, T_LBRACE, + + EOF_SYMBOL + }; + + for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) { + int a = t_action(errorState, *tk); + if (a > 0 && t_action(a, yytoken)) { + const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[*tk]); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + yytoken = *tk; + yylval = 0; + yylloc = token_buffer[0].loc; + + first_token = &token_buffer[0]; + last_token = &token_buffer[2]; + + action = errorState; + goto _Lcheck_token; + } + } + + for (int tk = 1; tk < TERMINAL_COUNT; ++tk) { + int a = t_action(errorState, tk); + if (a > 0 && t_action(a, yytoken)) { + const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[tk]); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + yytoken = tk; + yylval = 0; + yylloc = token_buffer[0].loc; + + action = errorState; + goto _Lcheck_token; + } + } + + const QString msg = QString::fromUtf8("Unexpected token"); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + } + + return false; +} + +QT_END_NAMESPACE + + +./ +/: +QT_END_NAMESPACE + + + +#endif // JAVASCRIPTPARSER_P_H +:/ diff --git a/src/declarative/qml/parser/javascriptast.cpp b/src/declarative/qml/parser/javascriptast.cpp new file mode 100644 index 0000000..8d8ca7d --- /dev/null +++ b/src/declarative/qml/parser/javascriptast.cpp @@ -0,0 +1,878 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "javascriptast_p.h" + + + +#include "javascriptastvisitor_p.h" + +QT_BEGIN_NAMESPACE + +namespace JavaScript { namespace AST { + +ExpressionNode *Node::expressionCast() +{ + return 0; +} + +BinaryExpression *Node::binaryExpressionCast() +{ + return 0; +} + +Statement *Node::statementCast() +{ + return 0; +} + +ExpressionNode *ExpressionNode::expressionCast() +{ + return this; +} + +BinaryExpression *BinaryExpression::binaryExpressionCast() +{ + return this; +} + +Statement *Statement::statementCast() +{ + return this; +} + +void ThisExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void IdentifierExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void NullExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void TrueLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void FalseLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void StringLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void NumericLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void RegExpLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void ArrayLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(elements, visitor); + acceptChild(elision, visitor); + } + + visitor->endVisit(this); +} + +void ObjectLiteral::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(properties, visitor); + } + + visitor->endVisit(this); +} + +void ElementList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + ElementList *it = this; + do { + acceptChild(it->elision, visitor); + acceptChild(it->expression, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void Elision::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + // ### + } + + visitor->endVisit(this); +} + +void PropertyNameAndValueList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + PropertyNameAndValueList *it = this; + do { + acceptChild(it->name, visitor); + acceptChild(it->value, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void IdentifierPropertyName::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void StringLiteralPropertyName::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void NumericLiteralPropertyName::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void ArrayMemberExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void FieldMemberExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + } + + visitor->endVisit(this); +} + +void NewMemberExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + acceptChild(arguments, visitor); + } + + visitor->endVisit(this); +} + +void NewExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void CallExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + acceptChild(arguments, visitor); + } + + visitor->endVisit(this); +} + +void ArgumentList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + ArgumentList *it = this; + do { + acceptChild(it->expression, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void PostIncrementExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + } + + visitor->endVisit(this); +} + +void PostDecrementExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(base, visitor); + } + + visitor->endVisit(this); +} + +void DeleteExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void VoidExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void TypeOfExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void PreIncrementExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void PreDecrementExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void UnaryPlusExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void UnaryMinusExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void TildeExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void NotExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void BinaryExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(left, visitor); + acceptChild(right, visitor); + } + + visitor->endVisit(this); +} + +void ConditionalExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(ok, visitor); + acceptChild(ko, visitor); + } + + visitor->endVisit(this); +} + +void Expression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(left, visitor); + acceptChild(right, visitor); + } + + visitor->endVisit(this); +} + +void Block::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statements, visitor); + } + + visitor->endVisit(this); +} + +void StatementList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + StatementList *it = this; + do { + acceptChild(it->statement, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void VariableStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(declarations, visitor); + } + + visitor->endVisit(this); +} + +void VariableDeclarationList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + VariableDeclarationList *it = this; + do { + acceptChild(it->declaration, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void VariableDeclaration::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void EmptyStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void ExpressionStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void IfStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(ok, visitor); + acceptChild(ko, visitor); + } + + visitor->endVisit(this); +} + +void DoWhileStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void WhileStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void ForStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(initialiser, visitor); + acceptChild(condition, visitor); + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void LocalForStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(declarations, visitor); + acceptChild(condition, visitor); + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void ForEachStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(initialiser, visitor); + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void LocalForEachStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(declaration, visitor); + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void ContinueStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void BreakStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +void ReturnStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void WithStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void SwitchStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(block, visitor); + } + + visitor->endVisit(this); +} + +void CaseBlock::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(clauses, visitor); + acceptChild(defaultClause, visitor); + acceptChild(moreClauses, visitor); + } + + visitor->endVisit(this); +} + +void CaseClauses::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + CaseClauses *it = this; + do { + acceptChild(it->clause, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void CaseClause::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(statements, visitor); + } + + visitor->endVisit(this); +} + +void DefaultClause::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statements, visitor); + } + + visitor->endVisit(this); +} + +void LabelledStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void ThrowStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + } + + visitor->endVisit(this); +} + +void TryStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + acceptChild(catchExpression, visitor); + acceptChild(finallyExpression, visitor); + } + + visitor->endVisit(this); +} + +void Catch::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void Finally::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void FunctionDeclaration::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(formals, visitor); + acceptChild(body, visitor); + } + + visitor->endVisit(this); +} + +void FunctionExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(formals, visitor); + acceptChild(body, visitor); + } + + visitor->endVisit(this); +} + +void FormalParameterList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + // ### + } + + visitor->endVisit(this); +} + +void FunctionBody::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(elements, visitor); + } + + visitor->endVisit(this); +} + +void Program::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(elements, visitor); + } + + visitor->endVisit(this); +} + +void SourceElements::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + SourceElements *it = this; + do { + acceptChild(it->element, visitor); + it = it->next; + } while (it); + } + + visitor->endVisit(this); +} + +void FunctionSourceElement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(declaration, visitor); + } + + visitor->endVisit(this); +} + +void StatementSourceElement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void DebuggerStatement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + + +void UiProgram::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + for (UiObjectMemberList *it = members; it; it = it->next) + acceptChild(it->member, visitor); + } + + visitor->endVisit(this); +} + +void UiPublicMember::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(expression, visitor); + acceptChild(initializer, visitor); + } + + visitor->endVisit(this); +} + +void UiObjectDefinition::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(initializer, visitor); + } + + visitor->endVisit(this); +} + +void UiObjectInitializer::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + for (UiObjectMemberList *it = members; it; it = it->next) + acceptChild(it->member, visitor); + } + + visitor->endVisit(this); +} + +void UiObjectBinding::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(qualifiedId, visitor); + acceptChild(initializer, visitor); + } + + visitor->endVisit(this); +} + +void UiScriptBinding::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(qualifiedId, visitor); + acceptChild(statement, visitor); + } + + visitor->endVisit(this); +} + +void UiArrayBinding::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + acceptChild(qualifiedId, visitor); + for (UiObjectMemberList *it = members; it; it = it->next) + acceptChild(it->member, visitor); + } + + visitor->endVisit(this); +} + +void UiObjectMemberList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + for (UiObjectMemberList *it = this; it; it = it->next) + acceptChild(it->member, visitor); + } + + visitor->endVisit(this); +} + +void UiQualifiedId::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + } + + visitor->endVisit(this); +} + +} } // namespace JavaScript::AST + +QT_END_NAMESPACE + + diff --git a/src/declarative/qml/parser/javascriptast_p.h b/src/declarative/qml/parser/javascriptast_p.h new file mode 100644 index 0000000..1e9256e --- /dev/null +++ b/src/declarative/qml/parser/javascriptast_p.h @@ -0,0 +1,1756 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTAST_P_H +#define JAVASCRIPTAST_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QString> + + + +#include "javascriptastvisitor_p.h" + +QT_BEGIN_NAMESPACE + +class JavaScriptNameIdImpl; + +namespace QSOperator // ### rename +{ + +enum Op { + Add, + And, + InplaceAnd, + Assign, + BitAnd, + BitOr, + BitXor, + InplaceSub, + Div, + InplaceDiv, + Equal, + Ge, + Gt, + In, + InplaceAdd, + InstanceOf, + Le, + LShift, + InplaceLeftShift, + Lt, + Mod, + InplaceMod, + Mul, + InplaceMul, + NotEqual, + Or, + InplaceOr, + RShift, + InplaceRightShift, + StrictEqual, + StrictNotEqual, + Sub, + URShift, + InplaceURightShift, + InplaceXor +}; + +} // namespace QSOperator + +namespace JavaScript { namespace AST { + +class SourceLocation +{ +public: + SourceLocation(quint32 offset = 0, quint32 length = 0) + : offset(offset), length(length), + startLine(0), startColumn(0) + { } + +// attributes + // ### encode + quint32 offset; + quint32 length; + quint32 startLine; + quint32 startColumn; +}; + +class Node +{ +public: + enum Kind { + Kind_Node, + Kind_ExpressionNode, + Kind_Statement, + Kind_ThisExpression, + Kind_IdentifierExpression, + Kind_NullExpression, + Kind_TrueLiteral, + Kind_FalseLiteral, + Kind_NumericLiteral, + Kind_StringLiteral, + Kind_RegExpLiteral, + Kind_ArrayLiteral, + Kind_ObjectLiteral, + Kind_ElementList, + Kind_Elision, + Kind_PropertyNameAndValueList, + Kind_PropertyName, + Kind_IdentifierPropertyName, + Kind_StringLiteralPropertyName, + Kind_NumericLiteralPropertyName, + Kind_ArrayMemberExpression, + Kind_FieldMemberExpression, + Kind_NewMemberExpression, + Kind_NewExpression, + Kind_CallExpression, + Kind_ArgumentList, + Kind_PostIncrementExpression, + Kind_PostDecrementExpression, + Kind_DeleteExpression, + Kind_VoidExpression, + Kind_TypeOfExpression, + Kind_PreIncrementExpression, + Kind_PreDecrementExpression, + Kind_UnaryPlusExpression, + Kind_UnaryMinusExpression, + Kind_TildeExpression, + Kind_NotExpression, + Kind_BinaryExpression, + Kind_ConditionalExpression, + Kind_Expression, + Kind_Block, + Kind_StatementList, + Kind_VariableStatement, + Kind_VariableDeclarationList, + Kind_VariableDeclaration, + Kind_EmptyStatement, + Kind_ExpressionStatement, + Kind_IfStatement, + Kind_DoWhileStatement, + Kind_WhileStatement, + Kind_ForStatement, + Kind_LocalForStatement, + Kind_ForEachStatement, + Kind_LocalForEachStatement, + Kind_ContinueStatement, + Kind_BreakStatement, + Kind_ReturnStatement, + Kind_WithStatement, + Kind_SwitchStatement, + Kind_CaseBlock, + Kind_CaseClauses, + Kind_CaseClause, + Kind_DefaultClause, + Kind_LabelledStatement, + Kind_ThrowStatement, + Kind_TryStatement, + Kind_Catch, + Kind_Finally, + Kind_FunctionDeclaration, + Kind_FunctionExpression, + Kind_FormalParameterList, + Kind_FunctionBody, + Kind_Program, + Kind_SourceElements, + Kind_SourceElement, + Kind_FunctionSourceElement, + Kind_StatementSourceElement, + Kind_DebuggerStatement, + + Kind_UiProgram, + Kind_UiPublicMember, + Kind_UiObjectDefinition, + Kind_UiObjectInitializer, + Kind_UiObjectBinding, + Kind_UiScriptBinding, + Kind_UiArrayBinding, + Kind_UiObjectMemberList, + Kind_UiQualifiedId + }; + + inline Node() + : kind(Kind_Node) {} + + virtual ~Node() {} + + virtual ExpressionNode *expressionCast(); + virtual BinaryExpression *binaryExpressionCast(); + virtual Statement *statementCast(); + + inline void accept(Visitor *visitor) + { + if (visitor->preVisit(this)) { + accept0(visitor); + visitor->postVisit(this); + } + } + + static void acceptChild(Node *node, Visitor *visitor) + { + if (node) + node->accept(visitor); + } + + virtual void accept0(Visitor *visitor) = 0; + + Kind kind; +}; + +class ExpressionNode: public Node +{ +public: + ExpressionNode() { kind = Kind_ExpressionNode; } + virtual ~ExpressionNode() {} + + virtual ExpressionNode *expressionCast(); +}; + +class Statement: public Node +{ +public: + Statement() { kind = Kind_Statement; } + virtual ~Statement() {} + + virtual Statement *statementCast(); +}; + +class ThisExpression: public ExpressionNode +{ +public: + ThisExpression() { kind = Kind_ThisExpression; } + virtual ~ThisExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceLocation thisToken; +}; + +class IdentifierExpression: public ExpressionNode +{ +public: + IdentifierExpression(JavaScriptNameIdImpl *n): + name (n) { kind = Kind_IdentifierExpression; } + + virtual ~IdentifierExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *name; + SourceLocation identifierToken; +}; + +class NullExpression: public ExpressionNode +{ +public: + NullExpression() { kind = Kind_NullExpression; } + virtual ~NullExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceLocation nullToken; +}; + +class TrueLiteral: public ExpressionNode +{ +public: + TrueLiteral() { kind = Kind_TrueLiteral; } + virtual ~TrueLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceLocation trueToken; +}; + +class FalseLiteral: public ExpressionNode +{ +public: + FalseLiteral() { kind = Kind_FalseLiteral; } + virtual ~FalseLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceLocation falseToken; +}; + +class NumericLiteral: public ExpressionNode +{ +public: + NumericLiteral(double v): + value (v) { kind = Kind_NumericLiteral; } + virtual ~NumericLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes: + double value; + SourceLocation literalToken; +}; + +class StringLiteral: public ExpressionNode +{ +public: + StringLiteral(JavaScriptNameIdImpl *v): + value (v) { kind = Kind_StringLiteral; } + + virtual ~StringLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes: + JavaScriptNameIdImpl *value; + SourceLocation literalToken; +}; + +class RegExpLiteral: public ExpressionNode +{ +public: + RegExpLiteral(JavaScriptNameIdImpl *p, int f): + pattern (p), flags (f) { kind = Kind_RegExpLiteral; } + + virtual ~RegExpLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes: + JavaScriptNameIdImpl *pattern; + int flags; + SourceLocation literalToken; +}; + +class ArrayLiteral: public ExpressionNode +{ +public: + ArrayLiteral(Elision *e): + elements (0), elision (e) + { kind = Kind_ArrayLiteral; } + + ArrayLiteral(ElementList *elts): + elements (elts), elision (0) + { kind = Kind_ArrayLiteral; } + + ArrayLiteral(ElementList *elts, Elision *e): + elements (elts), elision (e) + { kind = Kind_ArrayLiteral; } + + virtual ~ArrayLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ElementList *elements; + Elision *elision; +}; + +class ObjectLiteral: public ExpressionNode +{ +public: + ObjectLiteral(): + properties (0) { kind = Kind_ObjectLiteral; } + + ObjectLiteral(PropertyNameAndValueList *plist): + properties (plist) { kind = Kind_ObjectLiteral; } + + virtual ~ObjectLiteral() {} + + virtual void accept0(Visitor *visitor); + +// attributes + PropertyNameAndValueList *properties; +}; + +class ElementList: public Node +{ +public: + ElementList(Elision *e, ExpressionNode *expr): + elision (e), expression (expr), next (this) + { kind = Kind_ElementList; } + + ElementList(ElementList *previous, Elision *e, ExpressionNode *expr): + elision (e), expression (expr) + { + kind = Kind_ElementList; + next = previous->next; + previous->next = this; + } + + virtual ~ElementList() {} + + inline ElementList *finish () + { + ElementList *front = next; + next = 0; + return front; + } + + virtual void accept0(Visitor *visitor); + +// attributes + Elision *elision; + ExpressionNode *expression; + ElementList *next; +}; + +class Elision: public Node +{ +public: + Elision(): + next (this) { kind = Kind_Elision; } + + Elision(Elision *previous) + { + kind = Kind_Elision; + next = previous->next; + previous->next = this; + } + + virtual ~Elision() {} + + virtual void accept0(Visitor *visitor); + + inline Elision *finish () + { + Elision *front = next; + next = 0; + return front; + } + +// attributes + Elision *next; +}; + +class PropertyNameAndValueList: public Node +{ +public: + PropertyNameAndValueList(PropertyName *n, ExpressionNode *v): + name (n), value (v), next (this) + { kind = Kind_PropertyNameAndValueList; } + + PropertyNameAndValueList(PropertyNameAndValueList *previous, PropertyName *n, ExpressionNode *v): + name (n), value (v) + { + kind = Kind_PropertyNameAndValueList; + next = previous->next; + previous->next = this; + } + + virtual ~PropertyNameAndValueList() {} + + virtual void accept0(Visitor *visitor); + + inline PropertyNameAndValueList *finish () + { + PropertyNameAndValueList *front = next; + next = 0; + return front; + } + +// attributes + PropertyName *name; + ExpressionNode *value; + PropertyNameAndValueList *next; +}; + +class PropertyName: public Node +{ +public: + PropertyName() { kind = Kind_PropertyName; } + virtual ~PropertyName() {} +}; + +class IdentifierPropertyName: public PropertyName +{ +public: + IdentifierPropertyName(JavaScriptNameIdImpl *n): + id (n) { kind = Kind_IdentifierPropertyName; } + + virtual ~IdentifierPropertyName() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *id; +}; + +class StringLiteralPropertyName: public PropertyName +{ +public: + StringLiteralPropertyName(JavaScriptNameIdImpl *n): + id (n) { kind = Kind_StringLiteralPropertyName; } + virtual ~StringLiteralPropertyName() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *id; +}; + +class NumericLiteralPropertyName: public PropertyName +{ +public: + NumericLiteralPropertyName(double n): + id (n) { kind = Kind_NumericLiteralPropertyName; } + virtual ~NumericLiteralPropertyName() {} + + virtual void accept0(Visitor *visitor); + +// attributes + double id; +}; + +class ArrayMemberExpression: public ExpressionNode +{ +public: + ArrayMemberExpression(ExpressionNode *b, ExpressionNode *e): + base (b), expression (e) + { kind = Kind_ArrayMemberExpression; } + + virtual ~ArrayMemberExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; + ExpressionNode *expression; +}; + +class FieldMemberExpression: public ExpressionNode +{ +public: + FieldMemberExpression(ExpressionNode *b, JavaScriptNameIdImpl *n): + base (b), name (n) + { kind = Kind_FieldMemberExpression; } + + virtual ~FieldMemberExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; + JavaScriptNameIdImpl *name; + SourceLocation dotToken; + SourceLocation identifierToken; +}; + +class NewMemberExpression: public ExpressionNode +{ +public: + NewMemberExpression(ExpressionNode *b, ArgumentList *a): + base (b), arguments (a) + { kind = Kind_NewMemberExpression; } + + virtual ~NewMemberExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; + ArgumentList *arguments; + SourceLocation newToken; + SourceLocation lparenToken; + SourceLocation rparenToken; +}; + +class NewExpression: public ExpressionNode +{ +public: + NewExpression(ExpressionNode *e): + expression (e) { kind = Kind_NewExpression; } + + virtual ~NewExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + SourceLocation newToken; +}; + +class CallExpression: public ExpressionNode +{ +public: + CallExpression(ExpressionNode *b, ArgumentList *a): + base (b), arguments (a) + { kind = Kind_CallExpression; } + + virtual ~CallExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; + ArgumentList *arguments; + SourceLocation lparenToken; + SourceLocation rparenToken; +}; + +class ArgumentList: public Node +{ +public: + ArgumentList(ExpressionNode *e): + expression (e), next (this) + { kind = Kind_ArgumentList; } + + ArgumentList(ArgumentList *previous, ExpressionNode *e): + expression (e) + { + kind = Kind_ArgumentList; + next = previous->next; + previous->next = this; + } + + virtual ~ArgumentList() {} + + virtual void accept0(Visitor *visitor); + + inline ArgumentList *finish () + { + ArgumentList *front = next; + next = 0; + return front; + } + +// attributes + ExpressionNode *expression; + ArgumentList *next; + SourceLocation commaToken; +}; + +class PostIncrementExpression: public ExpressionNode +{ +public: + PostIncrementExpression(ExpressionNode *b): + base (b) { kind = Kind_PostIncrementExpression; } + + virtual ~PostIncrementExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; +}; + +class PostDecrementExpression: public ExpressionNode +{ +public: + PostDecrementExpression(ExpressionNode *b): + base (b) { kind = Kind_PostDecrementExpression; } + + virtual ~PostDecrementExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *base; +}; + +class DeleteExpression: public ExpressionNode +{ +public: + DeleteExpression(ExpressionNode *e): + expression (e) { kind = Kind_DeleteExpression; } + virtual ~DeleteExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class VoidExpression: public ExpressionNode +{ +public: + VoidExpression(ExpressionNode *e): + expression (e) { kind = Kind_VoidExpression; } + + virtual ~VoidExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class TypeOfExpression: public ExpressionNode +{ +public: + TypeOfExpression(ExpressionNode *e): + expression (e) { kind = Kind_TypeOfExpression; } + + virtual ~TypeOfExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class PreIncrementExpression: public ExpressionNode +{ +public: + PreIncrementExpression(ExpressionNode *e): + expression (e) { kind = Kind_PreIncrementExpression; } + + virtual ~PreIncrementExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class PreDecrementExpression: public ExpressionNode +{ +public: + PreDecrementExpression(ExpressionNode *e): + expression (e) { kind = Kind_PreDecrementExpression; } + + virtual ~PreDecrementExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class UnaryPlusExpression: public ExpressionNode +{ +public: + UnaryPlusExpression(ExpressionNode *e): + expression (e) { kind = Kind_UnaryPlusExpression; } + + virtual ~UnaryPlusExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class UnaryMinusExpression: public ExpressionNode +{ +public: + UnaryMinusExpression(ExpressionNode *e): + expression (e) { kind = Kind_UnaryMinusExpression; } + + virtual ~UnaryMinusExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class TildeExpression: public ExpressionNode +{ +public: + TildeExpression(ExpressionNode *e): + expression (e) { kind = Kind_TildeExpression; } + + virtual ~TildeExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class NotExpression: public ExpressionNode +{ +public: + NotExpression(ExpressionNode *e): + expression (e) { kind = Kind_NotExpression; } + + virtual ~NotExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class BinaryExpression: public ExpressionNode +{ +public: + BinaryExpression(ExpressionNode *l, int o, ExpressionNode *r): + left (l), op (o), right (r) + { kind = Kind_BinaryExpression; } + + virtual ~BinaryExpression() {} + + virtual BinaryExpression *binaryExpressionCast(); + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *left; + int op; + ExpressionNode *right; +}; + +class ConditionalExpression: public ExpressionNode +{ +public: + ConditionalExpression(ExpressionNode *e, ExpressionNode *t, ExpressionNode *f): + expression (e), ok (t), ko (f) + { kind = Kind_ConditionalExpression; } + + virtual ~ConditionalExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + ExpressionNode *ok; + ExpressionNode *ko; +}; + +class Expression: public ExpressionNode // ### rename +{ +public: + Expression(ExpressionNode *l, ExpressionNode *r): + left (l), right (r) { kind = Kind_Expression; } + + virtual ~Expression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *left; + ExpressionNode *right; +}; + +class Block: public Statement +{ +public: + Block(StatementList *slist): + statements (slist) { kind = Kind_Block; } + + virtual ~Block() {} + + virtual void accept0(Visitor *visitor); + +// attributes + StatementList *statements; +}; + +class StatementList: public Node +{ +public: + StatementList(Statement *stmt): + statement (stmt), next (this) + { kind = Kind_StatementList; } + + StatementList(StatementList *previous, Statement *stmt): + statement (stmt) + { + kind = Kind_StatementList; + next = previous->next; + previous->next = this; + } + + virtual ~StatementList() {} + + virtual void accept0(Visitor *visitor); + + inline StatementList *finish () + { + StatementList *front = next; + next = 0; + return front; + } + +// attributes + Statement *statement; + StatementList *next; +}; + +class VariableStatement: public Statement +{ +public: + VariableStatement(VariableDeclarationList *vlist): + declarations (vlist) + { kind = Kind_VariableStatement; } + + virtual ~VariableStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + VariableDeclarationList *declarations; + SourceLocation declarationKindToken; + SourceLocation semicolonToken; +}; + +class VariableDeclaration: public Node +{ +public: + VariableDeclaration(JavaScriptNameIdImpl *n, ExpressionNode *e): + name (n), expression (e), readOnly(false) + { kind = Kind_VariableDeclaration; } + + virtual ~VariableDeclaration() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *name; + ExpressionNode *expression; + bool readOnly; + SourceLocation identifierToken; +}; + +class VariableDeclarationList: public Node +{ +public: + VariableDeclarationList(VariableDeclaration *decl): + declaration (decl), next (this) + { kind = Kind_VariableDeclarationList; } + + VariableDeclarationList(VariableDeclarationList *previous, VariableDeclaration *decl): + declaration (decl) + { + kind = Kind_VariableDeclarationList; + next = previous->next; + previous->next = this; + } + + virtual ~VariableDeclarationList() {} + + virtual void accept0(Visitor *visitor); + + inline VariableDeclarationList *finish (bool readOnly) + { + VariableDeclarationList *front = next; + next = 0; + if (readOnly) { + VariableDeclarationList *vdl; + for (vdl = front; vdl != 0; vdl = vdl->next) + vdl->declaration->readOnly = true; + } + return front; + } + +// attributes + VariableDeclaration *declaration; + VariableDeclarationList *next; +}; + +class EmptyStatement: public Statement +{ +public: + EmptyStatement() { kind = Kind_EmptyStatement; } + virtual ~EmptyStatement() {} + + virtual void accept0(Visitor *visitor); +}; + +class ExpressionStatement: public Statement +{ +public: + ExpressionStatement(ExpressionNode *e): + expression (e) { kind = Kind_ExpressionStatement; } + + virtual ~ExpressionStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + SourceLocation semicolonToken; +}; + +class IfStatement: public Statement +{ +public: + IfStatement(ExpressionNode *e, Statement *t, Statement *f = 0): + expression (e), ok (t), ko (f) + { kind = Kind_IfStatement; } + + virtual ~IfStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + Statement *ok; + Statement *ko; +}; + +class DoWhileStatement: public Statement +{ +public: + DoWhileStatement(Statement *stmt, ExpressionNode *e): + statement (stmt), expression (e) + { kind = Kind_DoWhileStatement; } + + virtual ~DoWhileStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + Statement *statement; + ExpressionNode *expression; +}; + +class WhileStatement: public Statement +{ +public: + WhileStatement(ExpressionNode *e, Statement *stmt): + expression (e), statement (stmt) + { kind = Kind_WhileStatement; } + + virtual ~WhileStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + Statement *statement; +}; + +class ForStatement: public Statement +{ +public: + ForStatement(ExpressionNode *i, ExpressionNode *c, ExpressionNode *e, Statement *stmt): + initialiser (i), condition (c), expression (e), statement (stmt) + { kind = Kind_ForStatement; } + + virtual ~ForStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *initialiser; + ExpressionNode *condition; + ExpressionNode *expression; + Statement *statement; +}; + +class LocalForStatement: public Statement +{ +public: + LocalForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt): + declarations (vlist), condition (c), expression (e), statement (stmt) + { kind = Kind_LocalForStatement; } + + virtual ~LocalForStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + VariableDeclarationList *declarations; + ExpressionNode *condition; + ExpressionNode *expression; + Statement *statement; +}; + +class ForEachStatement: public Statement +{ +public: + ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt): + initialiser (i), expression (e), statement (stmt) + { kind = Kind_ForEachStatement; } + + virtual ~ForEachStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *initialiser; + ExpressionNode *expression; + Statement *statement; +}; + +class LocalForEachStatement: public Statement +{ +public: + LocalForEachStatement(VariableDeclaration *v, ExpressionNode *e, Statement *stmt): + declaration (v), expression (e), statement (stmt) + { kind = Kind_LocalForEachStatement; } + + virtual ~LocalForEachStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + VariableDeclaration *declaration; + ExpressionNode *expression; + Statement *statement; +}; + +class ContinueStatement: public Statement +{ +public: + ContinueStatement(JavaScriptNameIdImpl *l = 0): + label (l) { kind = Kind_ContinueStatement; } + + virtual ~ContinueStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *label; +}; + +class BreakStatement: public Statement +{ +public: + BreakStatement(JavaScriptNameIdImpl *l = 0): + label (l) { kind = Kind_BreakStatement; } + + virtual ~BreakStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *label; +}; + +class ReturnStatement: public Statement +{ +public: + ReturnStatement(ExpressionNode *e): + expression (e) { kind = Kind_ReturnStatement; } + + virtual ~ReturnStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class WithStatement: public Statement +{ +public: + WithStatement(ExpressionNode *e, Statement *stmt): + expression (e), statement (stmt) + { kind = Kind_WithStatement; } + + virtual ~WithStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + Statement *statement; +}; + +class SwitchStatement: public Statement +{ +public: + SwitchStatement(ExpressionNode *e, CaseBlock *b): + expression (e), block (b) + { kind = Kind_SwitchStatement; } + + virtual ~SwitchStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + CaseBlock *block; +}; + +class CaseBlock: public Node +{ +public: + CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0): + clauses (c), defaultClause (d), moreClauses (r) + { kind = Kind_CaseBlock; } + + virtual ~CaseBlock() {} + + virtual void accept0(Visitor *visitor); + +// attributes + CaseClauses *clauses; + DefaultClause *defaultClause; + CaseClauses *moreClauses; +}; + +class CaseClauses: public Node +{ +public: + CaseClauses(CaseClause *c): + clause (c), next (this) + { kind = Kind_CaseClauses; } + + CaseClauses(CaseClauses *previous, CaseClause *c): + clause (c) + { + kind = Kind_CaseClauses; + next = previous->next; + previous->next = this; + } + + virtual ~CaseClauses() {} + + virtual void accept0(Visitor *visitor); + + inline CaseClauses *finish () + { + CaseClauses *front = next; + next = 0; + return front; + } + +//attributes + CaseClause *clause; + CaseClauses *next; +}; + +class CaseClause: public Node +{ +public: + CaseClause(ExpressionNode *e, StatementList *slist): + expression (e), statements (slist) + { kind = Kind_CaseClause; } + + virtual ~CaseClause() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; + StatementList *statements; +}; + +class DefaultClause: public Node +{ +public: + DefaultClause(StatementList *slist): + statements (slist) + { kind = Kind_DefaultClause; } + + virtual ~DefaultClause() {} + + virtual void accept0(Visitor *visitor); + +// attributes + StatementList *statements; +}; + +class LabelledStatement: public Statement +{ +public: + LabelledStatement(JavaScriptNameIdImpl *l, Statement *stmt): + label (l), statement (stmt) + { kind = Kind_LabelledStatement; } + + virtual ~LabelledStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *label; + Statement *statement; +}; + +class ThrowStatement: public Statement +{ +public: + ThrowStatement(ExpressionNode *e): + expression (e) { kind = Kind_ThrowStatement; } + + virtual ~ThrowStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + ExpressionNode *expression; +}; + +class TryStatement: public Statement +{ +public: + TryStatement(Statement *stmt, Catch *c, Finally *f): + statement (stmt), catchExpression (c), finallyExpression (f) + { kind = Kind_TryStatement; } + + TryStatement(Statement *stmt, Finally *f): + statement (stmt), catchExpression (0), finallyExpression (f) + { kind = Kind_TryStatement; } + + TryStatement(Statement *stmt, Catch *c): + statement (stmt), catchExpression (c), finallyExpression (0) + { kind = Kind_TryStatement; } + + virtual ~TryStatement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + Statement *statement; + Catch *catchExpression; + Finally *finallyExpression; +}; + +class Catch: public Node +{ +public: + Catch(JavaScriptNameIdImpl *n, Statement *stmt): + name (n), statement (stmt) + { kind = Kind_Catch; } + + virtual ~Catch() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *name; + Statement *statement; +}; + +class Finally: public Node +{ +public: + Finally(Statement *stmt): + statement (stmt) + { kind = Kind_Finally; } + + virtual ~Finally() {} + + virtual void accept0(Visitor *visitor); + +// attributes + Statement *statement; +}; + +class FunctionExpression: public ExpressionNode +{ +public: + FunctionExpression(JavaScriptNameIdImpl *n, FormalParameterList *f, FunctionBody *b): + name (n), formals (f), body (b) + { kind = Kind_FunctionExpression; } + + virtual ~FunctionExpression() {} + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *name; + FormalParameterList *formals; + FunctionBody *body; + SourceLocation functionToken; + SourceLocation identifierToken; + SourceLocation lparenToken; + SourceLocation rparenToken; + SourceLocation lbraceToken; + SourceLocation rbraceToken; +}; + +class FunctionDeclaration: public FunctionExpression +{ +public: + FunctionDeclaration(JavaScriptNameIdImpl *n, FormalParameterList *f, FunctionBody *b): + FunctionExpression(n, f, b) + { kind = Kind_FunctionDeclaration; } + + virtual ~FunctionDeclaration() {} + + virtual void accept0(Visitor *visitor); +}; + +class FormalParameterList: public Node +{ +public: + FormalParameterList(JavaScriptNameIdImpl *n): + name (n), next (this) + { kind = Kind_FormalParameterList; } + + FormalParameterList(FormalParameterList *previous, JavaScriptNameIdImpl *n): + name (n) + { + kind = Kind_FormalParameterList; + next = previous->next; + previous->next = this; + } + + virtual ~FormalParameterList() {} + + virtual void accept0(Visitor *visitor); + + inline FormalParameterList *finish () + { + FormalParameterList *front = next; + next = 0; + return front; + } + +// attributes + JavaScriptNameIdImpl *name; + FormalParameterList *next; + SourceLocation commaToken; + SourceLocation identifierToken; +}; + +class FunctionBody: public Node +{ +public: + FunctionBody(SourceElements *elts): + elements (elts) + { kind = Kind_FunctionBody; } + + virtual ~FunctionBody() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceElements *elements; +}; + +class Program: public Node +{ +public: + Program(SourceElements *elts): + elements (elts) + { kind = Kind_Program; } + + virtual ~Program() {} + + virtual void accept0(Visitor *visitor); + +// attributes + SourceElements *elements; +}; + +class SourceElements: public Node +{ +public: + SourceElements(SourceElement *elt): + element (elt), next (this) + { kind = Kind_SourceElements; } + + SourceElements(SourceElements *previous, SourceElement *elt): + element (elt) + { + kind = Kind_SourceElements; + next = previous->next; + previous->next = this; + } + + virtual ~SourceElements() {} + + virtual void accept0(Visitor *visitor); + + inline SourceElements *finish () + { + SourceElements *front = next; + next = 0; + return front; + } + +// attributes + SourceElement *element; + SourceElements *next; +}; + +class SourceElement: public Node +{ +public: + inline SourceElement() + { kind = Kind_SourceElement; } + + virtual ~SourceElement() {} +}; + +class FunctionSourceElement: public SourceElement +{ +public: + FunctionSourceElement(FunctionDeclaration *f): + declaration (f) + { kind = Kind_FunctionSourceElement; } + + virtual ~FunctionSourceElement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + FunctionDeclaration *declaration; +}; + +class StatementSourceElement: public SourceElement +{ +public: + StatementSourceElement(Statement *stmt): + statement (stmt) + { kind = Kind_StatementSourceElement; } + + virtual ~StatementSourceElement() {} + + virtual void accept0(Visitor *visitor); + +// attributes + Statement *statement; +}; + +class DebuggerStatement: public Statement +{ +public: + DebuggerStatement() + { kind = Kind_DebuggerStatement; } + + virtual ~DebuggerStatement() {} + + virtual void accept0(Visitor *visitor); +}; + +class UiProgram: public Node +{ +public: + UiProgram(UiObjectMemberList *members) + : members(members) + { kind = Kind_UiProgram; } + + virtual void accept0(Visitor *visitor); + +// attributes + UiObjectMemberList *members; +}; + +class UiObjectMember: public Node +{ +}; + +class UiPublicMember: public UiObjectMember +{ +public: + UiPublicMember(JavaScriptNameIdImpl *type, + JavaScriptNameIdImpl *name) + : type(type), name(name), expression(0), initializer(0) + { kind = Kind_UiPublicMember; } + + UiPublicMember(JavaScriptNameIdImpl *type, + JavaScriptNameIdImpl *name, + ExpressionNode *expression, + UiObjectInitializer *initializer) + : type(type), name(name), + expression(expression), initializer(initializer) + { kind = Kind_UiPublicMember; } + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *type; + JavaScriptNameIdImpl *name; + ExpressionNode *expression; + UiObjectInitializer *initializer; + SourceLocation publicToken; + SourceLocation attributeTypeToken; + SourceLocation identifierToken; + SourceLocation colonToken; +}; + +class UiObjectDefinition: public UiObjectMember +{ +public: + UiObjectDefinition(JavaScriptNameIdImpl *name, + UiObjectInitializer *initializer) + : name(name), initializer(initializer) + { kind = Kind_UiObjectDefinition; } + + virtual void accept0(Visitor *visitor); + +// attributes + JavaScriptNameIdImpl *name; + UiObjectInitializer *initializer; + SourceLocation identifierToken; +}; + +class UiObjectInitializer: public Node +{ +public: + UiObjectInitializer(UiObjectMemberList *members) + : members(members) + { kind = Kind_UiObjectInitializer; } + + virtual void accept0(Visitor *visitor); + +// attributes + SourceLocation lbraceToken; + UiObjectMemberList *members; + SourceLocation rbraceToken; +}; + +class UiObjectBinding: public UiObjectMember +{ +public: + UiObjectBinding(UiQualifiedId *qualifiedId, + JavaScriptNameIdImpl *name, + UiObjectInitializer *initializer) + : qualifiedId(qualifiedId), + name(name), + initializer(initializer) + { kind = Kind_UiObjectBinding; } + + virtual void accept0(Visitor *visitor); + +// attributes + UiQualifiedId *qualifiedId; + JavaScriptNameIdImpl *name; + UiObjectInitializer *initializer; + SourceLocation colonToken; + SourceLocation identifierToken; +}; + +class UiScriptBinding: public UiObjectMember +{ +public: + UiScriptBinding(UiQualifiedId *qualifiedId, + Statement *statement) + : qualifiedId(qualifiedId), + statement(statement) + { kind = Kind_UiScriptBinding; } + + virtual void accept0(Visitor *visitor); + +// attributes + UiQualifiedId *qualifiedId; + Statement *statement; + SourceLocation colonToken; +}; + +class UiArrayBinding: public UiObjectMember +{ +public: + UiArrayBinding(UiQualifiedId *qualifiedId, + UiObjectMemberList *members) + : qualifiedId(qualifiedId), + members(members) + { kind = Kind_UiArrayBinding; } + + virtual void accept0(Visitor *visitor); + +// attributes + UiQualifiedId *qualifiedId; + UiObjectMemberList *members; + SourceLocation colonToken; + SourceLocation lbracketToken; + SourceLocation rbraceToken; +}; + +class UiObjectMemberList: public Node +{ +public: + UiObjectMemberList(UiObjectMember *member) + : next(this), member(member) + { kind = Kind_UiObjectMemberList; } + + UiObjectMemberList(UiObjectMemberList *previous, UiObjectMember *member) + : member(member) + { + kind = Kind_UiObjectMemberList; + next = previous->next; + previous->next = this; + } + + virtual void accept0(Visitor *visitor); + + UiObjectMemberList *finish() + { + UiObjectMemberList *head = next; + next = 0; + return head; + } + +// attributes + UiObjectMemberList *next; + UiObjectMember *member; +}; + +class UiQualifiedId: public Node +{ +public: + UiQualifiedId(JavaScriptNameIdImpl *name) + : next(this), name(name) + { kind = Kind_UiQualifiedId; } + + UiQualifiedId(UiQualifiedId *previous, JavaScriptNameIdImpl *name) + : name(name) + { + kind = Kind_UiQualifiedId; + next = previous->next; + previous->next = this; + } + + virtual ~UiQualifiedId() {} + + UiQualifiedId *finish() + { + UiQualifiedId *head = next; + next = 0; + return head; + } + + virtual void accept0(Visitor *visitor); + +// attributes + UiQualifiedId *next; + JavaScriptNameIdImpl *name; + SourceLocation identifierToken; +}; + + +} } // namespace AST + + + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/qml/parser/javascriptastfwd_p.h b/src/declarative/qml/parser/javascriptastfwd_p.h new file mode 100644 index 0000000..946879a --- /dev/null +++ b/src/declarative/qml/parser/javascriptastfwd_p.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTAST_FWD_P_H +#define JAVASCRIPTAST_FWD_P_H + +#include <QtCore/qglobal.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +namespace JavaScript { namespace AST { + +class SourceLocation; + +class Visitor; +class Node; +class ExpressionNode; +class Statement; +class ThisExpression; +class IdentifierExpression; +class NullExpression; +class TrueLiteral; +class FalseLiteral; +class NumericLiteral; +class StringLiteral; +class RegExpLiteral; +class ArrayLiteral; +class ObjectLiteral; +class ElementList; +class Elision; +class PropertyNameAndValueList; +class PropertyName; +class IdentifierPropertyName; +class StringLiteralPropertyName; +class NumericLiteralPropertyName; +class ArrayMemberExpression; +class FieldMemberExpression; +class NewMemberExpression; +class NewExpression; +class CallExpression; +class ArgumentList; +class PostIncrementExpression; +class PostDecrementExpression; +class DeleteExpression; +class VoidExpression; +class TypeOfExpression; +class PreIncrementExpression; +class PreDecrementExpression; +class UnaryPlusExpression; +class UnaryMinusExpression; +class TildeExpression; +class NotExpression; +class BinaryExpression; +class ConditionalExpression; +class Expression; // ### rename +class Block; +class StatementList; +class VariableStatement; +class VariableDeclarationList; +class VariableDeclaration; +class EmptyStatement; +class ExpressionStatement; +class IfStatement; +class DoWhileStatement; +class WhileStatement; +class ForStatement; +class LocalForStatement; +class ForEachStatement; +class LocalForEachStatement; +class ContinueStatement; +class BreakStatement; +class ReturnStatement; +class WithStatement; +class SwitchStatement; +class CaseBlock; +class CaseClauses; +class CaseClause; +class DefaultClause; +class LabelledStatement; +class ThrowStatement; +class TryStatement; +class Catch; +class Finally; +class FunctionDeclaration; +class FunctionExpression; +class FormalParameterList; +class FunctionBody; +class Program; +class SourceElements; +class SourceElement; +class FunctionSourceElement; +class StatementSourceElement; +class DebuggerStatement; + +// ui elements +class UiProgram; +class UiPublicMember; +class UiObjectDefinition; +class UiObjectInitializer; +class UiObjectBinding; +class UiScriptBinding; +class UiArrayBinding; +class UiObjectMember; +class UiObjectMemberList; +class UiQualifiedId; + +} } // namespace AST + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/qml/parser/javascriptastvisitor.cpp b/src/declarative/qml/parser/javascriptastvisitor.cpp new file mode 100644 index 0000000..eac291d --- /dev/null +++ b/src/declarative/qml/parser/javascriptastvisitor.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "javascriptastvisitor_p.h" + +QT_BEGIN_NAMESPACE + +namespace JavaScript { namespace AST { + +Visitor::Visitor() +{ +} + +Visitor::~Visitor() +{ +} + +} } // namespace JavaScript::AST + +QT_END_NAMESPACE diff --git a/src/declarative/qml/parser/javascriptastvisitor_p.h b/src/declarative/qml/parser/javascriptastvisitor_p.h new file mode 100644 index 0000000..9e428cb --- /dev/null +++ b/src/declarative/qml/parser/javascriptastvisitor_p.h @@ -0,0 +1,317 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTASTVISITOR_P_H +#define JAVASCRIPTASTVISITOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "javascriptastfwd_p.h" + +QT_BEGIN_NAMESPACE + +namespace JavaScript { namespace AST { + +class Visitor +{ +public: + Visitor(); + virtual ~Visitor(); + + virtual bool preVisit(Node *) { return true; } + virtual void postVisit(Node *) {} + + // Ui + virtual bool visit(UiProgram *) { return true; } + virtual bool visit(UiPublicMember *) { return true; } + virtual bool visit(UiObjectDefinition *) { return true; } + virtual bool visit(UiObjectInitializer *) { return true; } + virtual bool visit(UiObjectBinding *) { return true; } + virtual bool visit(UiScriptBinding *) { return true; } + virtual bool visit(UiArrayBinding *) { return true; } + virtual bool visit(UiObjectMemberList *) { return true; } + virtual bool visit(UiQualifiedId *) { return true; } + + virtual void endVisit(UiProgram *) {} + virtual void endVisit(UiPublicMember *) {} + virtual void endVisit(UiObjectDefinition *) {} + virtual void endVisit(UiObjectInitializer *) {} + virtual void endVisit(UiObjectBinding *) {} + virtual void endVisit(UiScriptBinding *) {} + virtual void endVisit(UiArrayBinding *) {} + virtual void endVisit(UiObjectMemberList *) {} + virtual void endVisit(UiQualifiedId *) {} + + // JavaScript + virtual bool visit(ThisExpression *) { return true; } + virtual void endVisit(ThisExpression *) {} + + virtual bool visit(IdentifierExpression *) { return true; } + virtual void endVisit(IdentifierExpression *) {} + + virtual bool visit(NullExpression *) { return true; } + virtual void endVisit(NullExpression *) {} + + virtual bool visit(TrueLiteral *) { return true; } + virtual void endVisit(TrueLiteral *) {} + + virtual bool visit(FalseLiteral *) { return true; } + virtual void endVisit(FalseLiteral *) {} + + virtual bool visit(StringLiteral *) { return true; } + virtual void endVisit(StringLiteral *) {} + + virtual bool visit(NumericLiteral *) { return true; } + virtual void endVisit(NumericLiteral *) {} + + virtual bool visit(RegExpLiteral *) { return true; } + virtual void endVisit(RegExpLiteral *) {} + + virtual bool visit(ArrayLiteral *) { return true; } + virtual void endVisit(ArrayLiteral *) {} + + virtual bool visit(ObjectLiteral *) { return true; } + virtual void endVisit(ObjectLiteral *) {} + + virtual bool visit(ElementList *) { return true; } + virtual void endVisit(ElementList *) {} + + virtual bool visit(Elision *) { return true; } + virtual void endVisit(Elision *) {} + + virtual bool visit(PropertyNameAndValueList *) { return true; } + virtual void endVisit(PropertyNameAndValueList *) {} + + virtual bool visit(IdentifierPropertyName *) { return true; } + virtual void endVisit(IdentifierPropertyName *) {} + + virtual bool visit(StringLiteralPropertyName *) { return true; } + virtual void endVisit(StringLiteralPropertyName *) {} + + virtual bool visit(NumericLiteralPropertyName *) { return true; } + virtual void endVisit(NumericLiteralPropertyName *) {} + + virtual bool visit(ArrayMemberExpression *) { return true; } + virtual void endVisit(ArrayMemberExpression *) {} + + virtual bool visit(FieldMemberExpression *) { return true; } + virtual void endVisit(FieldMemberExpression *) {} + + virtual bool visit(NewMemberExpression *) { return true; } + virtual void endVisit(NewMemberExpression *) {} + + virtual bool visit(NewExpression *) { return true; } + virtual void endVisit(NewExpression *) {} + + virtual bool visit(CallExpression *) { return true; } + virtual void endVisit(CallExpression *) {} + + virtual bool visit(ArgumentList *) { return true; } + virtual void endVisit(ArgumentList *) {} + + virtual bool visit(PostIncrementExpression *) { return true; } + virtual void endVisit(PostIncrementExpression *) {} + + virtual bool visit(PostDecrementExpression *) { return true; } + virtual void endVisit(PostDecrementExpression *) {} + + virtual bool visit(DeleteExpression *) { return true; } + virtual void endVisit(DeleteExpression *) {} + + virtual bool visit(VoidExpression *) { return true; } + virtual void endVisit(VoidExpression *) {} + + virtual bool visit(TypeOfExpression *) { return true; } + virtual void endVisit(TypeOfExpression *) {} + + virtual bool visit(PreIncrementExpression *) { return true; } + virtual void endVisit(PreIncrementExpression *) {} + + virtual bool visit(PreDecrementExpression *) { return true; } + virtual void endVisit(PreDecrementExpression *) {} + + virtual bool visit(UnaryPlusExpression *) { return true; } + virtual void endVisit(UnaryPlusExpression *) {} + + virtual bool visit(UnaryMinusExpression *) { return true; } + virtual void endVisit(UnaryMinusExpression *) {} + + virtual bool visit(TildeExpression *) { return true; } + virtual void endVisit(TildeExpression *) {} + + virtual bool visit(NotExpression *) { return true; } + virtual void endVisit(NotExpression *) {} + + virtual bool visit(BinaryExpression *) { return true; } + virtual void endVisit(BinaryExpression *) {} + + virtual bool visit(ConditionalExpression *) { return true; } + virtual void endVisit(ConditionalExpression *) {} + + virtual bool visit(Expression *) { return true; } + virtual void endVisit(Expression *) {} + + virtual bool visit(Block *) { return true; } + virtual void endVisit(Block *) {} + + virtual bool visit(StatementList *) { return true; } + virtual void endVisit(StatementList *) {} + + virtual bool visit(VariableStatement *) { return true; } + virtual void endVisit(VariableStatement *) {} + + virtual bool visit(VariableDeclarationList *) { return true; } + virtual void endVisit(VariableDeclarationList *) {} + + virtual bool visit(VariableDeclaration *) { return true; } + virtual void endVisit(VariableDeclaration *) {} + + virtual bool visit(EmptyStatement *) { return true; } + virtual void endVisit(EmptyStatement *) {} + + virtual bool visit(ExpressionStatement *) { return true; } + virtual void endVisit(ExpressionStatement *) {} + + virtual bool visit(IfStatement *) { return true; } + virtual void endVisit(IfStatement *) {} + + virtual bool visit(DoWhileStatement *) { return true; } + virtual void endVisit(DoWhileStatement *) {} + + virtual bool visit(WhileStatement *) { return true; } + virtual void endVisit(WhileStatement *) {} + + virtual bool visit(ForStatement *) { return true; } + virtual void endVisit(ForStatement *) {} + + virtual bool visit(LocalForStatement *) { return true; } + virtual void endVisit(LocalForStatement *) {} + + virtual bool visit(ForEachStatement *) { return true; } + virtual void endVisit(ForEachStatement *) {} + + virtual bool visit(LocalForEachStatement *) { return true; } + virtual void endVisit(LocalForEachStatement *) {} + + virtual bool visit(ContinueStatement *) { return true; } + virtual void endVisit(ContinueStatement *) {} + + virtual bool visit(BreakStatement *) { return true; } + virtual void endVisit(BreakStatement *) {} + + virtual bool visit(ReturnStatement *) { return true; } + virtual void endVisit(ReturnStatement *) {} + + virtual bool visit(WithStatement *) { return true; } + virtual void endVisit(WithStatement *) {} + + virtual bool visit(SwitchStatement *) { return true; } + virtual void endVisit(SwitchStatement *) {} + + virtual bool visit(CaseBlock *) { return true; } + virtual void endVisit(CaseBlock *) {} + + virtual bool visit(CaseClauses *) { return true; } + virtual void endVisit(CaseClauses *) {} + + virtual bool visit(CaseClause *) { return true; } + virtual void endVisit(CaseClause *) {} + + virtual bool visit(DefaultClause *) { return true; } + virtual void endVisit(DefaultClause *) {} + + virtual bool visit(LabelledStatement *) { return true; } + virtual void endVisit(LabelledStatement *) {} + + virtual bool visit(ThrowStatement *) { return true; } + virtual void endVisit(ThrowStatement *) {} + + virtual bool visit(TryStatement *) { return true; } + virtual void endVisit(TryStatement *) {} + + virtual bool visit(Catch *) { return true; } + virtual void endVisit(Catch *) {} + + virtual bool visit(Finally *) { return true; } + virtual void endVisit(Finally *) {} + + virtual bool visit(FunctionDeclaration *) { return true; } + virtual void endVisit(FunctionDeclaration *) {} + + virtual bool visit(FunctionExpression *) { return true; } + virtual void endVisit(FunctionExpression *) {} + + 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 *) {} +}; + +} } // namespace AST + +QT_END_NAMESPACE + +#endif // JAVASCRIPTASTVISITOR_P_H diff --git a/src/declarative/qml/parser/javascriptengine_p.cpp b/src/declarative/qml/parser/javascriptengine_p.cpp new file mode 100644 index 0000000..ca15b75 --- /dev/null +++ b/src/declarative/qml/parser/javascriptengine_p.cpp @@ -0,0 +1,157 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#include "javascriptengine_p.h" +#include "javascriptnodepool_p.h" +#include "javascriptvalue.h" +#include <qnumeric.h> +#include <QHash> + +QT_BEGIN_NAMESPACE + +namespace JavaScript { + +QString numberToString(qjsreal value) +{ return QString::number(value); } + +int Ecma::RegExp::flagFromChar(const QChar &ch) +{ + static QHash<QChar, int> flagsHash; + if (flagsHash.isEmpty()) { + flagsHash[QLatin1Char('g')] = Global; + flagsHash[QLatin1Char('i')] = IgnoreCase; + flagsHash[QLatin1Char('m')] = Multiline; + } + QHash<QChar, int>::const_iterator it; + it = flagsHash.constFind(ch); + if (it == flagsHash.constEnd()) + return 0; + return it.value(); +} + +QString Ecma::RegExp::flagsToString(int flags) +{ + QString result; + if (flags & Global) + result += QLatin1Char('g'); + if (flags & IgnoreCase) + result += QLatin1Char('i'); + if (flags & Multiline) + result += QLatin1Char('m'); + return result; +} + +NodePool::NodePool(const QString &fileName, JavaScriptEnginePrivate *engine) + : m_fileName(fileName), m_engine(engine) +{ +} + +NodePool::~NodePool() +{ +} + +Code *NodePool::createCompiledCode(AST::Node *, CompilationUnit &) +{ + Q_ASSERT(0); + return 0; +} + +static int toDigit(char c) +{ + if ((c >= '0') && (c <= '9')) + return c - '0'; + else if ((c >= 'a') && (c <= 'z')) + return 10 + c - 'a'; + else if ((c >= 'A') && (c <= 'Z')) + return 10 + c - 'A'; + return -1; +} + +qjsreal integerFromString(const char *buf, int size, int radix) +{ + if (size == 0) + return qSNaN(); + + qjsreal sign = 1.0; + int i = 0; + if (buf[0] == '+') { + ++i; + } else if (buf[0] == '-') { + sign = -1.0; + ++i; + } + + if (((size-i) >= 2) && (buf[i] == '0')) { + if (((buf[i+1] == 'x') || (buf[i+1] == 'X')) + && (radix < 34)) { + if ((radix != 0) && (radix != 16)) + return 0; + radix = 16; + i += 2; + } else { + if (radix == 0) { + radix = 8; + ++i; + } + } + } else if (radix == 0) { + radix = 10; + } + + int j = i; + for ( ; i < size; ++i) { + int d = toDigit(buf[i]); + if ((d == -1) || (d >= radix)) + break; + } + qjsreal result; + if (j == i) { + if (!qstrcmp(buf, "Infinity")) + result = qInf(); + else + result = qSNaN(); + } else { + result = 0; + qjsreal multiplier = 1; + for (--i ; i >= j; --i, multiplier *= radix) + result += toDigit(buf[i]) * multiplier; + } + result *= sign; + return result; +} + +qjsreal integerFromString(const QString &str, int radix) +{ + QByteArray ba = str.trimmed().toUtf8(); + return integerFromString(ba.constData(), ba.size(), radix); +} + +} // end of namespace JavaScript + +QT_END_NAMESPACE diff --git a/src/declarative/qml/parser/javascriptengine_p.h b/src/declarative/qml/parser/javascriptengine_p.h new file mode 100644 index 0000000..1e6e568 --- /dev/null +++ b/src/declarative/qml/parser/javascriptengine_p.h @@ -0,0 +1,144 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** +**************************************************************************/ + +#ifndef JAVASCRIPTENGINE_P_H +#define JAVASCRIPTENGINE_P_H + +#include "javascriptvalue.h" +#include <QString> +#include <QSet> + +QT_BEGIN_NAMESPACE + +namespace JavaScript { + +class Node; +class Lexer; +class NodePool; + +namespace AST { + +class Node; + +} // end of namespace AST + +namespace Ecma { + +class RegExp +{ +public: + enum RegExpFlag { + Global = 0x01, + IgnoreCase = 0x02, + Multiline = 0x04 + }; + +public: + static int flagFromChar(const QChar &); + static QString flagsToString(int flags); +}; + +} // end of namespace Ecma + +} // end of namespace JavaScript + + + +class JavaScriptNameIdImpl +{ + QString _text; + +public: + JavaScriptNameIdImpl(const QChar *u, int s) + : _text(u, s) + { } + + const QString asString() const + { return _text; } + + bool operator == (const JavaScriptNameIdImpl &other) const + { return _text == other._text; } + + bool operator != (const JavaScriptNameIdImpl &other) const + { return _text != other._text; } + + bool operator < (const JavaScriptNameIdImpl &other) const + { return _text < other._text; } +}; + +inline uint qHash(const JavaScriptNameIdImpl &id) +{ return qHash(id.asString()); } + +class JavaScriptEnginePrivate +{ + JavaScript::Lexer *_lexer; + JavaScript::NodePool *_nodePool; + JavaScript::AST::Node *_ast; + QSet<JavaScriptNameIdImpl> _literals; + +public: + JavaScriptEnginePrivate() + : _lexer(0), _nodePool(0), _ast(0) + { } + + QSet<JavaScriptNameIdImpl> literals() const + { return _literals; } + + JavaScriptNameIdImpl *intern(const QChar *u, int s) + { return const_cast<JavaScriptNameIdImpl *>(&*_literals.insert(JavaScriptNameIdImpl(u, s))); } + + static QString toString(JavaScriptNameIdImpl *id) + { return id->asString(); } + + JavaScript::Lexer *lexer() const + { return _lexer; } + + void setLexer(JavaScript::Lexer *lexer) + { _lexer = lexer; } + + JavaScript::NodePool *nodePool() const + { return _nodePool; } + + void setNodePool(JavaScript::NodePool *nodePool) + { _nodePool = nodePool; } + + JavaScript::AST::Node *ast() const + { return _ast; } + + JavaScript::AST::Node *changeAbstractSyntaxTree(JavaScript::AST::Node *node) + { + JavaScript::AST::Node *previousAST = _ast; + _ast = node; + return previousAST; + } +}; + +QT_END_NAMESPACE + +#endif // JAVASCRIPTENGINE_P_H diff --git a/src/declarative/qml/parser/javascriptgrammar.cpp b/src/declarative/qml/parser/javascriptgrammar.cpp new file mode 100644 index 0000000..a8da9a6 --- /dev/null +++ b/src/declarative/qml/parser/javascriptgrammar.cpp @@ -0,0 +1,623 @@ +// This file was generated by qlalr - DO NOT EDIT! +#include "javascriptgrammar_p.h" + +const char *const JavaScriptGrammar::spell [] = { + "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue", + "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===", + "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier", + "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=", + "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=", + "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return", + ")", ";", 0, "*", "*=", "string literal", "switch", "this", "throw", "~", + "try", "typeof", "var", "void", "while", "with", "^", "^=", "null", "true", + "false", "const", "debugger", "reserved word", "public", 0, 0}; + +const int JavaScriptGrammar::lhs [] = { + 87, 89, 88, 88, 88, 91, 90, 90, 90, 90, + 90, 90, 90, 92, 92, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 97, 97, 101, 101, 96, 96, 99, 99, 102, 102, + 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 104, 104, 105, 105, 105, 105, 105, + 108, 108, 109, 109, 109, 109, 107, 107, 110, 110, + 111, 111, 112, 112, 112, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 114, 114, 114, 114, 115, + 115, 115, 116, 116, 116, 116, 117, 117, 117, 117, + 117, 117, 117, 118, 118, 118, 118, 118, 118, 119, + 119, 119, 119, 119, 120, 120, 120, 120, 120, 121, + 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, + 126, 127, 127, 128, 128, 129, 129, 130, 130, 131, + 131, 132, 132, 100, 100, 133, 133, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 94, + 94, 135, 135, 136, 136, 137, 137, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 138, 154, 154, 153, 153, 139, 139, 155, + 155, 156, 156, 158, 158, 157, 159, 162, 160, 160, + 163, 161, 161, 140, 141, 141, 142, 142, 143, 143, + 143, 143, 143, 143, 143, 144, 144, 144, 144, 145, + 145, 145, 145, 146, 146, 147, 149, 164, 164, 167, + 167, 165, 165, 168, 166, 148, 150, 150, 151, 151, + 151, 169, 170, 152, 152, 171, 106, 175, 175, 172, + 172, 173, 173, 176, 177, 177, 178, 178, 174, 174, + 98, 98, 179}; + +const int JavaScriptGrammar:: rhs[] = { + 1, 0, 1, 3, 3, 3, 4, 2, 5, 3, + 6, 3, 5, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 5, 3, 4, 3, + 2, 4, 1, 2, 0, 1, 3, 5, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 3, 5, + 1, 2, 4, 4, 4, 3, 0, 1, 1, 3, + 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 3, 3, 3, 1, + 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, + 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, + 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, + 5, 1, 5, 1, 3, 1, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 3, 0, 1, 1, 3, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 2, 0, 1, 3, 3, 1, + 1, 1, 3, 1, 3, 2, 2, 2, 0, 1, + 2, 0, 1, 1, 2, 2, 7, 5, 7, 7, + 5, 9, 10, 7, 8, 2, 2, 3, 3, 2, + 2, 3, 3, 3, 3, 5, 5, 3, 5, 1, + 2, 0, 1, 4, 3, 3, 3, 3, 3, 3, + 4, 5, 2, 2, 2, 8, 8, 1, 3, 0, + 1, 0, 1, 1, 1, 2, 1, 1, 0, 1, + 0, 1, 2}; + +const int JavaScriptGrammar::action_default [] = { + 0, 0, 14, 0, 3, 2, 0, 283, 0, 8, + 2, 0, 0, 6, 4, 5, 0, 12, 0, 113, + 180, 144, 152, 148, 92, 164, 140, 13, 77, 93, + 156, 160, 81, 110, 91, 96, 76, 130, 117, 0, + 23, 24, 20, 279, 17, 281, 35, 0, 0, 0, + 0, 0, 18, 21, 0, 0, 22, 16, 0, 19, + 0, 0, 106, 0, 0, 93, 112, 95, 94, 0, + 0, 0, 108, 109, 107, 111, 0, 141, 0, 0, + 0, 0, 131, 0, 0, 0, 0, 0, 0, 121, + 0, 0, 0, 115, 116, 114, 119, 123, 122, 120, + 118, 133, 132, 134, 0, 149, 0, 145, 0, 0, + 87, 86, 75, 43, 44, 45, 70, 46, 71, 47, + 48, 49, 50, 51, 52, 53, 54, 74, 55, 56, + 57, 58, 59, 72, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 73, 0, 0, 85, 181, 88, + 0, 89, 0, 90, 84, 11, 0, 177, 170, 168, + 175, 176, 174, 173, 179, 172, 171, 169, 178, 165, + 0, 153, 0, 0, 157, 0, 0, 161, 0, 0, + 87, 79, 0, 78, 0, 83, 97, 0, 280, 270, + 271, 0, 268, 0, 269, 0, 272, 188, 195, 194, + 202, 190, 0, 191, 273, 0, 278, 192, 193, 198, + 196, 275, 274, 277, 199, 0, 210, 0, 0, 0, + 0, 279, 17, 0, 281, 182, 224, 0, 0, 0, + 211, 0, 0, 200, 201, 0, 189, 197, 225, 226, + 267, 276, 240, 0, 241, 242, 243, 236, 0, 237, + 238, 239, 264, 265, 0, 0, 0, 0, 0, 229, + 230, 186, 184, 146, 154, 150, 166, 142, 187, 0, + 93, 158, 162, 135, 124, 0, 0, 143, 0, 0, + 0, 0, 136, 0, 0, 0, 0, 0, 128, 126, + 129, 127, 125, 138, 137, 139, 0, 151, 0, 147, + 0, 185, 93, 0, 167, 182, 183, 0, 182, 0, + 0, 232, 0, 0, 0, 234, 0, 155, 0, 0, + 159, 0, 0, 163, 222, 0, 214, 223, 217, 0, + 221, 0, 182, 215, 0, 182, 0, 0, 233, 0, + 0, 0, 235, 280, 270, 0, 0, 272, 0, 266, + 0, 256, 0, 0, 0, 228, 0, 227, 0, 282, + 0, 42, 204, 207, 0, 43, 70, 46, 71, 48, + 49, 20, 53, 54, 17, 55, 58, 18, 21, 182, + 22, 61, 16, 63, 19, 65, 66, 67, 68, 69, + 73, 0, 37, 0, 0, 39, 41, 29, 40, 0, + 38, 28, 205, 203, 81, 82, 87, 0, 80, 0, + 244, 245, 0, 0, 0, 247, 252, 250, 253, 0, + 0, 251, 252, 0, 248, 0, 249, 206, 255, 0, + 206, 254, 0, 257, 258, 0, 206, 259, 260, 0, + 0, 261, 0, 0, 0, 262, 263, 99, 98, 0, + 0, 0, 231, 0, 0, 0, 246, 219, 212, 0, + 220, 216, 0, 218, 208, 0, 209, 213, 0, 36, + 0, 33, 35, 26, 0, 32, 27, 34, 31, 25, + 0, 30, 103, 101, 105, 102, 100, 104, 0, 0, + 10, 17, 35, 7, 2, 9, 15}; + +const int JavaScriptGrammar::goto_default [] = { + 1, 5, 11, 4, 9, 6, 362, 202, 36, 470, + 468, 360, 359, 20, 469, 358, 361, 111, 32, 28, + 150, 34, 24, 149, 29, 35, 62, 33, 19, 38, + 37, 273, 26, 267, 21, 263, 23, 265, 22, 264, + 30, 271, 31, 272, 25, 266, 262, 303, 409, 268, + 269, 197, 236, 201, 203, 207, 208, 199, 198, 210, + 237, 209, 214, 233, 234, 200, 364, 363, 235, 459, + 458, 325, 326, 461, 328, 460, 327, 415, 419, 422, + 418, 417, 437, 438, 206, 191, 205, 187, 190, 204, + 212, 211, 0}; + +const int JavaScriptGrammar::action_index [] = { + 107, 43, -3, -8, -87, 144, 165, -87, 122, -87, + 135, 120, 111, -87, -87, -87, -22, 3, 567, 127, + -87, 13, -36, -63, 192, -87, 220, 106, -87, 407, + 81, 78, 195, 177, -87, -87, -87, 317, 259, 567, + -87, -87, -87, 34, -87, 1041, 52, 567, 567, 567, + 349, 567, -87, -87, 567, 567, -87, -87, 567, -87, + 567, 567, -87, 567, 567, 108, 162, -87, -87, 567, + 567, 567, -87, -87, -87, 146, 567, 204, 567, 567, + 567, 567, 280, 567, 567, 567, 567, 567, 567, 154, + 567, 567, 567, 82, 87, 97, 259, 259, 259, 259, + 259, 300, 290, 270, 567, -65, 567, 17, 958, 567, + 567, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + -87, -87, -87, -87, -87, 113, 567, -87, -87, 49, + -1, -87, 567, -87, -87, -87, 567, -87, -87, -87, + -87, -87, -87, -87, -87, -87, -87, -87, -87, -87, + 567, 38, 567, 567, 64, 58, 567, -87, 958, 567, + 567, -87, 117, -87, 2, -87, -87, 36, -87, 46, + 63, 20, -87, 40, -87, 35, 1373, -87, -87, -87, + -87, -87, 138, -87, -87, 1, -87, -87, -87, -87, + -87, -87, 1373, -87, -87, 136, -87, 153, 109, 1290, + 60, 65, 85, 59, 1456, 567, -87, 48, 567, 57, + -87, 53, 51, -87, -87, 56, -87, -87, -87, -87, + -87, -87, -87, 80, -87, -87, -87, -87, 68, -87, + -87, -87, -87, -87, -57, -16, 567, 197, 115, -87, + -87, 875, -87, 4, -48, -72, -87, 214, -2, -59, + 449, 14, 114, 323, 259, 8, 567, 223, 567, 567, + 567, 567, 238, 567, 567, 567, 567, 567, 259, 259, + 259, 259, 259, 255, 221, 248, 567, -43, 567, 118, + 567, -87, 491, 567, -87, 567, 23, -29, 567, -34, + 1290, -87, 567, 126, 1290, -87, 567, -39, 567, 567, + 6, 32, 567, -87, 11, 99, 7, -87, -87, 567, + -87, 0, 567, -87, -38, 567, -33, 1290, -87, 567, + 103, 1290, -87, -11, 5, -24, 9, 1373, -10, -87, + 1290, -87, 567, 94, 1290, 30, 1290, -87, 37, 33, + -20, -87, -87, 1290, -15, 159, -5, 155, 62, 567, + 1290, -4, -35, 79, 15, -17, 375, 67, 41, 799, + 70, 61, 84, 567, 86, 66, 567, 69, 567, 16, + 22, 567, -87, 1124, 54, -87, -87, -87, -87, 567, + -87, -87, -87, -87, 160, -87, 567, -9, -87, 55, + -87, -87, 567, 102, -18, -87, 73, -87, 77, 90, + 567, -87, 83, 74, -87, 24, -87, 1290, -87, 105, + 1290, -87, 175, -87, -87, 100, 1290, 29, -87, 19, + 21, -87, 44, 10, 31, -87, -87, -87, -87, 567, + 95, 1290, -87, 567, 96, 1290, -87, 50, -87, 151, + -87, -87, 567, -87, -87, 47, -87, -87, 101, 45, + 719, -87, 42, -87, 643, -87, -87, -87, -87, -87, + 93, -87, -87, -87, -87, -87, -87, -87, 1207, 18, + -87, 98, 179, -87, 110, -87, -87, + + -93, -93, -93, -93, -93, -93, -93, -93, 23, -93, + -93, 16, 18, -93, -93, -93, -93, -93, 28, -93, + -93, -93, -93, -93, -93, -93, -93, 29, -93, -31, + -93, -93, -93, -93, -93, -93, -93, -93, -93, 107, + -93, -93, -93, -93, -93, -93, -93, -1, 126, 123, + 118, 98, -93, -93, 138, 218, -93, -93, 97, -93, + 93, 88, -93, 81, 143, -93, -93, -93, -93, 149, + 101, 120, -93, -93, -93, -93, 110, -93, 102, 150, + 142, 141, -93, 127, 66, 64, 67, 68, 74, -93, + 49, 55, 58, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, 77, -93, 70, -93, 46, 52, + 35, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -4, -93, -93, -93, + -93, -93, 45, -93, -93, -93, 42, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + 61, -93, 144, 33, -93, -93, -9, -93, 112, 5, + 117, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, 25, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, 69, -93, -93, -93, -93, -93, -93, 11, + -93, -93, -93, -93, -93, 34, -93, -93, 30, -23, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, 57, -93, -93, -93, + -93, 114, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, 162, -93, 191, 192, + 175, 201, -93, 60, 82, 91, 124, 116, -93, -93, + -93, -93, -93, -93, -93, -93, 153, -93, 172, -93, + 164, -93, -93, 154, -93, 128, -93, -93, 62, -93, + 20, -93, 15, -93, 14, -93, 174, -93, 188, 165, + -93, -93, 163, -93, -93, -93, -93, -93, -93, 173, + -93, -57, 111, -93, -93, 59, -93, -6, -93, 56, + -93, 38, -93, -93, -49, -93, -93, 72, -93, -93, + 54, -93, 44, -93, 47, -93, 48, -93, -93, -93, + -93, -93, -93, 51, -93, -93, -93, -93, -93, 76, + 43, -93, -93, -93, -93, -93, 50, -93, -93, 36, + -93, -93, -93, 40, -93, -22, 137, -93, 131, -93, + -93, 39, -93, 41, -93, -93, -93, -93, -93, 37, + -93, -93, -93, -93, -93, -93, 96, -93, -93, -93, + -93, -93, 27, -93, -93, -93, -93, -93, -80, -93, + 80, -93, -65, -93, -93, -93, -93, -55, -93, -93, + -56, -93, -93, -93, -93, -93, -93, -75, -93, -93, + -44, -93, -93, -93, -37, -93, -93, -93, -93, -5, + -93, -3, -93, -2, -93, 12, -93, -93, -93, -93, + -93, -93, 26, -93, -93, -43, -93, -93, -93, -93, + 32, -93, 31, -93, 19, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, 24, -93, + -93, 21, 22, -93, -93, -93, -93}; + +const int JavaScriptGrammar::action_info [] = { + 296, 261, 305, -51, 298, 276, 300, 17, 316, 296, + 18, 106, 104, 106, 76, 416, 316, 255, 76, 352, + 256, 16, -39, 335, -210, 344, 310, 337, 329, 324, + 8, 146, 308, 298, 192, 401, 346, 324, 339, 322, + 403, 393, 347, 7, 391, 349, 356, 496, -41, 440, + 471, 408, 449, 477, 436, 442, 240, 152, 453, 154, + 471, 399, 185, 188, 436, 176, 170, 462, 196, 194, + 444, 193, 189, 443, -59, 192, 457, -40, 420, 426, + 195, 427, 420, 170, 412, 457, 104, 453, 420, 449, + 436, -62, 350, -64, 343, 352, 261, 412, -211, 436, + 423, 146, 146, 146, 146, 350, 439, 331, 188, 472, + 146, 146, 430, 146, 146, -279, 411, 410, 12, 276, + 440, 146, 63, 253, 252, 146, 0, 63, 172, 251, + 250, 8, 173, 64, 146, 0, 2, 63, 64, 8, + 2, 246, 245, 12, -1, 424, 146, 0, 64, 2, + 67, 2, 12, 481, 354, 451, 455, 473, 69, 465, + 332, 68, 414, 341, 318, 243, 495, 63, 319, 147, + 253, 252, 488, 183, 69, 178, 260, 259, 64, 90, + 489, 91, 248, 146, 248, 0, 314, 471, 243, 69, + 13, 3, 92, 0, 179, 3, 406, 244, 242, 239, + 238, 0, 0, 70, 3, 146, 3, 108, 2, 71, + 178, 0, 466, 464, 249, 247, 249, 247, 0, 70, + 244, 242, 78, 79, 0, 71, 109, 0, 110, 179, + 0, 180, 278, 279, 70, 0, 434, 433, 78, 79, + 71, 278, 279, 0, 283, 284, 0, 0, 0, 80, + 81, 0, 0, 285, 0, 0, 286, 258, 287, 280, + 281, 283, 284, 3, 0, 80, 81, 0, 280, 281, + 285, 283, 284, 286, 0, 287, 0, 0, 283, 284, + 285, 0, 0, 286, 90, 287, 91, 285, 0, 0, + 286, 0, 287, 83, 84, 0, 0, 92, 0, 0, + 0, 85, 86, 83, 84, 87, 0, 88, 0, 0, + 0, 85, 86, 83, 84, 87, 0, 88, 0, 0, + 0, 85, 86, 83, 84, 87, 0, 88, 0, 0, + 0, 85, 86, 0, 0, 87, 0, 88, 0, 0, + 83, 84, 0, 0, 0, 0, 283, 284, 85, 86, + 0, 0, 87, 0, 88, 285, 0, 0, 286, 0, + 287, 40, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 0, 0, 0, 0, 0, 0, 44, 0, + 0, 0, 45, 46, 0, 47, 0, 40, 41, 0, + 0, 0, 50, 0, 0, 0, 53, 43, 0, 0, + 0, 0, 0, 0, 44, 0, 0, 0, 45, 46, + 157, 47, 0, 0, 56, 0, 57, 0, 50, 0, + 158, 0, 53, 0, 159, 0, 0, 52, 59, 42, + 0, 0, 0, 160, 0, 161, 0, 0, 0, 0, + 56, 0, 57, 0, 0, 0, 162, 0, 163, 67, + 0, 0, 157, 52, 59, 42, 164, 0, 0, 165, + 68, 0, 158, 0, 0, 166, 159, 0, 0, 0, + 0, 167, 0, 0, 0, 160, 0, 161, 0, 0, + 312, 0, 0, 0, 168, 0, 0, 0, 162, 0, + 163, 67, 0, 0, 157, 0, 0, 0, 164, 0, + 0, 165, 68, 0, 158, 0, 0, 166, 159, 0, + 0, 0, 0, 167, 0, 0, 0, 160, 0, 161, + 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, + 162, 0, 163, 67, 0, 0, 0, 0, 0, 0, + 164, 0, 0, 165, 68, 0, 0, 0, 0, 166, + 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 39, 40, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 43, + 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, + 45, 46, 0, 47, 0, 0, 0, 48, 0, 49, + 50, 51, 0, 0, 53, 0, 0, 0, 54, 0, + 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 56, 0, 57, 0, 58, 0, 60, 0, + 61, 0, 0, 0, 0, 52, 59, 42, 0, 0, + 0, 0, 0, 0, 39, 40, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, + 0, 0, 44, 0, 0, 0, 45, 46, 0, 47, + 0, 0, 0, 48, 0, 49, 50, 51, 0, 0, + 53, 0, 0, 0, 54, 0, 55, 0, 0, 476, + 0, 0, 0, 0, 0, 0, 0, 0, 56, 0, + 57, 0, 58, 0, 60, 0, 61, 0, 0, 0, + 0, 52, 59, 42, 0, 0, 0, 0, 0, 0, + 39, 40, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 0, 0, 0, 0, 0, 0, 44, 0, + 0, 0, 45, 46, 0, 47, 0, 0, 0, 48, + 0, 49, 50, 51, 0, 0, 53, 0, 0, 0, + 54, 0, 55, 0, 0, 479, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 57, 0, 58, 0, + 60, 0, 61, 0, 0, 0, 0, 52, 59, 42, + 0, 0, 0, 0, 0, 0, -60, 0, 0, 0, + 39, 40, 41, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 0, 0, 0, 0, 0, 0, 44, 0, + 0, 0, 45, 46, 0, 47, 0, 0, 0, 48, + 0, 49, 50, 51, 0, 0, 53, 0, 0, 0, + 54, 0, 55, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 57, 0, 58, 0, + 60, 0, 61, 0, 0, 0, 0, 52, 59, 42, + 0, 0, 0, 0, 0, 0, 39, 40, 41, 0, + 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, + 0, 0, 0, 0, 44, 0, 0, 0, 45, 46, + 0, 47, 0, 0, 0, 48, 0, 49, 50, 51, + 0, 0, 53, 0, 0, 0, 54, 0, 55, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 57, 0, 58, 0, 60, 275, 61, 0, + 0, 0, 0, 52, 59, 42, 0, 0, 0, 0, + 0, 0, 113, 114, 115, 0, 0, 117, 119, 120, + 0, 0, 121, 0, 122, 0, 0, 0, 124, 125, + 126, 0, 0, 0, 0, 0, 0, 127, 128, 129, + 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 134, 0, 0, + 0, 0, 0, 0, 135, 136, 137, 0, 139, 140, + 141, 142, 143, 144, 0, 0, 132, 138, 123, 116, + 118, 133, 0, 0, 0, 113, 114, 115, 0, 0, + 117, 119, 120, 0, 0, 121, 0, 122, 0, 0, + 0, 124, 125, 126, 0, 0, 0, 0, 0, 0, + 395, 128, 129, 130, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 131, 0, 0, 0, 396, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 134, 0, 0, 0, 0, 0, 398, 135, 136, 137, + 0, 139, 140, 141, 142, 143, 144, 0, 0, 132, + 138, 123, 116, 118, 133, 0, 0, 0, 113, 114, + 115, 0, 0, 117, 119, 120, 0, 0, 121, 0, + 122, 0, 0, 0, 124, 125, 126, 0, 0, 0, + 0, 0, 0, 395, 128, 129, 130, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 0, 396, 0, 0, 0, 0, 0, 0, 0, 397, + 0, 0, 0, 134, 0, 0, 0, 0, 0, 398, + 135, 136, 137, 0, 139, 140, 141, 142, 143, 144, + 0, 0, 132, 138, 123, 116, 118, 133, 0, 0, + 0, 215, 0, 0, 0, 0, 217, 0, 39, 40, + 41, 219, 0, 0, 0, 0, 0, 0, 220, 43, + 0, 0, 0, 0, 0, 0, 491, 223, 0, 0, + 224, 492, 0, 47, 0, 0, 0, 48, 0, 49, + 50, 51, 0, 0, 53, 0, 0, 0, 54, 0, + 55, 0, 0, 0, 0, 0, 225, 0, 226, 0, + 0, 0, 56, 227, 57, 228, 58, 229, 60, 230, + 61, 231, 232, 0, 0, 52, 59, 42, 216, 218, + 0, 0, 0, 0, 215, 0, 0, 0, 0, 217, + 0, 39, 40, 41, 219, 0, 0, 0, 0, 0, + 0, 220, 43, 0, 0, 0, 0, 0, 0, 222, + 223, 0, 0, 224, 46, 0, 47, 0, 0, 0, + 48, 0, 49, 50, 51, 0, 0, 53, 0, 0, + 0, 54, 0, 55, 0, 0, 0, 0, 0, 225, + 0, 226, 0, 0, 0, 56, 227, 57, 228, 58, + 229, 60, 230, 61, 231, 232, 0, 0, 52, 59, + 42, 216, 218, 0, 0, 0, 0, 215, 0, 0, + 0, 0, 217, 0, 39, 40, 41, 219, 0, 0, + 0, 0, 0, 0, 220, 221, 0, 0, 0, 0, + 0, 0, 222, 223, 0, 0, 224, 46, 0, 47, + 0, 0, 0, 48, 0, 49, 50, 51, 0, 0, + 53, 0, 0, 0, 54, 0, 55, 0, 0, 0, + 0, 0, 225, 0, 226, 0, 0, 0, 56, 227, + 57, 228, 58, 229, 60, 230, 61, 231, 232, 0, + 0, 52, 59, 42, 216, 218, 0, 0, 0, 0, + 365, 114, 115, 0, 0, 367, 119, 369, 40, 41, + 370, 0, 122, 0, 0, 0, 124, 372, 373, 0, + 0, 0, 0, 0, 0, 374, 375, 129, 130, 224, + 46, 0, 47, 0, 0, 0, 48, 0, 49, 376, + 51, 0, 0, 378, 0, 0, 0, 54, 0, 55, + 0, -206, 0, 0, 0, 379, 0, 226, 0, 0, + 0, 380, 381, 382, 383, 58, 385, 386, 387, 388, + 389, 390, 0, 0, 377, 384, 371, 366, 368, 133, + 0, 0, 0, + + 338, 421, 450, 452, 177, 454, 480, 446, 441, 148, + 431, 428, 182, 425, 445, 333, 156, 254, 456, 14, + 315, 15, 313, 494, 10, 493, 311, 467, 435, 435, + 490, 213, 475, 155, 413, 27, 345, 432, 0, 463, + 474, 306, 0, 306, 342, 478, 175, 432, 151, 254, + 400, 353, 392, 355, 357, 169, 394, 402, 153, 145, + 351, 0, 112, 340, 257, 0, 306, 0, 404, 306, + 0, 405, 0, 65, 0, 213, 0, 93, 213, 65, + 0, 0, 65, 94, 65, 65, 95, 429, 65, 288, + 65, 65, 65, 97, 65, 96, 98, 99, 65, 171, + 65, 65, 186, 100, 107, 65, 65, 336, 66, 151, + 309, 289, 65, 105, 448, 65, 407, 65, 306, 447, + 290, 65, 65, 487, 484, 65, 65, 73, 112, 181, + 151, 65, 82, 186, 65, 306, 404, 184, 270, 405, + 65, 0, 77, 274, 65, 292, 74, 65, 65, 483, + 65, 65, 482, 291, 0, 65, 89, 448, 348, 334, + 241, 65, 65, 447, 485, 65, 65, 65, 65, 0, + 75, 103, 102, 65, 65, 72, 307, 65, 302, 0, + 101, 0, 274, 274, 174, 0, 65, 302, 302, 302, + 297, 274, 274, 274, 274, 277, 65, 302, 65, 65, + 304, 274, 274, 274, 274, 0, 294, 299, 0, 323, + 301, 321, 65, 317, 0, 65, 65, 274, 0, 330, + 274, 274, 282, 293, 0, 65, 0, 0, 0, 320, + 274, 0, 295, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 0, 486, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; + +const int JavaScriptGrammar::action_check [] = { + 48, 36, 61, 7, 76, 1, 8, 29, 2, 48, + 7, 76, 48, 76, 1, 33, 2, 74, 1, 36, + 36, 29, 7, 61, 29, 36, 60, 60, 17, 29, + 33, 8, 61, 76, 29, 55, 60, 29, 31, 7, + 55, 8, 33, 0, 7, 55, 16, 29, 7, 20, + 8, 60, 36, 8, 33, 36, 55, 8, 36, 60, + 8, 7, 60, 29, 33, 7, 2, 17, 33, 29, + 60, 8, 36, 29, 7, 29, 29, 7, 5, 55, + 60, 7, 5, 2, 36, 29, 48, 36, 5, 36, + 33, 7, 7, 7, 29, 36, 36, 36, 29, 33, + 10, 8, 8, 8, 8, 7, 6, 8, 29, 8, + 8, 8, 7, 8, 8, 36, 61, 62, 8, 1, + 20, 8, 40, 61, 62, 8, -1, 40, 50, 61, + 62, 33, 54, 51, 8, -1, 29, 40, 51, 33, + 29, 61, 62, 8, 0, 55, 8, -1, 51, 29, + 42, 29, 8, 60, 60, 60, 60, 56, 12, 8, + 61, 53, 60, 60, 50, 29, 56, 40, 54, 56, + 61, 62, 7, 56, 12, 15, 61, 62, 51, 25, + 15, 27, 29, 8, 29, -1, 60, 8, 29, 12, + 55, 84, 38, -1, 34, 84, 36, 61, 62, 61, + 62, -1, -1, 57, 84, 8, 84, 15, 29, 63, + 15, -1, 61, 62, 61, 62, 61, 62, -1, 57, + 61, 62, 18, 19, -1, 63, 34, -1, 36, 34, + -1, 36, 18, 19, 57, -1, 61, 62, 18, 19, + 63, 18, 19, -1, 23, 24, -1, -1, -1, 45, + 46, -1, -1, 32, -1, -1, 35, 60, 37, 45, + 46, 23, 24, 84, -1, 45, 46, -1, 45, 46, + 32, 23, 24, 35, -1, 37, -1, -1, 23, 24, + 32, -1, -1, 35, 25, 37, 27, 32, -1, -1, + 35, -1, 37, 23, 24, -1, -1, 38, -1, -1, + -1, 31, 32, 23, 24, 35, -1, 37, -1, -1, + -1, 31, 32, 23, 24, 35, -1, 37, -1, -1, + -1, 31, 32, 23, 24, 35, -1, 37, -1, -1, + -1, 31, 32, -1, -1, 35, -1, 37, -1, -1, + 23, 24, -1, -1, -1, -1, 23, 24, 31, 32, + -1, -1, 35, -1, 37, 32, -1, -1, 35, -1, + 37, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, + -1, -1, 33, 34, -1, 36, -1, 12, 13, -1, + -1, -1, 43, -1, -1, -1, 47, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + 3, 36, -1, -1, 65, -1, 67, -1, 43, -1, + 13, -1, 47, -1, 17, -1, -1, 78, 79, 80, + -1, -1, -1, 26, -1, 28, -1, -1, -1, -1, + 65, -1, 67, -1, -1, -1, 39, -1, 41, 42, + -1, -1, 3, 78, 79, 80, 49, -1, -1, 52, + 53, -1, 13, -1, -1, 58, 17, -1, -1, -1, + -1, 64, -1, -1, -1, 26, -1, 28, -1, -1, + 31, -1, -1, -1, 77, -1, -1, -1, 39, -1, + 41, 42, -1, -1, 3, -1, -1, -1, 49, -1, + -1, 52, 53, -1, 13, -1, -1, 58, 17, -1, + -1, -1, -1, 64, -1, -1, -1, 26, -1, 28, + -1, -1, -1, -1, -1, -1, 77, -1, -1, -1, + 39, -1, 41, 42, -1, -1, -1, -1, -1, -1, + 49, -1, -1, 52, 53, -1, -1, -1, -1, 58, + -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 77, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 65, -1, 67, -1, 69, -1, 71, -1, + 73, -1, -1, -1, -1, 78, 79, 80, -1, -1, + -1, -1, -1, -1, 11, 12, 13, -1, -1, -1, + -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, + -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, -1, 56, + -1, -1, -1, -1, -1, -1, -1, -1, 65, -1, + 67, -1, 69, -1, 71, -1, 73, -1, -1, -1, + -1, 78, 79, 80, -1, -1, -1, -1, -1, -1, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, + -1, -1, -1, -1, 65, -1, 67, -1, 69, -1, + 71, -1, 73, -1, -1, -1, -1, 78, 79, 80, + -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 65, -1, 67, -1, 69, -1, + 71, -1, 73, -1, -1, -1, -1, 78, 79, 80, + -1, -1, -1, -1, -1, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, + -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 65, -1, 67, -1, 69, -1, 71, 72, 73, -1, + -1, -1, -1, 78, 79, 80, -1, -1, -1, -1, + -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, + -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, + 22, -1, -1, -1, -1, -1, -1, 29, 30, 31, + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, + -1, -1, -1, -1, 66, 67, 68, -1, 70, 71, + 72, 73, 74, 75, -1, -1, 78, 79, 80, 81, + 82, 83, -1, -1, -1, 4, 5, 6, -1, -1, + 9, 10, 11, -1, -1, 14, -1, 16, -1, -1, + -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, + 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 59, -1, -1, -1, -1, -1, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, 75, -1, -1, 78, + 79, 80, 81, 82, 83, -1, -1, -1, 4, 5, + 6, -1, -1, 9, 10, 11, -1, -1, 14, -1, + 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, + -1, -1, -1, 29, 30, 31, 32, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, + -1, 47, -1, -1, -1, -1, -1, -1, -1, 55, + -1, -1, -1, 59, -1, -1, -1, -1, -1, 65, + 66, 67, 68, -1, 70, 71, 72, 73, 74, 75, + -1, -1, 78, 79, 80, 81, 82, 83, -1, -1, + -1, 4, -1, -1, -1, -1, 9, -1, 11, 12, + 13, 14, -1, -1, -1, -1, -1, -1, 21, 22, + -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, -1, -1, -1, -1, 59, -1, 61, -1, + -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, -1, -1, 78, 79, 80, 81, 82, + -1, -1, -1, -1, 4, -1, -1, -1, -1, 9, + -1, 11, 12, 13, 14, -1, -1, -1, -1, -1, + -1, 21, 22, -1, -1, -1, -1, -1, -1, 29, + 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, + 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, + -1, 51, -1, 53, -1, -1, -1, -1, -1, 59, + -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, -1, -1, 78, 79, + 80, 81, 82, -1, -1, -1, -1, 4, -1, -1, + -1, -1, 9, -1, 11, 12, 13, 14, -1, -1, + -1, -1, -1, -1, 21, 22, -1, -1, -1, -1, + -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, + -1, -1, 59, -1, 61, -1, -1, -1, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, -1, + -1, 78, 79, 80, 81, 82, -1, -1, -1, -1, + 4, 5, 6, -1, -1, 9, 10, 11, 12, 13, + 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, + -1, -1, -1, -1, -1, 29, 30, 31, 32, 33, + 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, + 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, + -1, 55, -1, -1, -1, 59, -1, 61, -1, -1, + -1, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, -1, -1, 78, 79, 80, 81, 82, 83, + -1, -1, -1, + + 6, 81, 7, 6, 13, 7, 7, 51, 83, 13, + 66, 66, 7, 78, 51, 72, 47, 6, 6, 3, + 6, 3, 7, 1, 1, 4, 6, 70, 51, 51, + 6, 6, 13, 4, 7, 7, 85, 7, -1, 13, + 9, 7, -1, 7, 6, 13, 13, 7, 13, 6, + 13, 7, 13, 6, 6, 13, 15, 6, 13, 7, + 6, -1, 16, 7, 7, -1, 7, -1, 18, 7, + -1, 21, -1, 24, -1, 6, -1, 28, 6, 24, + -1, -1, 24, 28, 24, 24, 28, 7, 24, 29, + 24, 24, 24, 29, 24, 29, 29, 29, 24, 38, + 24, 24, 26, 29, 34, 24, 24, 48, 27, 13, + 48, 29, 24, 36, 26, 24, 20, 24, 7, 26, + 29, 24, 24, 26, 26, 24, 24, 26, 16, 17, + 13, 24, 30, 26, 24, 7, 18, 20, 24, 21, + 24, -1, 32, 29, 24, 29, 26, 24, 24, 26, + 24, 24, 26, 29, -1, 24, 29, 26, 86, 48, + 91, 24, 24, 26, 26, 24, 24, 24, 24, -1, + 27, 30, 30, 24, 24, 26, 48, 24, 24, -1, + 30, -1, 29, 29, 40, -1, 24, 24, 24, 24, + 37, 29, 29, 29, 29, 33, 24, 24, 24, 24, + 46, 29, 29, 29, 29, -1, 31, 35, -1, 46, + 46, 46, 24, 39, -1, 24, 24, 29, -1, 46, + 29, 29, 31, 31, -1, 24, -1, -1, -1, 41, + 29, -1, 31, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 24, -1, 26, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1}; + diff --git a/src/declarative/qml/parser/javascriptgrammar_p.h b/src/declarative/qml/parser/javascriptgrammar_p.h new file mode 100644 index 0000000..3cc3307 --- /dev/null +++ b/src/declarative/qml/parser/javascriptgrammar_p.h @@ -0,0 +1,144 @@ +// This file was generated by qlalr - DO NOT EDIT! +#ifndef JAVASCRIPTGRAMMAR_P_H +#define JAVASCRIPTGRAMMAR_P_H + +class JavaScriptGrammar +{ +public: + enum { + EOF_SYMBOL = 0, + REDUCE_HERE = 86, + SHIFT_THERE = 85, + T_AND = 1, + T_AND_AND = 2, + T_AND_EQ = 3, + T_AUTOMATIC_SEMICOLON = 62, + T_BREAK = 4, + T_CASE = 5, + T_CATCH = 6, + T_COLON = 7, + T_COMMA = 8, + T_CONST = 81, + T_CONTINUE = 9, + T_DEBUGGER = 82, + T_DEFAULT = 10, + T_DELETE = 11, + T_DIVIDE_ = 12, + T_DIVIDE_EQ = 13, + T_DO = 14, + T_DOT = 15, + T_ELSE = 16, + T_EQ = 17, + T_EQ_EQ = 18, + T_EQ_EQ_EQ = 19, + T_FALSE = 80, + T_FINALLY = 20, + T_FOR = 21, + T_FUNCTION = 22, + T_GE = 23, + T_GT = 24, + T_GT_GT = 25, + T_GT_GT_EQ = 26, + T_GT_GT_GT = 27, + T_GT_GT_GT_EQ = 28, + T_IDENTIFIER = 29, + T_IF = 30, + T_IN = 31, + T_INSTANCEOF = 32, + T_LBRACE = 33, + T_LBRACKET = 34, + T_LE = 35, + T_LPAREN = 36, + T_LT = 37, + T_LT_LT = 38, + T_LT_LT_EQ = 39, + T_MINUS = 40, + T_MINUS_EQ = 41, + T_MINUS_MINUS = 42, + T_NEW = 43, + T_NOT = 44, + T_NOT_EQ = 45, + T_NOT_EQ_EQ = 46, + T_NULL = 78, + T_NUMERIC_LITERAL = 47, + T_OR = 48, + T_OR_EQ = 49, + T_OR_OR = 50, + T_PLUS = 51, + T_PLUS_EQ = 52, + T_PLUS_PLUS = 53, + T_PUBLIC = 84, + T_QUESTION = 54, + T_RBRACE = 55, + T_RBRACKET = 56, + T_REMAINDER = 57, + T_REMAINDER_EQ = 58, + T_RESERVED_WORD = 83, + T_RETURN = 59, + T_RPAREN = 60, + T_SEMICOLON = 61, + T_STAR = 63, + T_STAR_EQ = 64, + T_STRING_LITERAL = 65, + T_SWITCH = 66, + T_THIS = 67, + T_THROW = 68, + T_TILDE = 69, + T_TRUE = 79, + T_TRY = 70, + T_TYPEOF = 71, + T_VAR = 72, + T_VOID = 73, + T_WHILE = 74, + T_WITH = 75, + T_XOR = 76, + T_XOR_EQ = 77, + + ACCEPT_STATE = 7, + RULE_COUNT = 283, + STATE_COUNT = 497, + TERMINAL_COUNT = 87, + NON_TERMINAL_COUNT = 93, + + GOTO_INDEX_OFFSET = 497, + GOTO_INFO_OFFSET = 1543, + GOTO_CHECK_OFFSET = 1543 + }; + + static const char *const spell []; + static const int lhs []; + static const int rhs []; + static const int goto_default []; + static const int action_default []; + static const int action_index []; + static const int action_info []; + static const int action_check []; + + static inline int nt_action (int state, int nt) + { + const int *const goto_index = &action_index [GOTO_INDEX_OFFSET]; + const int *const goto_check = &action_check [GOTO_CHECK_OFFSET]; + + const int yyn = goto_index [state] + nt; + + if (yyn < 0 || goto_check [yyn] != nt) + return goto_default [nt]; + + const int *const goto_info = &action_info [GOTO_INFO_OFFSET]; + return goto_info [yyn]; + } + + static inline int t_action (int state, int token) + { + const int yyn = action_index [state] + token; + + if (yyn < 0 || action_check [yyn] != token) + return - action_default [state]; + + return action_info [yyn]; + } +}; + + +#endif // JAVASCRIPTGRAMMAR_P_H + diff --git a/src/declarative/qml/parser/javascriptlexer.cpp b/src/declarative/qml/parser/javascriptlexer.cpp new file mode 100644 index 0000000..58d8c53 --- /dev/null +++ b/src/declarative/qml/parser/javascriptlexer.cpp @@ -0,0 +1,1124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "javascriptengine_p.h" + + + + + + + +#include "javascriptlexer_p.h" +#include "javascriptgrammar_p.h" + +#include <ctype.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +QT_BEGIN_NAMESPACE + +extern double qstrtod(const char *s00, char const **se, bool *ok); + +#define shiftWindowsLineBreak() \ + do { \ + if (((current == '\r') && (next1 == '\n')) \ + || ((current == '\n') && (next1 == '\r'))) { \ + shift(1); \ + } \ + } \ + while (0) + +namespace JavaScript { +extern qjsreal integerFromString(const char *buf, int size, int radix); +} + +JavaScript::Lexer::Lexer(JavaScriptEnginePrivate *eng) + : driver(eng), + yylineno(0), + done(false), + size8(128), size16(128), + pos8(0), pos16(0), + terminator(false), + restrKeyword(false), + delimited(false), + stackToken(-1), + state(Start), + pos(0), + code(0), length(0), + yycolumn(0), + startpos(0), + startlineno(0), startcolumn(0), + bol(true), + current(0), next1(0), next2(0), next3(0), + err(NoError), + wantRx(false), + check_reserved(true), + parenthesesState(IgnoreParentheses), + parenthesesCount(0), + prohibitAutomaticSemicolon(false) +{ + // allocate space for read buffers + buffer8 = new char[size8]; + buffer16 = new QChar[size16]; + pattern = 0; + flags = 0; + +} + +JavaScript::Lexer::~Lexer() +{ + delete [] buffer8; + delete [] buffer16; +} + +void JavaScript::Lexer::setCode(const QString &c, int lineno) +{ + errmsg = QString(); + yylineno = lineno; + yycolumn = 1; + restrKeyword = false; + delimited = false; + stackToken = -1; + pos = 0; + code = c.unicode(); + length = c.length(); + bol = true; + + // read first characters + current = (length > 0) ? code[0].unicode() : 0; + next1 = (length > 1) ? code[1].unicode() : 0; + next2 = (length > 2) ? code[2].unicode() : 0; + next3 = (length > 3) ? code[3].unicode() : 0; +} + +void JavaScript::Lexer::shift(uint p) +{ + while (p--) { + ++pos; + ++yycolumn; + current = next1; + next1 = next2; + next2 = next3; + next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0; + } +} + +void JavaScript::Lexer::setDone(State s) +{ + state = s; + done = true; +} + +int JavaScript::Lexer::findReservedWord(const QChar *c, int size) const +{ + switch (size) { + case 2: { + if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')) + return JavaScriptGrammar::T_DO; + else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f')) + return JavaScriptGrammar::T_IF; + else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')) + return JavaScriptGrammar::T_IN; + } break; + + case 3: { + if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r')) + return JavaScriptGrammar::T_FOR; + else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w')) + return JavaScriptGrammar::T_NEW; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y')) + return JavaScriptGrammar::T_TRY; + else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r')) + return JavaScriptGrammar::T_VAR; + else if (check_reserved) { + if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 4: { + if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a') + && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e')) + return JavaScriptGrammar::T_CASE; + else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l') + && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e')) + return JavaScriptGrammar::T_ELSE; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s')) + return JavaScriptGrammar::T_THIS; + else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d')) + return JavaScriptGrammar::T_VOID; + else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h')) + return JavaScriptGrammar::T_WITH; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') + && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e')) + return JavaScriptGrammar::T_TRUE; + else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u') + && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l')) + return JavaScriptGrammar::T_NULL; + else if (check_reserved) { + if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n') + && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 5: { + if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r') + && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('k')) + return JavaScriptGrammar::T_BREAK; + else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c') + && c[4] == QLatin1Char('h')) + return JavaScriptGrammar::T_CATCH; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o') + && c[4] == QLatin1Char('w')) + return JavaScriptGrammar::T_THROW; + else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l') + && c[4] == QLatin1Char('e')) + return JavaScriptGrammar::T_WHILE; + else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s') + && c[4] == QLatin1Char('t')) + return JavaScriptGrammar::T_CONST; + else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a') + && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s') + && c[4] == QLatin1Char('e')) + return JavaScriptGrammar::T_FALSE; + else if (check_reserved) { + if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r') + && c[4] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u') + && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e') + && c[4] == QLatin1Char('r')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('l')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l') + && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s') + && c[4] == QLatin1Char('s')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l') + && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 6: { + if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e') + && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e') + && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e')) + return JavaScriptGrammar::T_DELETE; + else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u') + && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n')) + return JavaScriptGrammar::T_RETURN; + else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w') + && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h')) + return JavaScriptGrammar::T_SWITCH; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y') + && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e') + && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f')) + return JavaScriptGrammar::T_TYPEOF; + else if (check_reserved) { + if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x') + && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o') + && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t') + && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b') + && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m') + && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o') + && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u') + && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l') + && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c')) + return JavaScriptGrammar::T_PUBLIC; + else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i') + && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h') + && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o') + && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 7: { + if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e') + && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l') + && c[6] == QLatin1Char('t')) + return JavaScriptGrammar::T_DEFAULT; + else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l') + && c[6] == QLatin1Char('y')) + return JavaScriptGrammar::T_FINALLY; + else if (check_reserved) { + if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l') + && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a') + && c[6] == QLatin1Char('n')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e') + && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d') + && c[6] == QLatin1Char('s')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a') + && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k') + && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g') + && c[6] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r') + && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v') + && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t') + && c[6] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 8: { + if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n') + && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e')) + return JavaScriptGrammar::T_CONTINUE; + else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c') + && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i') + && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')) + return JavaScriptGrammar::T_FUNCTION; + else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e') + && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u') + && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g') + && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r')) + return JavaScriptGrammar::T_DEBUGGER; + else if (check_reserved) { + if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b') + && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a') + && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o') + && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a') + && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i') + && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 9: { + if (check_reserved) { + if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') + && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e') + && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f') + && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c') + && c[8] == QLatin1Char('e')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') + && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n') + && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i') + && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n') + && c[8] == QLatin1Char('t')) + return JavaScriptGrammar::T_RESERVED_WORD; + else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r') + && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c') + && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e') + && c[8] == QLatin1Char('d')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 10: { + if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') + && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t') + && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n') + && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e') + && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f')) + return JavaScriptGrammar::T_INSTANCEOF; + else if (check_reserved) { + if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m') + && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l') + && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m') + && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n') + && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + case 12: { + if (check_reserved) { + if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y') + && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c') + && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r') + && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n') + && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z') + && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d')) + return JavaScriptGrammar::T_RESERVED_WORD; + } + } break; + + } // switch + + return -1; +} + +int JavaScript::Lexer::lex() +{ + int token = 0; + state = Start; + ushort stringType = 0; // either single or double quotes + pos8 = pos16 = 0; + done = false; + terminator = false; + + // did we push a token on the stack previously ? + // (after an automatic semicolon insertion) + if (stackToken >= 0) { + setDone(Other); + token = stackToken; + stackToken = -1; + } + + while (!done) { + switch (state) { + case Start: + if (isWhiteSpace()) { + // do nothing + } else if (current == '/' && next1 == '/') { + recordStartPos(); + shift(1); + state = InSingleLineComment; + } else if (current == '/' && next1 == '*') { + recordStartPos(); + shift(1); + state = InMultiLineComment; + } else if (current == 0) { + syncProhibitAutomaticSemicolon(); + if (!terminator && !delimited && !prohibitAutomaticSemicolon) { + // automatic semicolon insertion if program incomplete + token = JavaScriptGrammar::T_SEMICOLON; + stackToken = 0; + setDone(Other); + } else { + setDone(Eof); + } + } else if (isLineTerminator()) { + shiftWindowsLineBreak(); + yylineno++; + yycolumn = 0; + bol = true; + terminator = true; + syncProhibitAutomaticSemicolon(); + if (restrKeyword) { + token = JavaScriptGrammar::T_SEMICOLON; + setDone(Other); + } + } else if (current == '"' || current == '\'') { + recordStartPos(); + state = InString; + stringType = current; + } else if (isIdentLetter(current)) { + recordStartPos(); + record16(current); + state = InIdentifier; + } else if (current == '0') { + recordStartPos(); + record8(current); + state = InNum0; + } else if (isDecimalDigit(current)) { + recordStartPos(); + record8(current); + state = InNum; + } else if (current == '.' && isDecimalDigit(next1)) { + recordStartPos(); + record8(current); + state = InDecimal; + } else { + recordStartPos(); + token = matchPunctuator(current, next1, next2, next3); + if (token != -1) { + if (terminator && !delimited && !prohibitAutomaticSemicolon + && (token == JavaScriptGrammar::T_PLUS_PLUS + || token == JavaScriptGrammar::T_MINUS_MINUS)) { + // automatic semicolon insertion + stackToken = token; + token = JavaScriptGrammar::T_SEMICOLON; + } + setDone(Other); + } + else { + setDone(Bad); + err = IllegalCharacter; + errmsg = QLatin1String("Illegal character"); + } + } + break; + case InString: + if (current == stringType) { + shift(1); + setDone(String); + } else if (current == 0 || isLineTerminator()) { + setDone(Bad); + err = UnclosedStringLiteral; + errmsg = QLatin1String("Unclosed string at end of line"); + } else if (current == '\\') { + state = InEscapeSequence; + } else { + record16(current); + } + break; + // Escape Sequences inside of strings + case InEscapeSequence: + if (isOctalDigit(current)) { + if (current >= '0' && current <= '3' && + isOctalDigit(next1) && isOctalDigit(next2)) { + record16(convertOctal(current, next1, next2)); + shift(2); + state = InString; + } else if (isOctalDigit(current) && + isOctalDigit(next1)) { + record16(convertOctal('0', current, next1)); + shift(1); + state = InString; + } else if (isOctalDigit(current)) { + record16(convertOctal('0', '0', current)); + state = InString; + } else { + setDone(Bad); + err = IllegalEscapeSequence; + errmsg = QLatin1String("Illegal escape squence"); + } + } else if (current == 'x') + state = InHexEscape; + else if (current == 'u') + state = InUnicodeEscape; + else { + if (isLineTerminator()) { + shiftWindowsLineBreak(); + yylineno++; + yycolumn = 0; + bol = true; + } else { + record16(singleEscape(current)); + } + state = InString; + } + break; + case InHexEscape: + if (isHexDigit(current) && isHexDigit(next1)) { + state = InString; + record16(QLatin1Char(convertHex(current, next1))); + shift(1); + } else if (current == stringType) { + record16(QLatin1Char('x')); + shift(1); + setDone(String); + } else { + record16(QLatin1Char('x')); + record16(current); + state = InString; + } + break; + case InUnicodeEscape: + if (isHexDigit(current) && isHexDigit(next1) && + isHexDigit(next2) && isHexDigit(next3)) { + record16(convertUnicode(current, next1, next2, next3)); + shift(3); + state = InString; + } else if (current == stringType) { + record16(QLatin1Char('u')); + shift(1); + setDone(String); + } else { + setDone(Bad); + err = IllegalUnicodeEscapeSequence; + errmsg = QLatin1String("Illegal unicode escape sequence"); + } + break; + case InSingleLineComment: + if (isLineTerminator()) { + shiftWindowsLineBreak(); + yylineno++; + yycolumn = 0; + terminator = true; + bol = true; + if (restrKeyword) { + token = JavaScriptGrammar::T_SEMICOLON; + setDone(Other); + } else + state = Start; + } else if (current == 0) { + setDone(Eof); + } + break; + case InMultiLineComment: + if (current == 0) { + setDone(Bad); + err = UnclosedComment; + errmsg = QLatin1String("Unclosed comment at end of file"); + } else if (isLineTerminator()) { + shiftWindowsLineBreak(); + yylineno++; + } else if (current == '*' && next1 == '/') { + state = Start; + shift(1); + } + break; + case InIdentifier: + if (isIdentLetter(current) || isDecimalDigit(current)) { + record16(current); + break; + } + setDone(Identifier); + break; + case InNum0: + if (current == 'x' || current == 'X') { + record8(current); + state = InHex; + } else if (current == '.') { + record8(current); + state = InDecimal; + } else if (current == 'e' || current == 'E') { + record8(current); + state = InExponentIndicator; + } else if (isOctalDigit(current)) { + record8(current); + state = InOctal; + } else if (isDecimalDigit(current)) { + record8(current); + state = InDecimal; + } else { + setDone(Number); + } + break; + case InHex: + if (isHexDigit(current)) + record8(current); + else + setDone(Hex); + break; + case InOctal: + if (isOctalDigit(current)) { + record8(current); + } else if (isDecimalDigit(current)) { + record8(current); + state = InDecimal; + } else { + setDone(Octal); + } + break; + case InNum: + if (isDecimalDigit(current)) { + record8(current); + } else if (current == '.') { + record8(current); + state = InDecimal; + } else if (current == 'e' || current == 'E') { + record8(current); + state = InExponentIndicator; + } else { + setDone(Number); + } + break; + case InDecimal: + if (isDecimalDigit(current)) { + record8(current); + } else if (current == 'e' || current == 'E') { + record8(current); + state = InExponentIndicator; + } else { + setDone(Number); + } + break; + case InExponentIndicator: + if (current == '+' || current == '-') { + record8(current); + } else if (isDecimalDigit(current)) { + record8(current); + state = InExponent; + } else { + setDone(Bad); + err = IllegalExponentIndicator; + errmsg = QLatin1String("Illegal syntax for exponential number"); + } + break; + case InExponent: + if (isDecimalDigit(current)) { + record8(current); + } else { + setDone(Number); + } + break; + default: + Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement"); + } + + // move on to the next character + if (!done) + shift(1); + if (state != Start && state != InSingleLineComment) + bol = false; + } + + // no identifiers allowed directly after numeric literal, e.g. "3in" is bad + if ((state == Number || state == Octal || state == Hex) + && isIdentLetter(current)) { + state = Bad; + err = IllegalIdentifier; + errmsg = QLatin1String("Identifier cannot start with numeric literal"); + } + + // terminate string + buffer8[pos8] = '\0'; + + double dval = 0; + if (state == Number) { + dval = qstrtod(buffer8, 0, 0); + } else if (state == Hex) { // scan hex numbers + dval = JavaScript::integerFromString(buffer8, pos8, 16); + state = Number; + } else if (state == Octal) { // scan octal number + dval = JavaScript::integerFromString(buffer8, pos8, 8); + state = Number; + } + + restrKeyword = false; + delimited = false; + + switch (parenthesesState) { + case IgnoreParentheses: + break; + case CountParentheses: + if (token == JavaScriptGrammar::T_RPAREN) { + --parenthesesCount; + if (parenthesesCount == 0) + parenthesesState = BalancedParentheses; + } else if (token == JavaScriptGrammar::T_LPAREN) { + ++parenthesesCount; + } + break; + case BalancedParentheses: + parenthesesState = IgnoreParentheses; + break; + } + + switch (state) { + case Eof: + return 0; + case Other: + if(token == JavaScriptGrammar::T_RBRACE || token == JavaScriptGrammar::T_SEMICOLON) + delimited = true; + return token; + case Identifier: + if ((token = findReservedWord(buffer16, pos16)) < 0) { + /* TODO: close leak on parse error. same holds true for String */ + if (driver) + qsyylval.ustr = driver->intern(buffer16, pos16); + else + qsyylval.ustr = 0; + return JavaScriptGrammar::T_IDENTIFIER; + } + if (token == JavaScriptGrammar::T_CONTINUE || token == JavaScriptGrammar::T_BREAK + || token == JavaScriptGrammar::T_RETURN || token == JavaScriptGrammar::T_THROW) { + restrKeyword = true; + } else if (token == JavaScriptGrammar::T_IF || token == JavaScriptGrammar::T_FOR + || token == JavaScriptGrammar::T_WHILE || token == JavaScriptGrammar::T_WITH) { + parenthesesState = CountParentheses; + parenthesesCount = 0; + } else if (token == JavaScriptGrammar::T_DO) { + parenthesesState = BalancedParentheses; + } + return token; + case String: + if (driver) + qsyylval.ustr = driver->intern(buffer16, pos16); + else + qsyylval.ustr = 0; + return JavaScriptGrammar::T_STRING_LITERAL; + case Number: + qsyylval.dval = dval; + return JavaScriptGrammar::T_NUMERIC_LITERAL; + case Bad: + return -1; + default: + Q_ASSERT(!"unhandled numeration value in switch"); + return -1; + } +} + +bool JavaScript::Lexer::isWhiteSpace() const +{ + return (current == ' ' || current == '\t' || + current == 0x0b || current == 0x0c); +} + +bool JavaScript::Lexer::isLineTerminator() const +{ + return (current == '\n' || current == '\r'); +} + +bool JavaScript::Lexer::isIdentLetter(ushort c) +{ + /* TODO: allow other legitimate unicode chars */ + return ((c >= 'a' && c <= 'z') + || (c >= 'A' && c <= 'Z') + || c == '$' + || c == '_'); +} + +bool JavaScript::Lexer::isDecimalDigit(ushort c) +{ + return (c >= '0' && c <= '9'); +} + +bool JavaScript::Lexer::isHexDigit(ushort c) const +{ + return ((c >= '0' && c <= '9') + || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F')); +} + +bool JavaScript::Lexer::isOctalDigit(ushort c) const +{ + return (c >= '0' && c <= '7'); +} + +int JavaScript::Lexer::matchPunctuator(ushort c1, ushort c2, + ushort c3, ushort c4) +{ + if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') { + shift(4); + return JavaScriptGrammar::T_GT_GT_GT_EQ; + } else if (c1 == '=' && c2 == '=' && c3 == '=') { + shift(3); + return JavaScriptGrammar::T_EQ_EQ_EQ; + } else if (c1 == '!' && c2 == '=' && c3 == '=') { + shift(3); + return JavaScriptGrammar::T_NOT_EQ_EQ; + } else if (c1 == '>' && c2 == '>' && c3 == '>') { + shift(3); + return JavaScriptGrammar::T_GT_GT_GT; + } else if (c1 == '<' && c2 == '<' && c3 == '=') { + shift(3); + return JavaScriptGrammar::T_LT_LT_EQ; + } else if (c1 == '>' && c2 == '>' && c3 == '=') { + shift(3); + return JavaScriptGrammar::T_GT_GT_EQ; + } else if (c1 == '<' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_LE; + } else if (c1 == '>' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_GE; + } else if (c1 == '!' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_NOT_EQ; + } else if (c1 == '+' && c2 == '+') { + shift(2); + return JavaScriptGrammar::T_PLUS_PLUS; + } else if (c1 == '-' && c2 == '-') { + shift(2); + return JavaScriptGrammar::T_MINUS_MINUS; + } else if (c1 == '=' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_EQ_EQ; + } else if (c1 == '+' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_PLUS_EQ; + } else if (c1 == '-' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_MINUS_EQ; + } else if (c1 == '*' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_STAR_EQ; + } else if (c1 == '/' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_DIVIDE_EQ; + } else if (c1 == '&' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_AND_EQ; + } else if (c1 == '^' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_XOR_EQ; + } else if (c1 == '%' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_REMAINDER_EQ; + } else if (c1 == '|' && c2 == '=') { + shift(2); + return JavaScriptGrammar::T_OR_EQ; + } else if (c1 == '<' && c2 == '<') { + shift(2); + return JavaScriptGrammar::T_LT_LT; + } else if (c1 == '>' && c2 == '>') { + shift(2); + return JavaScriptGrammar::T_GT_GT; + } else if (c1 == '&' && c2 == '&') { + shift(2); + return JavaScriptGrammar::T_AND_AND; + } else if (c1 == '|' && c2 == '|') { + shift(2); + return JavaScriptGrammar::T_OR_OR; + } + + switch(c1) { + case '=': shift(1); return JavaScriptGrammar::T_EQ; + case '>': shift(1); return JavaScriptGrammar::T_GT; + case '<': shift(1); return JavaScriptGrammar::T_LT; + case ',': shift(1); return JavaScriptGrammar::T_COMMA; + case '!': shift(1); return JavaScriptGrammar::T_NOT; + case '~': shift(1); return JavaScriptGrammar::T_TILDE; + case '?': shift(1); return JavaScriptGrammar::T_QUESTION; + case ':': shift(1); return JavaScriptGrammar::T_COLON; + case '.': shift(1); return JavaScriptGrammar::T_DOT; + case '+': shift(1); return JavaScriptGrammar::T_PLUS; + case '-': shift(1); return JavaScriptGrammar::T_MINUS; + case '*': shift(1); return JavaScriptGrammar::T_STAR; + case '/': shift(1); return JavaScriptGrammar::T_DIVIDE_; + case '&': shift(1); return JavaScriptGrammar::T_AND; + case '|': shift(1); return JavaScriptGrammar::T_OR; + case '^': shift(1); return JavaScriptGrammar::T_XOR; + case '%': shift(1); return JavaScriptGrammar::T_REMAINDER; + case '(': shift(1); return JavaScriptGrammar::T_LPAREN; + case ')': shift(1); return JavaScriptGrammar::T_RPAREN; + case '{': shift(1); return JavaScriptGrammar::T_LBRACE; + case '}': shift(1); return JavaScriptGrammar::T_RBRACE; + case '[': shift(1); return JavaScriptGrammar::T_LBRACKET; + case ']': shift(1); return JavaScriptGrammar::T_RBRACKET; + case ';': shift(1); return JavaScriptGrammar::T_SEMICOLON; + + default: return -1; + } +} + +ushort JavaScript::Lexer::singleEscape(ushort c) const +{ + switch(c) { + case 'b': + return 0x08; + case 't': + return 0x09; + case 'n': + return 0x0A; + case 'v': + return 0x0B; + case 'f': + return 0x0C; + case 'r': + return 0x0D; + case '"': + return 0x22; + case '\'': + return 0x27; + case '\\': + return 0x5C; + default: + return c; + } +} + +ushort JavaScript::Lexer::convertOctal(ushort c1, ushort c2, + ushort c3) const +{ + return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0'); +} + +unsigned char JavaScript::Lexer::convertHex(ushort c) +{ + if (c >= '0' && c <= '9') + return (c - '0'); + else if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + else + return (c - 'A' + 10); +} + +unsigned char JavaScript::Lexer::convertHex(ushort c1, ushort c2) +{ + return ((convertHex(c1) << 4) + convertHex(c2)); +} + +QChar JavaScript::Lexer::convertUnicode(ushort c1, ushort c2, + ushort c3, ushort c4) +{ + return QChar((convertHex(c3) << 4) + convertHex(c4), + (convertHex(c1) << 4) + convertHex(c2)); +} + +void JavaScript::Lexer::record8(ushort c) +{ + Q_ASSERT(c <= 0xff); + + // enlarge buffer if full + if (pos8 >= size8 - 1) { + char *tmp = new char[2 * size8]; + memcpy(tmp, buffer8, size8 * sizeof(char)); + delete [] buffer8; + buffer8 = tmp; + size8 *= 2; + } + + buffer8[pos8++] = (char) c; +} + +void JavaScript::Lexer::record16(QChar c) +{ + // enlarge buffer if full + if (pos16 >= size16 - 1) { + QChar *tmp = new QChar[2 * size16]; + memcpy(tmp, buffer16, size16 * sizeof(QChar)); + delete [] buffer16; + buffer16 = tmp; + size16 *= 2; + } + + buffer16[pos16++] = c; +} + +void JavaScript::Lexer::recordStartPos() +{ + startpos = pos; + startlineno = yylineno; + startcolumn = yycolumn; +} + +bool JavaScript::Lexer::scanRegExp(RegExpBodyPrefix prefix) +{ + pos16 = 0; + bool lastWasEscape = false; + + if (prefix == EqualPrefix) + record16(QLatin1Char('=')); + + while (1) { + if (isLineTerminator() || current == 0) { + errmsg = QLatin1String("Unterminated regular expression literal"); + return false; + } + else if (current != '/' || lastWasEscape == true) + { + record16(current); + lastWasEscape = !lastWasEscape && (current == '\\'); + } + else { + if (driver) + pattern = driver->intern(buffer16, pos16); + else + pattern = 0; + pos16 = 0; + shift(1); + break; + } + shift(1); + } + + flags = 0; + while (isIdentLetter(current)) { + int flag = JavaScript::Ecma::RegExp::flagFromChar(current); + if (flag == 0) { + errmsg = QString::fromLatin1("Invalid regular expression flag '%0'") + .arg(QChar(current)); + return false; + } + flags |= flag; + record16(current); + shift(1); + } + + return true; +} + +void JavaScript::Lexer::syncProhibitAutomaticSemicolon() +{ + if (parenthesesState == BalancedParentheses) { + // we have seen something like "if (foo)", which means we should + // never insert an automatic semicolon at this point, since it would + // then be expanded into an empty statement (ECMA-262 7.9.1) + prohibitAutomaticSemicolon = true; + parenthesesState = IgnoreParentheses; + } else { + prohibitAutomaticSemicolon = false; + } +} + +QT_END_NAMESPACE + + diff --git a/src/declarative/qml/parser/javascriptlexer_p.h b/src/declarative/qml/parser/javascriptlexer_p.h new file mode 100644 index 0000000..e71c10c --- /dev/null +++ b/src/declarative/qml/parser/javascriptlexer_p.h @@ -0,0 +1,250 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTLEXER_P_H +#define JAVASCRIPTLEXER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QString> + + + +QT_BEGIN_NAMESPACE + +class JavaScriptEnginePrivate; +class JavaScriptNameIdImpl; + +namespace JavaScript { + +class Lexer +{ +public: + Lexer(JavaScriptEnginePrivate *eng); + ~Lexer(); + + void setCode(const QString &c, int lineno); + int lex(); + + int currentLineNo() const { return yylineno; } + int currentColumnNo() const { return yycolumn; } + + int tokenOffset() const { return startpos; } + int tokenLength() const { return pos - startpos; } + + int startLineNo() const { return startlineno; } + int startColumnNo() const { return startcolumn; } + + int endLineNo() const { return currentLineNo(); } + int endColumnNo() const + { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; } + + bool prevTerminator() const { return terminator; } + + enum State { Start, + Identifier, + InIdentifier, + InSingleLineComment, + InMultiLineComment, + InNum, + InNum0, + InHex, + InOctal, + InDecimal, + InExponentIndicator, + InExponent, + Hex, + Octal, + Number, + String, + Eof, + InString, + InEscapeSequence, + InHexEscape, + InUnicodeEscape, + Other, + Bad }; + + enum Error { + NoError, + IllegalCharacter, + UnclosedStringLiteral, + IllegalEscapeSequence, + IllegalUnicodeEscapeSequence, + UnclosedComment, + IllegalExponentIndicator, + IllegalIdentifier + }; + + enum ParenthesesState { + IgnoreParentheses, + CountParentheses, + BalancedParentheses + }; + + enum RegExpBodyPrefix { + NoPrefix, + EqualPrefix + }; + + bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix); + + JavaScriptNameIdImpl *pattern; + int flags; + + State lexerState() const + { return state; } + + QString errorMessage() const + { return errmsg; } + void setErrorMessage(const QString &err) + { errmsg = err; } + void setErrorMessage(const char *err) + { setErrorMessage(QString::fromLatin1(err)); } + + Error error() const + { return err; } + void clearError() + { err = NoError; } + +private: + JavaScriptEnginePrivate *driver; + int yylineno; + bool done; + char *buffer8; + QChar *buffer16; + uint size8, size16; + uint pos8, pos16; + bool terminator; + bool restrKeyword; + // encountered delimiter like "'" and "}" on last run + bool delimited; + int stackToken; + + State state; + void setDone(State s); + uint pos; + void shift(uint p); + int lookupKeyword(const char *); + + bool isWhiteSpace() const; + bool isLineTerminator() const; + bool isHexDigit(ushort c) const; + bool isOctalDigit(ushort c) const; + + int matchPunctuator(ushort c1, ushort c2, + ushort c3, ushort c4); + ushort singleEscape(ushort c) const; + ushort convertOctal(ushort c1, ushort c2, + ushort c3) const; +public: + static unsigned char convertHex(ushort c1); + static unsigned char convertHex(ushort c1, ushort c2); + static QChar convertUnicode(ushort c1, ushort c2, + ushort c3, ushort c4); + static bool isIdentLetter(ushort c); + static bool isDecimalDigit(ushort c); + + inline int ival() const { return qsyylval.ival; } + inline double dval() const { return qsyylval.dval; } + inline JavaScriptNameIdImpl *ustr() const { return qsyylval.ustr; } + + const QChar *characterBuffer() const { return buffer16; } + int characterCount() const { return pos16; } + +private: + void record8(ushort c); + void record16(QChar c); + void recordStartPos(); + + int findReservedWord(const QChar *buffer, int size) const; + + void syncProhibitAutomaticSemicolon(); + + const QChar *code; + uint length; + int yycolumn; + int startpos; + int startlineno; + int startcolumn; + int bol; // begin of line + + union { + int ival; + double dval; + JavaScriptNameIdImpl *ustr; + } qsyylval; + + // current and following unicode characters + ushort current, next1, next2, next3; + + struct keyword { + const char *name; + int token; + }; + + QString errmsg; + Error err; + + bool wantRx; + bool check_reserved; + + ParenthesesState parenthesesState; + int parenthesesCount; + bool prohibitAutomaticSemicolon; +}; + +} // namespace JavaScript + +QT_END_NAMESPACE + + + +#endif diff --git a/src/declarative/qml/parser/javascriptmemorypool_p.h b/src/declarative/qml/parser/javascriptmemorypool_p.h new file mode 100644 index 0000000..cff7677 --- /dev/null +++ b/src/declarative/qml/parser/javascriptmemorypool_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTMEMORYPOOL_P_H +#define JAVASCRIPTMEMORYPOOL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtCore/qshareddata.h> +#include <string.h> + +QT_BEGIN_NAMESPACE + +namespace JavaScript { + +class MemoryPool : public QSharedData +{ +public: + enum { maxBlockCount = -1 }; + enum { defaultBlockSize = 1 << 12 }; + + MemoryPool() { + m_blockIndex = maxBlockCount; + m_currentIndex = 0; + m_storage = 0; + m_currentBlock = 0; + m_currentBlockSize = 0; + } + + virtual ~MemoryPool() { + for (int index = 0; index < m_blockIndex + 1; ++index) + qFree(m_storage[index]); + + qFree(m_storage); + } + + char *allocate(int bytes) { + bytes += (8 - bytes) & 7; // ensure multiple of 8 bytes (maintain alignment) + if (m_currentBlock == 0 || m_currentBlockSize < m_currentIndex + bytes) { + ++m_blockIndex; + m_currentBlockSize = defaultBlockSize << m_blockIndex; + + m_storage = reinterpret_cast<char**>(qRealloc(m_storage, sizeof(char*) * (1 + m_blockIndex))); + m_currentBlock = m_storage[m_blockIndex] = reinterpret_cast<char*>(qMalloc(m_currentBlockSize)); + ::memset(m_currentBlock, 0, m_currentBlockSize); + + m_currentIndex = (8 - quintptr(m_currentBlock)) & 7; // ensure first chunk is 64-bit aligned + Q_ASSERT(m_currentIndex + bytes <= m_currentBlockSize); + } + + char *p = reinterpret_cast<char *> + (m_currentBlock + m_currentIndex); + + m_currentIndex += bytes; + + return p; + } + + int bytesAllocated() const { + int bytes = 0; + for (int index = 0; index < m_blockIndex; ++index) + bytes += (defaultBlockSize << index); + bytes += m_currentIndex; + return bytes; + } + +private: + int m_blockIndex; + int m_currentIndex; + char *m_currentBlock; + int m_currentBlockSize; + char **m_storage; + +private: + Q_DISABLE_COPY(MemoryPool) +}; + +} // namespace JavaScript + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/qml/parser/javascriptnodepool_p.h b/src/declarative/qml/parser/javascriptnodepool_p.h new file mode 100644 index 0000000..3f59123 --- /dev/null +++ b/src/declarative/qml/parser/javascriptnodepool_p.h @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTNODEPOOL_P_H +#define JAVASCRIPTNODEPOOL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QHash> +#include <QtCore/QString> + +#include "javascriptmemorypool_p.h" + +QT_BEGIN_NAMESPACE + +class JavaScriptEnginePrivate; + +namespace JavaScript { + +namespace AST { +class Node; +} // namespace AST + +class Code; +class CompilationUnit; + +template <typename NodeType> +inline NodeType *makeAstNode(MemoryPool *storage) +{ + NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(); + return node; +} + +template <typename NodeType, typename Arg1> +inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1) +{ + NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1); + return node; +} + +template <typename NodeType, typename Arg1, typename Arg2> +inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2) +{ + NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2); + return node; +} + +template <typename NodeType, typename Arg1, typename Arg2, typename Arg3> +inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3) +{ + NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3); + return node; +} + +template <typename NodeType, typename Arg1, typename Arg2, typename Arg3, typename Arg4> +inline NodeType *makeAstNode(MemoryPool *storage, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) +{ + NodeType *node = new (storage->allocate(sizeof(NodeType))) NodeType(arg1, arg2, arg3, arg4); + return node; +} + +class NodePool : public MemoryPool +{ +public: + NodePool(const QString &fileName, JavaScriptEnginePrivate *engine); + virtual ~NodePool(); + + Code *createCompiledCode(AST::Node *node, CompilationUnit &compilation); + + inline QString fileName() const { return m_fileName; } + inline JavaScriptEnginePrivate *engine() const { return m_engine; } +#ifndef J_SCRIPT_NO_EVENT_NOTIFY + inline qint64 id() const { return m_id; } +#endif + +private: + QHash<AST::Node*, Code*> m_codeCache; + QString m_fileName; + JavaScriptEnginePrivate *m_engine; +#ifndef J_SCRIPT_NO_EVENT_NOTIFY + qint64 m_id; +#endif + +private: + Q_DISABLE_COPY(NodePool) +}; + +} // namespace JavaScript + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/qml/parser/javascriptparser.cpp b/src/declarative/qml/parser/javascriptparser.cpp new file mode 100644 index 0000000..0b87500 --- /dev/null +++ b/src/declarative/qml/parser/javascriptparser.cpp @@ -0,0 +1,1207 @@ +// This file was generated by qlalr - DO NOT EDIT! + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QtDebug> + +#include <string.h> + +#include "javascriptengine_p.h" +#include "javascriptlexer_p.h" +#include "javascriptast_p.h" +#include "javascriptnodepool_p.h" + + + +#include "javascriptparser_p.h" + +// +// This file is automatically generated from javascript.g. +// Changes will be lost. +// + +using namespace JavaScript; + +QT_BEGIN_NAMESPACE + +void JavaScriptParser::reallocateStack() +{ + if (! stack_size) + stack_size = 128; + else + stack_size <<= 1; + + sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); + state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int))); + location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation))); +} + +inline static bool automatic(JavaScriptEnginePrivate *driver, int token) +{ + return token == JavaScriptGrammar::T_RBRACE + || token == 0 + || driver->lexer()->prevTerminator(); +} + + +JavaScriptParser::JavaScriptParser(): + tos(0), + stack_size(0), + sym_stack(0), + state_stack(0), + location_stack(0), + first_token(0), + last_token(0) +{ +} + +JavaScriptParser::~JavaScriptParser() +{ + if (stack_size) { + qFree(sym_stack); + qFree(state_stack); + qFree(location_stack); + } +} + +static inline AST::SourceLocation location(Lexer *lexer) +{ + AST::SourceLocation loc; + loc.offset = lexer->tokenOffset(); + loc.length = lexer->tokenLength(); + loc.startLine = lexer->startLineNo(); + loc.startColumn = lexer->startColumnNo(); + return loc; +} + +bool JavaScriptParser::parse(JavaScriptEnginePrivate *driver) +{ + Lexer *lexer = driver->lexer(); + bool hadErrors = false; + int yytoken = -1; + int action = 0; + + first_token = last_token = 0; + + tos = -1; + + do { + if (++tos == stack_size) + reallocateStack(); + + state_stack[tos] = action; + + _Lcheck_token: + if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) { + yyprevlloc = yylloc; + + if (first_token == last_token) { + yytoken = lexer->lex(); + yylval = lexer->dval(); + yylloc = location(lexer); + } else { + yytoken = first_token->token; + yylval = first_token->dval; + yylloc = first_token->loc; + ++first_token; + } + } + + action = t_action(action, yytoken); + if (action > 0) { + if (action != ACCEPT_STATE) { + yytoken = -1; + sym(1).dval = yylval; + loc(1) = yylloc; + } else { + --tos; + return ! hadErrors; + } + } else if (action < 0) { + const int r = -action - 1; + tos -= rhs[r]; + + switch (r) { + +case 0: { + sym(1).Node = makeAstNode<AST::UiProgram> (driver->nodePool(), sym(1).UiObjectMemberList->finish()); +} break; + +case 2: { + sym(1).Node = makeAstNode<AST::UiObjectMemberList> (driver->nodePool(), sym(1).UiObjectMember); +} break; +case 3: +case 4: { + AST::UiObjectMemberList *node = makeAstNode<AST:: UiObjectMemberList> (driver->nodePool(), + sym(1).UiObjectMemberList, sym(3).UiObjectMember); + sym(1).Node = node; +} break; + +case 5: { + AST::UiObjectInitializer *node = makeAstNode<AST::UiObjectInitializer> (driver->nodePool(), sym(2).UiObjectMemberList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; +} break; + +case 6: { + AST::UiObjectBinding *node = makeAstNode<AST::UiObjectBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(3).sval, sym(4).UiObjectInitializer); + node->colonToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; + +case 7: { + AST::UiObjectDefinition *node = makeAstNode<AST::UiObjectDefinition> (driver->nodePool(), sym(1).sval, + sym(2).UiObjectInitializer); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 8: { + AST::UiArrayBinding *node = makeAstNode<AST::UiArrayBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(4).UiObjectMemberList->finish()); + node->colonToken = loc(2); + node->lbracketToken = loc(3); + node->rbraceToken = loc(5); + sym(1).Node = node; +} break; + +case 9: { + AST::UiScriptBinding *node = makeAstNode<AST::UiScriptBinding> (driver->nodePool(), sym(1).UiQualifiedId->finish(), + sym(3).Statement); + node->colonToken = loc(2); + sym(1).Node = node; +} break; + +case 10: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval, + sym(5).Expression, sym(6).UiObjectInitializer); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; +} break; + +case 11: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; + +case 12: { + AST::UiPublicMember *node = makeAstNode<AST::UiPublicMember> (driver->nodePool(), sym(2).sval, sym(3).sval, + sym(5).Expression, static_cast<AST::UiObjectInitializer *>(0)); + node->publicToken = loc(1); + node->attributeTypeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; +} break; + +case 13: { + AST::UiQualifiedId *node = makeAstNode<AST::UiQualifiedId> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 14: + AST::UiQualifiedId *node = makeAstNode<AST::UiQualifiedId> (driver->nodePool(), sym(1).UiQualifiedId, sym(3).sval); + node->identifierToken = loc(3); + sym(1).Node = node; + break; + +case 15: { + AST::ThisExpression *node = makeAstNode<AST::ThisExpression> (driver->nodePool()); + node->thisToken = loc(1); + sym(1).Node = node; +} break; + +case 16: { + AST::IdentifierExpression *node = makeAstNode<AST::IdentifierExpression> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 17: { + AST::NullExpression *node = makeAstNode<AST::NullExpression> (driver->nodePool()); + node->nullToken = loc(1); + sym(1).Node = node; +} break; + +case 18: { + AST::TrueLiteral *node = makeAstNode<AST::TrueLiteral> (driver->nodePool()); + node->trueToken = loc(1); + sym(1).Node = node; +} break; + +case 19: { + AST::FalseLiteral *node = makeAstNode<AST::FalseLiteral> (driver->nodePool()); + node->falseToken = loc(1); + sym(1).Node = node; +} break; + +case 20: { + AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval); + node->literalToken = loc(1); + sym(1).Node = node; +} break; + +case 21: { + AST::StringLiteral *node = makeAstNode<AST::StringLiteral> (driver->nodePool(), sym(1).sval); + node->literalToken = loc(1); + sym(1).Node = node; +} break; + +case 22: { + bool rx = lexer->scanRegExp(Lexer::NoPrefix); + if (!rx) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(), + lexer->startColumnNo(), lexer->errorMessage())); + return false; + } + AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags); + node->literalToken = loc(1); + sym(1).Node = node; +} break; + +case 23: { + bool rx = lexer->scanRegExp(Lexer::EqualPrefix); + if (!rx) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, lexer->startLineNo(), + lexer->startColumnNo(), lexer->errorMessage())); + return false; + } + AST::RegExpLiteral *node = makeAstNode<AST::RegExpLiteral> (driver->nodePool(), lexer->pattern, lexer->flags); + node->literalToken = loc(1); + sym(1).Node = node; +} break; + +case 24: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).Elision); +} break; + +case 25: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish ()); +} break; + +case 26: { + sym(1).Node = makeAstNode<AST::ArrayLiteral> (driver->nodePool(), sym(2).ElementList->finish (), sym(4).Elision); +} break; + +case 27: { + if (sym(2).Node) + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ()); + else + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool()); +} break; + +case 28: { + sym(1).Node = makeAstNode<AST::ObjectLiteral> (driver->nodePool(), sym(2).PropertyNameAndValueList->finish ()); +} break; + +case 29: { + sym(1) = sym(2); +} break; + +case 30: { + sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).Elision, sym(2).Expression); +} break; + +case 31: { + sym(1).Node = makeAstNode<AST::ElementList> (driver->nodePool(), sym(1).ElementList, sym(3).Elision, sym(4).Expression); +} break; + +case 32: { + sym(1).Node = makeAstNode<AST::Elision> (driver->nodePool()); +} break; + +case 33: { + sym(1).Node = makeAstNode<AST::Elision> (driver->nodePool(), sym(1).Elision); +} break; + +case 34: { + sym(1).Node = 0; +} break; + +case 35: { + sym(1).Elision = sym(1).Elision->finish (); +} break; + +case 36: { + sym(1).Node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyName, sym(3).Expression); +} break; + +case 37: { + sym(1).Node = makeAstNode<AST::PropertyNameAndValueList> (driver->nodePool(), sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression); +} break; + +case 38: { + sym(1).Node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval); +} break; + +case 39: { + sym(1).Node = makeAstNode<AST::StringLiteralPropertyName> (driver->nodePool(), sym(1).sval); +} break; + +case 40: { + sym(1).Node = makeAstNode<AST::NumericLiteralPropertyName> (driver->nodePool(), sym(1).dval); +} break; + +case 41: { + sym(1).Node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval); +} break; + +case 42: + +case 43: + +case 44: + +case 45: + +case 46: + +case 47: + +case 48: + +case 49: + +case 50: + +case 51: + +case 52: + +case 53: + +case 54: + +case 55: + +case 56: + +case 57: + +case 58: + +case 59: + +case 60: + +case 61: + +case 62: + +case 63: + +case 64: + +case 65: + +case 66: + +case 67: + +case 68: + +case 69: + +case 70: + +case 71: + +case 72: +{ + sym(1).sval = driver->intern(lexer->characterBuffer(), lexer->characterCount()); +} break; + +case 77: { + sym(1).Node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; + +case 78: { + AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; + +case 79: { + AST::NewMemberExpression *node = makeAstNode<AST::NewMemberExpression> (driver->nodePool(), sym(2).Expression, sym(4).ArgumentList); + node->newToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + sym(1).Node = node; +} break; + +case 81: { + AST::NewExpression *node = makeAstNode<AST::NewExpression> (driver->nodePool(), sym(2).Expression); + node->newToken = loc(1); + sym(1).Node = node; +} break; + +case 82: { + AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; +} break; + +case 83: { + AST::CallExpression *node = makeAstNode<AST::CallExpression> (driver->nodePool(), sym(1).Expression, sym(3).ArgumentList); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; +} break; + +case 84: { + sym(1).Node = makeAstNode<AST::ArrayMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; + +case 85: { + AST::FieldMemberExpression *node = makeAstNode<AST::FieldMemberExpression> (driver->nodePool(), sym(1).Expression, sym(3).sval); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; + +case 86: { + sym(1).Node = 0; +} break; + +case 87: { + sym(1).Node = sym(1).ArgumentList->finish(); +} break; + +case 88: { + sym(1).Node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).Expression); +} break; + +case 89: { + AST::ArgumentList *node = makeAstNode<AST::ArgumentList> (driver->nodePool(), sym(1).ArgumentList, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; +} break; + +case 93: { + sym(1).Node = makeAstNode<AST::PostIncrementExpression> (driver->nodePool(), sym(1).Expression); +} break; + +case 94: { + sym(1).Node = makeAstNode<AST::PostDecrementExpression> (driver->nodePool(), sym(1).Expression); +} break; + +case 96: { + sym(1).Node = makeAstNode<AST::DeleteExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 97: { + sym(1).Node = makeAstNode<AST::VoidExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 98: { + sym(1).Node = makeAstNode<AST::TypeOfExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 99: { + sym(1).Node = makeAstNode<AST::PreIncrementExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 100: { + sym(1).Node = makeAstNode<AST::PreDecrementExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 101: { + sym(1).Node = makeAstNode<AST::UnaryPlusExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 102: { + sym(1).Node = makeAstNode<AST::UnaryMinusExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 103: { + sym(1).Node = makeAstNode<AST::TildeExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 104: { + sym(1).Node = makeAstNode<AST::NotExpression> (driver->nodePool(), sym(2).Expression); +} break; + +case 106: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mul, sym(3).Expression); +} break; + +case 107: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Div, sym(3).Expression); +} break; + +case 108: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Mod, sym(3).Expression); +} break; + +case 110: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Add, sym(3).Expression); +} break; + +case 111: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Sub, sym(3).Expression); +} break; + +case 113: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::LShift, sym(3).Expression); +} break; + +case 114: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::RShift, sym(3).Expression); +} break; + +case 115: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::URShift, sym(3).Expression); +} break; + +case 117: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); +} break; + +case 118: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); +} break; + +case 119: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); +} break; + +case 120: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); +} break; + +case 121: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); +} break; + +case 122: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::In, sym(3).Expression); +} break; + +case 124: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Lt, sym(3).Expression); +} break; + +case 125: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Gt, sym(3).Expression); +} break; + +case 126: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Le, sym(3).Expression); +} break; + +case 127: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Ge, sym(3).Expression); +} break; + +case 128: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); +} break; + +case 130: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); +} break; + +case 131: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); +} break; + +case 132: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); +} break; + +case 133: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); +} break; + +case 135: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Equal, sym(3).Expression); +} break; + +case 136: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); +} break; + +case 137: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); +} break; + +case 138: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); +} break; + +case 140: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); +} break; + +case 142: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); +} break; + +case 144: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression); +} break; + +case 146: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitXor, sym(3).Expression); +} break; + +case 148: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression); +} break; + +case 150: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::BitOr, sym(3).Expression); +} break; + +case 152: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression); +} break; + +case 154: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::And, sym(3).Expression); +} break; + +case 156: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression); +} break; + +case 158: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, QSOperator::Or, sym(3).Expression); +} break; + +case 160: { + sym(1).Node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); +} break; + +case 162: { + sym(1).Node = makeAstNode<AST::ConditionalExpression> (driver->nodePool(), sym(1).Expression, sym(3).Expression, sym(5).Expression); +} break; + +case 164: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); +} break; + +case 166: { + sym(1).Node = makeAstNode<AST::BinaryExpression> (driver->nodePool(), sym(1).Expression, sym(2).ival, sym(3).Expression); +} break; + +case 167: { + sym(1).ival = QSOperator::Assign; +} break; + +case 168: { + sym(1).ival = QSOperator::InplaceMul; +} break; + +case 169: { + sym(1).ival = QSOperator::InplaceDiv; +} break; + +case 170: { + sym(1).ival = QSOperator::InplaceMod; +} break; + +case 171: { + sym(1).ival = QSOperator::InplaceAdd; +} break; + +case 172: { + sym(1).ival = QSOperator::InplaceSub; +} break; + +case 173: { + sym(1).ival = QSOperator::InplaceLeftShift; +} break; + +case 174: { + sym(1).ival = QSOperator::InplaceRightShift; +} break; + +case 175: { + sym(1).ival = QSOperator::InplaceURightShift; +} break; + +case 176: { + sym(1).ival = QSOperator::InplaceAnd; +} break; + +case 177: { + sym(1).ival = QSOperator::InplaceXor; +} break; + +case 178: { + sym(1).ival = QSOperator::InplaceOr; +} break; + +case 180: { + sym(1).Node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; + +case 181: { + sym(1).Node = 0; +} break; + +case 184: { + sym(1).Node = makeAstNode<AST::Expression> (driver->nodePool(), sym(1).Expression, sym(3).Expression); +} break; + +case 185: { + sym(1).Node = 0; +} break; + +case 202: { + sym(1).Node = makeAstNode<AST::Block> (driver->nodePool(), sym(2).StatementList); +} break; + +case 203: { + sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).Statement); +} break; + +case 204: { + sym(1).Node = makeAstNode<AST::StatementList> (driver->nodePool(), sym(1).StatementList, sym(2).Statement); +} break; + +case 205: { + sym(1).Node = 0; +} break; + +case 206: { + sym(1).Node = sym(1).StatementList->finish (); +} break; + +case 208: { + AST::VariableStatement *node = makeAstNode<AST::VariableStatement> (driver->nodePool(), sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST)); + node->declarationKindToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; +} break; + +case 209: { + sym(1).ival = T_CONST; +} break; + +case 210: { + sym(1).ival = T_VAR; +} break; + +case 211: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration); +} break; + +case 212: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); +} break; + +case 213: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclaration); +} break; + +case 214: { + sym(1).Node = makeAstNode<AST::VariableDeclarationList> (driver->nodePool(), sym(1).VariableDeclarationList, sym(3).VariableDeclaration); +} break; + +case 215: { + AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 216: { + AST::VariableDeclaration *node = makeAstNode<AST::VariableDeclaration> (driver->nodePool(), sym(1).sval, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 217: { + sym(1) = sym(2); +} break; + +case 218: { + sym(1).Node = 0; +} break; + +case 220: { + sym(1) = sym(2); +} break; + +case 221: { + sym(1).Node = 0; +} break; + +case 223: { + sym(1).Node = makeAstNode<AST::EmptyStatement> (driver->nodePool()); +} break; + +case 225: { + AST::ExpressionStatement *node = makeAstNode<AST::ExpressionStatement> (driver->nodePool(), sym(1).Expression); + node->semicolonToken = loc(2); + sym(1).Node = node; +} break; + +case 226: { + sym(1).Node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement, sym(7).Statement); +} break; + +case 227: { + sym(1).Node = makeAstNode<AST::IfStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; + +case 229: { + sym(1).Node = makeAstNode<AST::DoWhileStatement> (driver->nodePool(), sym(2).Statement, sym(5).Expression); +} break; + +case 230: { + sym(1).Node = makeAstNode<AST::WhileStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; + +case 231: { + sym(1).Node = makeAstNode<AST::ForStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement); +} break; + +case 232: { + sym(1).Node = makeAstNode<AST::LocalForStatement> (driver->nodePool(), sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression, sym(8).Expression, sym(10).Statement); +} break; + +case 233: { + sym(1).Node = makeAstNode<AST::ForEachStatement> (driver->nodePool(), sym(3).Expression, sym(5).Expression, sym(7).Statement); +} break; + +case 234: { + sym(1).Node = makeAstNode<AST::LocalForEachStatement> (driver->nodePool(), sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); +} break; + +case 236: { + sym(1).Node = makeAstNode<AST::ContinueStatement> (driver->nodePool()); +} break; + +case 238: { + sym(1).Node = makeAstNode<AST::ContinueStatement> (driver->nodePool(), sym(2).sval); +} break; + +case 240: { + sym(1).Node = makeAstNode<AST::BreakStatement> (driver->nodePool()); +} break; + +case 242: { + sym(1).Node = makeAstNode<AST::BreakStatement> (driver->nodePool(), sym(2).sval); +} break; + +case 244: { + sym(1).Node = makeAstNode<AST::ReturnStatement> (driver->nodePool(), sym(2).Expression); +} break; + +case 245: { + sym(1).Node = makeAstNode<AST::WithStatement> (driver->nodePool(), sym(3).Expression, sym(5).Statement); +} break; + +case 246: { + sym(1).Node = makeAstNode<AST::SwitchStatement> (driver->nodePool(), sym(3).Expression, sym(5).CaseBlock); +} break; + +case 247: { + sym(1).Node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses); +} break; + +case 248: { + sym(1).Node = makeAstNode<AST::CaseBlock> (driver->nodePool(), sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); +} break; + +case 249: { + sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClause); +} break; + +case 250: { + sym(1).Node = makeAstNode<AST::CaseClauses> (driver->nodePool(), sym(1).CaseClauses, sym(2).CaseClause); +} break; + +case 251: { + sym(1).Node = 0; +} break; + +case 252: { + sym(1).Node = sym(1).CaseClauses->finish (); +} break; + +case 253: { + sym(1).Node = makeAstNode<AST::CaseClause> (driver->nodePool(), sym(2).Expression, sym(4).StatementList); +} break; + +case 254: { + sym(1).Node = makeAstNode<AST::DefaultClause> (driver->nodePool(), sym(3).StatementList); +} break; + +case 255: { + sym(1).Node = makeAstNode<AST::LabelledStatement> (driver->nodePool(), sym(1).sval, sym(3).Statement); +} break; + +case 257: { + sym(1).Node = makeAstNode<AST::ThrowStatement> (driver->nodePool(), sym(2).Expression); +} break; + +case 258: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch); +} break; + +case 259: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Finally); +} break; + +case 260: { + sym(1).Node = makeAstNode<AST::TryStatement> (driver->nodePool(), sym(2).Statement, sym(3).Catch, sym(4).Finally); +} break; + +case 261: { + sym(1).Node = makeAstNode<AST::Catch> (driver->nodePool(), sym(3).sval, sym(5).Statement); +} break; + +case 262: { + sym(1).Node = makeAstNode<AST::Finally> (driver->nodePool(), sym(2).Statement); +} break; + +case 264: { + sym(1).Node = makeAstNode<AST::DebuggerStatement> (driver->nodePool()); +} break; + +case 265: { + AST::FunctionDeclaration *node = makeAstNode<AST::FunctionDeclaration> (driver->nodePool(), sym(2).sval, 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 266: { + AST::FunctionExpression *node = makeAstNode<AST::FunctionExpression> (driver->nodePool(), sym(2).sval, sym(4).FormalParameterList, sym(7).FunctionBody); + node->functionToken = loc(1); + if (sym(2).sval) + 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 267: { + AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).sval); + node->identifierToken = loc(1); + sym(1).Node = node; +} break; + +case 268: { + AST::FormalParameterList *node = makeAstNode<AST::FormalParameterList> (driver->nodePool(), sym(1).FormalParameterList, sym(3).sval); + node->commaToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; +} break; + +case 269: { + sym(1).Node = 0; +} break; + +case 270: { + sym(1).Node = sym(1).FormalParameterList->finish (); +} break; + +case 271: { + sym(1).Node = 0; +} break; + +case 273: { + sym(1).Node = makeAstNode<AST::FunctionBody> (driver->nodePool(), sym(1).SourceElements->finish ()); +} break; + +case 274: { + sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElement); +} break; + +case 275: { + sym(1).Node = makeAstNode<AST::SourceElements> (driver->nodePool(), sym(1).SourceElements, sym(2).SourceElement); +} break; + +case 276: { + sym(1).Node = makeAstNode<AST::StatementSourceElement> (driver->nodePool(), sym(1).Statement); +} break; + +case 277: { + sym(1).Node = makeAstNode<AST::FunctionSourceElement> (driver->nodePool(), sym(1).FunctionDeclaration); +} break; + +case 278: { + sym(1).sval = 0; +} break; + +case 280: { + sym(1).Node = 0; +} break; + + } // switch + action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT); + } // if + } while (action != 0); + + if (first_token == last_token) { + const int errorState = state_stack[tos]; + + // automatic insertion of `;' + if (t_action(errorState, T_AUTOMATIC_SEMICOLON) && automatic(driver, yytoken)) { + SavedToken &tk = token_buffer[0]; + tk.token = yytoken; + tk.dval = yylval; + tk.loc = yylloc; + + const QString msg = QString::fromUtf8("Missing `;'"); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, + yyprevlloc.startLine, yyprevlloc.startColumn, msg)); + + first_token = &token_buffer[0]; + last_token = &token_buffer[1]; + + yytoken = T_SEMICOLON; + yylval = 0; + + action = errorState; + + goto _Lcheck_token; + } + + hadErrors = true; + + token_buffer[0].token = yytoken; + token_buffer[0].dval = yylval; + token_buffer[0].loc = yylloc; + + token_buffer[1].token = yytoken = lexer->lex(); + token_buffer[1].dval = yylval = lexer->dval(); + token_buffer[1].loc = yylloc = location(lexer); + + if (t_action(errorState, yytoken)) { + const QString msg = QString::fromUtf8("Removed token: `%1'").arg(spell[token_buffer[0].token]); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + action = errorState; + goto _Lcheck_token; + } + + static int tokens[] = { + T_PLUS, + T_EQ, + + T_COMMA, + T_COLON, + T_SEMICOLON, + + T_RPAREN, T_RBRACKET, T_RBRACE, + + T_NUMERIC_LITERAL, + T_IDENTIFIER, + + T_LPAREN, T_LBRACKET, T_LBRACE, + + EOF_SYMBOL + }; + + for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) { + int a = t_action(errorState, *tk); + if (a > 0 && t_action(a, yytoken)) { + const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[*tk]); + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + yytoken = *tk; + yylval = 0; + yylloc = token_buffer[0].loc; + + first_token = &token_buffer[0]; + last_token = &token_buffer[2]; + + action = errorState; + goto _Lcheck_token; + } + } + + for (int tk = 1; tk < TERMINAL_COUNT; ++tk) { + int a = t_action(errorState, tk); + if (a > 0 && t_action(a, yytoken)) { + const QString msg = QString::fromUtf8("Inserted token: `%1'").arg(spell[tk]); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + + yytoken = tk; + yylval = 0; + yylloc = token_buffer[0].loc; + + action = errorState; + goto _Lcheck_token; + } + } + + const QString msg = QString::fromUtf8("Unexpected token"); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, + token_buffer[0].loc.startLine, token_buffer[0].loc.startColumn, msg)); + } + + return false; +} + +QT_END_NAMESPACE + + diff --git a/src/declarative/qml/parser/javascriptparser_p.h b/src/declarative/qml/parser/javascriptparser_p.h new file mode 100644 index 0000000..5a47cb0 --- /dev/null +++ b/src/declarative/qml/parser/javascriptparser_p.h @@ -0,0 +1,212 @@ +// This file was generated by qlalr - DO NOT EDIT! + +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// +// This file is automatically generated from javascript.g. +// Changes will be lost. +// + +#ifndef JAVASCRIPTPARSER_P_H +#define JAVASCRIPTPARSER_P_H + +#include "javascriptgrammar_p.h" +#include "javascriptast_p.h" +#include <QtCore/QList> + +QT_BEGIN_NAMESPACE + +class QString; +class JavaScriptEnginePrivate; +class JavaScriptNameIdImpl; + +class JavaScriptParser: protected JavaScriptGrammar +{ +public: + union Value { + int ival; + double dval; + JavaScriptNameIdImpl *sval; + JavaScript::AST::ArgumentList *ArgumentList; + JavaScript::AST::CaseBlock *CaseBlock; + JavaScript::AST::CaseClause *CaseClause; + JavaScript::AST::CaseClauses *CaseClauses; + JavaScript::AST::Catch *Catch; + JavaScript::AST::DefaultClause *DefaultClause; + JavaScript::AST::ElementList *ElementList; + JavaScript::AST::Elision *Elision; + JavaScript::AST::ExpressionNode *Expression; + JavaScript::AST::Finally *Finally; + JavaScript::AST::FormalParameterList *FormalParameterList; + JavaScript::AST::FunctionBody *FunctionBody; + JavaScript::AST::FunctionDeclaration *FunctionDeclaration; + JavaScript::AST::Node *Node; + JavaScript::AST::PropertyName *PropertyName; + JavaScript::AST::PropertyNameAndValueList *PropertyNameAndValueList; + JavaScript::AST::SourceElement *SourceElement; + JavaScript::AST::SourceElements *SourceElements; + JavaScript::AST::Statement *Statement; + JavaScript::AST::StatementList *StatementList; + JavaScript::AST::VariableDeclaration *VariableDeclaration; + JavaScript::AST::VariableDeclarationList *VariableDeclarationList; + + JavaScript::AST::UiProgram *UiProgram; + JavaScript::AST::UiPublicMember *UiPublicMember; + JavaScript::AST::UiObjectDefinition *UiObjectDefinition; + JavaScript::AST::UiObjectInitializer *UiObjectInitializer; + JavaScript::AST::UiObjectBinding *UiObjectBinding; + JavaScript::AST::UiScriptBinding *UiScriptBinding; + JavaScript::AST::UiArrayBinding *UiArrayBinding; + JavaScript::AST::UiObjectMember *UiObjectMember; + JavaScript::AST::UiObjectMemberList *UiObjectMemberList; + JavaScript::AST::UiQualifiedId *UiQualifiedId; + }; + + struct DiagnosticMessage { + enum Kind { Warning, Error }; + + DiagnosticMessage() + : kind(Error), line(0), column(0) {} + + DiagnosticMessage(Kind kind, int line, int column, const QString &message) + : kind(kind), line(line), column(column), message(message) {} + + bool isWarning() const + { return kind == Warning; } + + bool isError() const + { return kind == Error; } + + Kind kind; + int line; + int column; + QString message; + }; + +public: + JavaScriptParser(); + ~JavaScriptParser(); + + bool parse(JavaScriptEnginePrivate *driver); + + JavaScript::AST::UiProgram *ast() + { return sym(1).UiProgram; } + + QList<DiagnosticMessage> diagnosticMessages() const + { return diagnostic_messages; } + + inline DiagnosticMessage diagnosticMessage() const + { + foreach (const DiagnosticMessage &d, diagnostic_messages) { + if (! d.kind == DiagnosticMessage::Warning) + return d; + } + + return DiagnosticMessage(); + } + + inline QString errorMessage() const + { return diagnosticMessage().message; } + + inline int errorLineNumber() const + { return diagnosticMessage().line; } + + inline int errorColumnNumber() const + { return diagnosticMessage().column; } + +protected: + void reallocateStack(); + + inline Value &sym(int index) + { return sym_stack [tos + index - 1]; } + + inline JavaScript::AST::SourceLocation &loc(int index) + { return location_stack [tos + index - 1]; } + +protected: + int tos; + int stack_size; + Value *sym_stack; + int *state_stack; + JavaScript::AST::SourceLocation *location_stack; + + // error recovery + enum { TOKEN_BUFFER_SIZE = 3 }; + + struct SavedToken { + int token; + double dval; + JavaScript::AST::SourceLocation loc; + }; + + double yylval; + JavaScript::AST::SourceLocation yylloc; + JavaScript::AST::SourceLocation yyprevlloc; + + SavedToken token_buffer[TOKEN_BUFFER_SIZE]; + SavedToken *first_token; + SavedToken *last_token; + + QList<DiagnosticMessage> diagnostic_messages; +}; + + +#define J_SCRIPT_REGEXPLITERAL_RULE1 22 + +#define J_SCRIPT_REGEXPLITERAL_RULE2 23 + +QT_END_NAMESPACE + + + +#endif // JAVASCRIPTPARSER_P_H diff --git a/src/declarative/qml/parser/javascriptprettypretty.cpp b/src/declarative/qml/parser/javascriptprettypretty.cpp new file mode 100644 index 0000000..6e632b7 --- /dev/null +++ b/src/declarative/qml/parser/javascriptprettypretty.cpp @@ -0,0 +1,1334 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "javascriptprettypretty_p.h" + + + +#include "javascriptengine_p.h" + + + + +#include "javascriptast_p.h" + +#include <QtCore/QString> +#include <QtCore/QTextStream> +#include <QtCore/QtDebug> + +QT_BEGIN_NAMESPACE + +namespace JavaScript { +QString numberToString(qjsreal value); +} + +using namespace JavaScript; + +PrettyPretty::PrettyPretty(QTextStream &o): + out(o), m_indentLevel(0) +{ +} + +PrettyPretty::~PrettyPretty() +{ +} + +void PrettyPretty::acceptAsBlock(AST::Node *node) +{ + out << "{"; + pushIndentLevel(); + newlineAndIndent(); + accept(node); + popIndentLevel(); + newlineAndIndent(); + out << "}"; +} + +int PrettyPretty::operatorPrecedenceLevel(int op) +{ + switch (op) { + case QSOperator::Div: + case QSOperator::Mod: + case QSOperator::Mul: + return 5; + case QSOperator::Add: + case QSOperator::Sub: + return 6; + case QSOperator::LShift: + case QSOperator::RShift: + case QSOperator::URShift: + return 7; + case QSOperator::Ge: + case QSOperator::Gt: + case QSOperator::In: + case QSOperator::InstanceOf: + case QSOperator::Le: + case QSOperator::Lt: + return 8; + case QSOperator::Equal: + case QSOperator::NotEqual: + case QSOperator::StrictEqual: + case QSOperator::StrictNotEqual: + return 9; + case QSOperator::BitAnd: + return 10; + case QSOperator::BitXor: + return 11; + case QSOperator::BitOr: + return 12; + case QSOperator::And: + return 13; + case QSOperator::Or: + return 14; + case QSOperator::InplaceAnd: + case QSOperator::InplaceSub: + case QSOperator::InplaceDiv: + case QSOperator::InplaceAdd: + case QSOperator::InplaceLeftShift: + case QSOperator::InplaceMod: + case QSOperator::InplaceMul: + case QSOperator::InplaceOr: + case QSOperator::InplaceRightShift: + case QSOperator::InplaceURightShift: + case QSOperator::InplaceXor: + case QSOperator::Assign: + return 16; + default: + Q_ASSERT_X(false, "PrettyPretty::operatorPrecedenceLevel()", "bad operator"); + } + return 0; +} + +int PrettyPretty::compareOperatorPrecedence(int op1, int op2) +{ + int prec1 = operatorPrecedenceLevel(op1); + int prec2 = operatorPrecedenceLevel(op2); + if (prec1 == prec2) + return 0; + if (prec1 > prec2) + return -1; + return 1; +} + +QTextStream &PrettyPretty::operator () (AST::Node *node, int level) +{ + int was = indentLevel(level); + accept(node); + indentLevel(was); + return out; +} + +QTextStream &PrettyPretty::newlineAndIndent() +{ + enum { IND = 4 }; + out << endl << QString().fill(QLatin1Char(' '), m_indentLevel * IND); + return out; +} + +void PrettyPretty::accept(AST::Node *node) +{ + AST::Node::acceptChild(node, this); +} + +bool PrettyPretty::visit(AST::ThisExpression *node) +{ + Q_UNUSED(node); + out << "this"; + return true; +} + +void PrettyPretty::endVisit(AST::ThisExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::IdentifierExpression *node) +{ + out << JavaScriptEnginePrivate::toString(node->name); + return true; +} + +void PrettyPretty::endVisit(AST::IdentifierExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NullExpression *node) +{ + Q_UNUSED(node); + out << "null"; + return false; +} + +void PrettyPretty::endVisit(AST::NullExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::TrueLiteral *node) +{ + Q_UNUSED(node); + out << "true"; + return false; +} + +void PrettyPretty::endVisit(AST::TrueLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FalseLiteral *node) +{ + Q_UNUSED(node); + out << "false"; + return false; +} + +void PrettyPretty::endVisit(AST::FalseLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::StringLiteral *node) +{ + QString lit = JavaScriptEnginePrivate::toString(node->value); + lit.replace(QLatin1String("\\"), QLatin1String("\\\\")); + out << "\"" << lit << "\""; + return false; +} + +void PrettyPretty::endVisit(AST::StringLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NumericLiteral *node) +{ + out << JavaScript::numberToString(node->value); + return true; +} + +void PrettyPretty::endVisit(AST::NumericLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::RegExpLiteral *node) +{ + out << "/" << JavaScriptEnginePrivate::toString(node->pattern) << "/"; + if (node->flags) + out << JavaScript::Ecma::RegExp::flagsToString(node->flags); + + return true; +} + +void PrettyPretty::endVisit(AST::RegExpLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ArrayLiteral *node) +{ + out << "["; + accept(node->elements); + accept(node->elision); + out << "]"; + return false; +} + +void PrettyPretty::endVisit(AST::ArrayLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ObjectLiteral *node) +{ + out << "{"; + if (node->properties) { + pushIndentLevel(); + AST::PropertyNameAndValueList *prop; + for (prop = node->properties; prop != 0; prop = prop->next) { + newlineAndIndent(); + accept(prop); + if (prop->next) + out << ","; + } + popIndentLevel(); + newlineAndIndent(); + } + out << "}"; + return false; +} + +void PrettyPretty::endVisit(AST::ObjectLiteral *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ElementList *node) +{ + accept(node->elision); + accept(node->expression); + for (node = node->next; node != 0; node = node->next) { + out << ", "; + accept(node->elision); + accept(node->expression); + } + return false; +} + +void PrettyPretty::endVisit(AST::ElementList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Elision *node) +{ + out << ", "; + for (AST::Elision *eit = node->next; eit != 0; eit = eit->next) + out << ", "; + return false; +} + +void PrettyPretty::endVisit(AST::Elision *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::PropertyNameAndValueList *node) +{ + accept(node->name); + out << ": "; + accept(node->value); + return false; +} + +void PrettyPretty::endVisit(AST::PropertyNameAndValueList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::IdentifierPropertyName *node) +{ + out << JavaScriptEnginePrivate::toString(node->id); + return false; +} + +void PrettyPretty::endVisit(AST::IdentifierPropertyName *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::StringLiteralPropertyName *node) +{ + QString lit = JavaScriptEnginePrivate::toString(node->id); + lit.replace(QLatin1String("\\"), QLatin1String("\\\\")); + out << lit; + return false; +} + +void PrettyPretty::endVisit(AST::StringLiteralPropertyName *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NumericLiteralPropertyName *node) +{ + out << node->id; + return false; +} + +void PrettyPretty::endVisit(AST::NumericLiteralPropertyName *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ArrayMemberExpression *node) +{ + accept(node->base); + out << "["; + accept(node->expression); + out << "]"; + return false; +} + +void PrettyPretty::endVisit(AST::ArrayMemberExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FieldMemberExpression *node) +{ + accept(node->base); + out << "." << JavaScriptEnginePrivate::toString(node->name); + return false; +} + +void PrettyPretty::endVisit(AST::FieldMemberExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NewMemberExpression *node) +{ + out << "new "; + accept(node->base); + out << "("; + accept(node->arguments); + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::NewMemberExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NewExpression *node) +{ + Q_UNUSED(node); + out << "new "; + return true; +} + +void PrettyPretty::endVisit(AST::NewExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::CallExpression *node) +{ + accept(node->base); + out << "("; + accept(node->arguments); + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::CallExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ArgumentList *node) +{ + accept(node->expression); + for (node = node->next; node != 0; node = node->next) { + out << ", "; + accept(node->expression); + } + return false; +} + +void PrettyPretty::endVisit(AST::ArgumentList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::PostIncrementExpression *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::PostIncrementExpression *node) +{ + Q_UNUSED(node); + out << "++"; +} + +bool PrettyPretty::visit(AST::PostDecrementExpression *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::PostDecrementExpression *node) +{ + Q_UNUSED(node); + out << "--"; +} + +bool PrettyPretty::visit(AST::DeleteExpression *node) +{ + Q_UNUSED(node); + out << "delete "; + return true; +} + +void PrettyPretty::endVisit(AST::DeleteExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::VoidExpression *node) +{ + Q_UNUSED(node); + out << "void "; + return true; +} + +void PrettyPretty::endVisit(AST::VoidExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::TypeOfExpression *node) +{ + Q_UNUSED(node); + out << "typeof "; + return true; +} + +void PrettyPretty::endVisit(AST::TypeOfExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::PreIncrementExpression *node) +{ + Q_UNUSED(node); + out << "++"; + return true; +} + +void PrettyPretty::endVisit(AST::PreIncrementExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::PreDecrementExpression *node) +{ + Q_UNUSED(node); + out << "--"; + return true; +} + +void PrettyPretty::endVisit(AST::PreDecrementExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::UnaryPlusExpression *node) +{ + out << "+"; + bool needParens = (node->expression->binaryExpressionCast() != 0); + if (needParens) + out << "("; + accept(node->expression); + if (needParens) + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::UnaryPlusExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::UnaryMinusExpression *node) +{ + out << "-"; + bool needParens = (node->expression->binaryExpressionCast() != 0); + if (needParens) + out << "("; + accept(node->expression); + if (needParens) + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::UnaryMinusExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::TildeExpression *node) +{ + out << "~"; + bool needParens = (node->expression->binaryExpressionCast() != 0); + if (needParens) + out << "("; + accept(node->expression); + if (needParens) + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::TildeExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::NotExpression *node) +{ + out << "!"; + bool needParens = (node->expression->binaryExpressionCast() != 0); + if (needParens) + out << "("; + accept(node->expression); + if (needParens) + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::NotExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::BinaryExpression *node) +{ + bool needParens = node->left->binaryExpressionCast() + && (compareOperatorPrecedence(node->left->binaryExpressionCast()->op, node->op) < 0); + if (needParens) + out << "("; + accept(node->left); + if (needParens) + out << ")"; + QString s; + switch (node->op) { + case QSOperator::Add: + s = QLatin1String("+"); break; + case QSOperator::And: + s = QLatin1String("&&"); break; + case QSOperator::InplaceAnd: + s = QLatin1String("&="); break; + case QSOperator::Assign: + s = QLatin1String("="); break; + case QSOperator::BitAnd: + s = QLatin1String("&"); break; + case QSOperator::BitOr: + s = QLatin1String("|"); break; + case QSOperator::BitXor: + s = QLatin1String("^"); break; + case QSOperator::InplaceSub: + s = QLatin1String("-="); break; + case QSOperator::Div: + s = QLatin1String("/"); break; + case QSOperator::InplaceDiv: + s = QLatin1String("/="); break; + case QSOperator::Equal: + s = QLatin1String("=="); break; + case QSOperator::Ge: + s = QLatin1String(">="); break; + case QSOperator::Gt: + s = QLatin1String(">"); break; + case QSOperator::In: + s = QLatin1String("in"); break; + case QSOperator::InplaceAdd: + s = QLatin1String("+="); break; + case QSOperator::InstanceOf: + s = QLatin1String("instanceof"); break; + case QSOperator::Le: + s = QLatin1String("<="); break; + case QSOperator::LShift: + s = QLatin1String("<<"); break; + case QSOperator::InplaceLeftShift: + s = QLatin1String("<<="); break; + case QSOperator::Lt: + s = QLatin1String("<"); break; + case QSOperator::Mod: + s = QLatin1String("%"); break; + case QSOperator::InplaceMod: + s = QLatin1String("%="); break; + case QSOperator::Mul: + s = QLatin1String("*"); break; + case QSOperator::InplaceMul: + s = QLatin1String("*="); break; + case QSOperator::NotEqual: + s = QLatin1String("!="); break; + case QSOperator::Or: + s = QLatin1String("||"); break; + case QSOperator::InplaceOr: + s = QLatin1String("|="); break; + case QSOperator::RShift: + s = QLatin1String(">>"); break; + case QSOperator::InplaceRightShift: + s = QLatin1String(">>="); break; + case QSOperator::StrictEqual: + s = QLatin1String("==="); break; + case QSOperator::StrictNotEqual: + s = QLatin1String("!=="); break; + case QSOperator::Sub: + s = QLatin1String("-"); break; + case QSOperator::URShift: + s = QLatin1String(">>>"); break; + case QSOperator::InplaceURightShift: + s = QLatin1String(">>>="); break; + case QSOperator::InplaceXor: + s = QLatin1String("^="); break; + default: + Q_ASSERT (0); + } + out << " " << s << " "; + needParens = node->right->binaryExpressionCast() + && (compareOperatorPrecedence(node->right->binaryExpressionCast()->op, node->op) <= 0); + if (needParens) + out << "("; + accept(node->right); + if (needParens) + out << ")"; + return false; +} + +void PrettyPretty::endVisit(AST::BinaryExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ConditionalExpression *node) +{ + accept(node->expression); + out << " ? "; + accept(node->ok); + out << " : "; + accept(node->ko); + return false; +} + +void PrettyPretty::endVisit(AST::ConditionalExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Expression *node) +{ + accept(node->left); + out << ", "; + accept(node->right); + return false; +} + +void PrettyPretty::endVisit(AST::Expression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Block *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::Block *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::StatementList *node) +{ + accept(node->statement); + for (node = node->next; node != 0; node = node->next) { + newlineAndIndent(); + accept(node->statement); + } + return false; +} + +void PrettyPretty::endVisit(AST::StatementList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::VariableDeclarationList *node) +{ + AST::VariableDeclarationList *it = node; + + do { + it->declaration->accept(this); + it = it->next; + if (it) + out << ", "; + } while (it); + + return false; +} + +void PrettyPretty::endVisit(AST::VariableDeclarationList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::VariableStatement *node) +{ + out << "var "; + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::VariableStatement *node) +{ + Q_UNUSED(node); + out << ";"; +} + +bool PrettyPretty::visit(AST::VariableDeclaration *node) +{ + out << JavaScriptEnginePrivate::toString(node->name); + if (node->expression) { + out << " = "; + accept(node->expression); + } + return false; +} + +void PrettyPretty::endVisit(AST::VariableDeclaration *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::EmptyStatement *node) +{ + Q_UNUSED(node); + out << ";"; + return true; +} + +void PrettyPretty::endVisit(AST::EmptyStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ExpressionStatement *node) +{ + accept(node->expression); + out << ";"; + return false; +} + +void PrettyPretty::endVisit(AST::ExpressionStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::IfStatement *node) +{ + out << "if ("; + accept(node->expression); + out << ") "; + acceptAsBlock(node->ok); + if (node->ko) { + out << " else "; + acceptAsBlock(node->ko); + } + return false; +} + +void PrettyPretty::endVisit(AST::IfStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::DoWhileStatement *node) +{ + out << "do "; + acceptAsBlock(node->statement); + out << " while ("; + accept(node->expression); + out << ");"; + return false; +} + +void PrettyPretty::endVisit(AST::DoWhileStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::WhileStatement *node) +{ + out << "while ("; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::WhileStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ForStatement *node) +{ + out << "for ("; + accept(node->initialiser); + out << "; "; + accept(node->condition); + out << "; "; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::ForStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::LocalForStatement *node) +{ + out << "for (var "; + accept(node->declarations); + out << "; "; + accept(node->condition); + out << "; "; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::LocalForStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ForEachStatement *node) +{ + out << "for ("; + accept(node->initialiser); + out << " in "; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::ForEachStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::LocalForEachStatement *node) +{ + out << "for (var "; + accept(node->declaration); + out << " in "; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::LocalForEachStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ContinueStatement *node) +{ + out << "continue"; + if (node->label) { + out << " " << JavaScriptEnginePrivate::toString(node->label); + } + out << ";"; + return false; +} + +void PrettyPretty::endVisit(AST::ContinueStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::BreakStatement *node) +{ + out << "break"; + if (node->label) { + out << " " << JavaScriptEnginePrivate::toString(node->label); + } + out << ";"; + return false; +} + +void PrettyPretty::endVisit(AST::BreakStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ReturnStatement *node) +{ + out << "return"; + if (node->expression) { + out << " "; + accept(node->expression); + } + out << ";"; + return false; +} + +void PrettyPretty::endVisit(AST::ReturnStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::WithStatement *node) +{ + out << "with ("; + accept(node->expression); + out << ") "; + acceptAsBlock(node->statement); + return false; +} + +void PrettyPretty::endVisit(AST::WithStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::SwitchStatement *node) +{ + out << "switch ("; + accept(node->expression); + out << ") "; + acceptAsBlock(node->block); + return false; +} + +void PrettyPretty::endVisit(AST::SwitchStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::CaseBlock *node) +{ + accept(node->clauses); + if (node->defaultClause) { + newlineAndIndent(); + accept(node->defaultClause); + } + if (node->moreClauses) { + newlineAndIndent(); + accept(node->moreClauses); + } + return false; +} + +void PrettyPretty::endVisit(AST::CaseBlock *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::CaseClauses *node) +{ + accept(node->clause); + for (node = node->next; node != 0; node = node->next) { + newlineAndIndent(); + accept(node->clause); + } + return false; +} + +void PrettyPretty::endVisit(AST::CaseClauses *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::CaseClause *node) +{ + out << "case "; + accept(node->expression); + out << ":"; + if (node->statements) { + newlineAndIndent(); + accept(node->statements); + } + return false; +} + +void PrettyPretty::endVisit(AST::CaseClause *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::DefaultClause *node) +{ + Q_UNUSED(node); + out << "default:"; + newlineAndIndent(); + return true; +} + +void PrettyPretty::endVisit(AST::DefaultClause *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::LabelledStatement *node) +{ + out << JavaScriptEnginePrivate::toString(node->label) << ": "; + return true; +} + +void PrettyPretty::endVisit(AST::LabelledStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::ThrowStatement *node) +{ + Q_UNUSED(node); + out << "throw "; + accept(node->expression); + out << ";"; + return false; +} + +void PrettyPretty::endVisit(AST::ThrowStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::TryStatement *node) +{ + out << "try "; + acceptAsBlock(node->statement); + if (node->catchExpression) { + out << " catch (" << JavaScriptEnginePrivate::toString(node->catchExpression->name) << ") "; + acceptAsBlock(node->catchExpression->statement); + } + if (node->finallyExpression) { + out << " finally "; + acceptAsBlock(node->finallyExpression->statement); + } + return false; +} + +void PrettyPretty::endVisit(AST::TryStatement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Catch *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::Catch *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Finally *node) +{ + Q_UNUSED(node); + out << "finally "; + return true; +} + +void PrettyPretty::endVisit(AST::Finally *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FunctionDeclaration *node) +{ + out << "function"; + + if (node->name) + out << " " << JavaScriptEnginePrivate::toString(node->name); + + // the arguments + out << "("; + for (AST::FormalParameterList *it = node->formals; it; it = it->next) { + if (it->name) + out << JavaScriptEnginePrivate::toString(it->name); + + if (it->next) + out << ", "; + } + out << ")"; + + // the function body + out << " {"; + + if (node->body) { + pushIndentLevel(); + newlineAndIndent(); + accept(node->body); + popIndentLevel(); + newlineAndIndent(); + } + + out << "}"; + + return false; +} + +void PrettyPretty::endVisit(AST::FunctionDeclaration *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FunctionExpression *node) +{ + out << "function"; + + if (node->name) + out << " " << JavaScriptEnginePrivate::toString(node->name); + + // the arguments + out << "("; + for (AST::FormalParameterList *it = node->formals; it; it = it->next) { + if (it->name) + out << JavaScriptEnginePrivate::toString(it->name); + + if (it->next) + out << ", "; + } + out << ")"; + + // the function body + out << " {"; + + if (node->body) { + pushIndentLevel(); + newlineAndIndent(); + accept(node->body); + popIndentLevel(); + newlineAndIndent(); + } + + out << "}"; + + return false; +} + +void PrettyPretty::endVisit(AST::FunctionExpression *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FormalParameterList *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::FormalParameterList *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FunctionBody *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::FunctionBody *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::Program *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::Program *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::SourceElements *node) +{ + Q_UNUSED(node); + accept(node->element); + for (node = node->next; node != 0; node = node->next) { + newlineAndIndent(); + accept(node->element); + } + return false; +} + +void PrettyPretty::endVisit(AST::SourceElements *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::FunctionSourceElement *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::FunctionSourceElement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::StatementSourceElement *node) +{ + Q_UNUSED(node); + return true; +} + +void PrettyPretty::endVisit(AST::StatementSourceElement *node) +{ + Q_UNUSED(node); +} + +bool PrettyPretty::visit(AST::DebuggerStatement *node) +{ + Q_UNUSED(node); + out << "debugger"; + return true; +} + +void PrettyPretty::endVisit(AST::DebuggerStatement *node) +{ + Q_UNUSED(node); + out << ";"; +} + +bool PrettyPretty::preVisit(AST::Node *node) +{ + Q_UNUSED(node); + return true; +} + +QT_END_NAMESPACE + + diff --git a/src/declarative/qml/parser/javascriptprettypretty_p.h b/src/declarative/qml/parser/javascriptprettypretty_p.h new file mode 100644 index 0000000..c692da5 --- /dev/null +++ b/src/declarative/qml/parser/javascriptprettypretty_p.h @@ -0,0 +1,329 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtScript module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef JAVASCRIPTPRETTYPRETTY_P_H +#define JAVASCRIPTPRETTYPRETTY_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> + +#include "javascriptastvisitor_p.h" + +QT_BEGIN_NAMESPACE + +class QTextStream; + +namespace JavaScript { + +class PrettyPretty: protected AST::Visitor +{ +public: + PrettyPretty(QTextStream &out); + virtual ~PrettyPretty(); + + QTextStream &operator () (AST::Node *node, int level = 0); + +protected: + void accept(AST::Node *node); + + virtual bool preVisit(AST::Node *node); + + virtual bool visit(AST::ThisExpression *node); + virtual void endVisit(AST::ThisExpression *node); + + virtual bool visit(AST::IdentifierExpression *node); + virtual void endVisit(AST::IdentifierExpression *node); + + virtual bool visit(AST::NullExpression *node); + virtual void endVisit(AST::NullExpression *node); + + virtual bool visit(AST::TrueLiteral *node); + virtual void endVisit(AST::TrueLiteral *node); + + virtual bool visit(AST::FalseLiteral *node); + virtual void endVisit(AST::FalseLiteral *node); + + virtual bool visit(AST::StringLiteral *node); + virtual void endVisit(AST::StringLiteral *node); + + virtual bool visit(AST::NumericLiteral *node); + virtual void endVisit(AST::NumericLiteral *node); + + virtual bool visit(AST::RegExpLiteral *node); + virtual void endVisit(AST::RegExpLiteral *node); + + virtual bool visit(AST::ArrayLiteral *node); + virtual void endVisit(AST::ArrayLiteral *node); + + virtual bool visit(AST::ObjectLiteral *node); + virtual void endVisit(AST::ObjectLiteral *node); + + virtual bool visit(AST::ElementList *node); + virtual void endVisit(AST::ElementList *node); + + virtual bool visit(AST::Elision *node); + virtual void endVisit(AST::Elision *node); + + virtual bool visit(AST::PropertyNameAndValueList *node); + virtual void endVisit(AST::PropertyNameAndValueList *node); + + virtual bool visit(AST::IdentifierPropertyName *node); + virtual void endVisit(AST::IdentifierPropertyName *node); + + virtual bool visit(AST::StringLiteralPropertyName *node); + virtual void endVisit(AST::StringLiteralPropertyName *node); + + virtual bool visit(AST::NumericLiteralPropertyName *node); + virtual void endVisit(AST::NumericLiteralPropertyName *node); + + virtual bool visit(AST::ArrayMemberExpression *node); + virtual void endVisit(AST::ArrayMemberExpression *node); + + virtual bool visit(AST::FieldMemberExpression *node); + virtual void endVisit(AST::FieldMemberExpression *node); + + virtual bool visit(AST::NewMemberExpression *node); + virtual void endVisit(AST::NewMemberExpression *node); + + virtual bool visit(AST::NewExpression *node); + virtual void endVisit(AST::NewExpression *node); + + virtual bool visit(AST::CallExpression *node); + virtual void endVisit(AST::CallExpression *node); + + virtual bool visit(AST::ArgumentList *node); + virtual void endVisit(AST::ArgumentList *node); + + virtual bool visit(AST::PostIncrementExpression *node); + virtual void endVisit(AST::PostIncrementExpression *node); + + virtual bool visit(AST::PostDecrementExpression *node); + virtual void endVisit(AST::PostDecrementExpression *node); + + virtual bool visit(AST::DeleteExpression *node); + virtual void endVisit(AST::DeleteExpression *node); + + virtual bool visit(AST::VoidExpression *node); + virtual void endVisit(AST::VoidExpression *node); + + virtual bool visit(AST::TypeOfExpression *node); + virtual void endVisit(AST::TypeOfExpression *node); + + virtual bool visit(AST::PreIncrementExpression *node); + virtual void endVisit(AST::PreIncrementExpression *node); + + virtual bool visit(AST::PreDecrementExpression *node); + virtual void endVisit(AST::PreDecrementExpression *node); + + virtual bool visit(AST::UnaryPlusExpression *node); + virtual void endVisit(AST::UnaryPlusExpression *node); + + virtual bool visit(AST::UnaryMinusExpression *node); + virtual void endVisit(AST::UnaryMinusExpression *node); + + virtual bool visit(AST::TildeExpression *node); + virtual void endVisit(AST::TildeExpression *node); + + virtual bool visit(AST::NotExpression *node); + virtual void endVisit(AST::NotExpression *node); + + virtual bool visit(AST::BinaryExpression *node); + virtual void endVisit(AST::BinaryExpression *node); + + virtual bool visit(AST::ConditionalExpression *node); + virtual void endVisit(AST::ConditionalExpression *node); + + virtual bool visit(AST::Expression *node); + virtual void endVisit(AST::Expression *node); + + virtual bool visit(AST::Block *node); + virtual void endVisit(AST::Block *node); + + virtual bool visit(AST::StatementList *node); + virtual void endVisit(AST::StatementList *node); + + virtual bool visit(AST::VariableStatement *node); + virtual void endVisit(AST::VariableStatement *node); + + virtual bool visit(AST::VariableDeclarationList *node); + virtual void endVisit(AST::VariableDeclarationList *node); + + virtual bool visit(AST::VariableDeclaration *node); + virtual void endVisit(AST::VariableDeclaration *node); + + virtual bool visit(AST::EmptyStatement *node); + virtual void endVisit(AST::EmptyStatement *node); + + virtual bool visit(AST::ExpressionStatement *node); + virtual void endVisit(AST::ExpressionStatement *node); + + virtual bool visit(AST::IfStatement *node); + virtual void endVisit(AST::IfStatement *node); + + virtual bool visit(AST::DoWhileStatement *node); + virtual void endVisit(AST::DoWhileStatement *node); + + virtual bool visit(AST::WhileStatement *node); + virtual void endVisit(AST::WhileStatement *node); + + virtual bool visit(AST::ForStatement *node); + virtual void endVisit(AST::ForStatement *node); + + virtual bool visit(AST::LocalForStatement *node); + virtual void endVisit(AST::LocalForStatement *node); + + virtual bool visit(AST::ForEachStatement *node); + virtual void endVisit(AST::ForEachStatement *node); + + virtual bool visit(AST::LocalForEachStatement *node); + virtual void endVisit(AST::LocalForEachStatement *node); + + virtual bool visit(AST::ContinueStatement *node); + virtual void endVisit(AST::ContinueStatement *node); + + virtual bool visit(AST::BreakStatement *node); + virtual void endVisit(AST::BreakStatement *node); + + virtual bool visit(AST::ReturnStatement *node); + virtual void endVisit(AST::ReturnStatement *node); + + virtual bool visit(AST::WithStatement *node); + virtual void endVisit(AST::WithStatement *node); + + virtual bool visit(AST::SwitchStatement *node); + virtual void endVisit(AST::SwitchStatement *node); + + virtual bool visit(AST::CaseBlock *node); + virtual void endVisit(AST::CaseBlock *node); + + virtual bool visit(AST::CaseClauses *node); + virtual void endVisit(AST::CaseClauses *node); + + virtual bool visit(AST::CaseClause *node); + virtual void endVisit(AST::CaseClause *node); + + virtual bool visit(AST::DefaultClause *node); + virtual void endVisit(AST::DefaultClause *node); + + virtual bool visit(AST::LabelledStatement *node); + virtual void endVisit(AST::LabelledStatement *node); + + virtual bool visit(AST::ThrowStatement *node); + virtual void endVisit(AST::ThrowStatement *node); + + virtual bool visit(AST::TryStatement *node); + virtual void endVisit(AST::TryStatement *node); + + virtual bool visit(AST::Catch *node); + virtual void endVisit(AST::Catch *node); + + virtual bool visit(AST::Finally *node); + virtual void endVisit(AST::Finally *node); + + virtual bool visit(AST::FunctionDeclaration *node); + virtual void endVisit(AST::FunctionDeclaration *node); + + virtual bool visit(AST::FunctionExpression *node); + virtual void endVisit(AST::FunctionExpression *node); + + virtual bool visit(AST::FormalParameterList *node); + virtual void endVisit(AST::FormalParameterList *node); + + virtual bool visit(AST::FunctionBody *node); + virtual void endVisit(AST::FunctionBody *node); + + virtual bool visit(AST::Program *node); + virtual void endVisit(AST::Program *node); + + virtual bool visit(AST::SourceElements *node); + virtual void endVisit(AST::SourceElements *node); + + virtual bool visit(AST::FunctionSourceElement *node); + virtual void endVisit(AST::FunctionSourceElement *node); + + virtual bool visit(AST::StatementSourceElement *node); + virtual void endVisit(AST::StatementSourceElement *node); + + virtual bool visit(AST::DebuggerStatement *node); + virtual void endVisit(AST::DebuggerStatement *node); + + int indentLevel(int level) + { + int was = m_indentLevel; + m_indentLevel = level; + return was; + } + + void pushIndentLevel() + { ++m_indentLevel; } + + void popIndentLevel() + { --m_indentLevel; } + + QTextStream &newlineAndIndent(); + + void acceptAsBlock(AST::Node *node); + + static int operatorPrecedenceLevel(int op); + static int compareOperatorPrecedence(int op1, int op2); + +private: + QTextStream &out; + int m_indentLevel; + + Q_DISABLE_COPY(PrettyPretty) +}; + +} // namespace JavaScript + +QT_END_NAMESPACE + +#endif diff --git a/src/declarative/qml/parser/javascriptvalue.h b/src/declarative/qml/parser/javascriptvalue.h new file mode 100644 index 0000000..c68b817 --- /dev/null +++ b/src/declarative/qml/parser/javascriptvalue.h @@ -0,0 +1,6 @@ +#ifndef JAVASCRIPTVALUE_H +#define JAVASCRIPTVALUE_H + +typedef double qjsreal; + +#endif // JAVASCRIPTVALUE_H diff --git a/src/declarative/qml/parser/parser.pri b/src/declarative/qml/parser/parser.pri new file mode 100644 index 0000000..130aeaf --- /dev/null +++ b/src/declarative/qml/parser/parser.pri @@ -0,0 +1,21 @@ + +HEADERS += $$PWD/javascriptast_p.h \ + $$PWD/javascriptastfwd_p.h \ + $$PWD/javascriptastvisitor_p.h \ + $$PWD/javascriptengine_p.h \ + $$PWD/javascriptgrammar_p.h \ + $$PWD/javascriptlexer_p.h \ + $$PWD/javascriptmemorypool_p.h \ + $$PWD/javascriptnodepool_p.h \ + $$PWD/javascriptparser_p.h \ + $$PWD/javascriptprettypretty_p.h \ + $$PWD/javascriptvalue.h \ + +SOURCES += $$PWD/javascriptast.cpp \ + $$PWD/javascriptastvisitor.cpp \ + $$PWD/javascriptengine_p.cpp \ + $$PWD/javascriptgrammar.cpp \ + $$PWD/javascriptlexer.cpp \ + $$PWD/javascriptprettypretty.cpp \ + $$PWD/javascriptparser.cpp + diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 65e6763..523a31b 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -61,3 +61,10 @@ HEADERS += qml/qmlparser_p.h \ # for qtscript debugger QT += scripttools include(script/script.pri) + +# new language front-end +include(parser/parser.pri) + +HEADERS += qml/qmlscriptparser_p.h + +SOURCES += qml/qmlscriptparser.cpp diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index f03ce20..e1a88bb 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -60,6 +60,8 @@ #include <qmlmetatype.h> #include <QtCore/qdebug.h> +#include "qmlscriptparser_p.h" + QT_BEGIN_NAMESPACE /* New properties and signals can be added to any QObject type from QML. diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 754e284..79d788e 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -51,6 +51,7 @@ class QStringList; QT_BEGIN_NAMESPACE class QmlXmlParser; +class QmlScriptParser; class QmlEngine; class QmlComponent; class QmlCompiledComponent; diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp index 83d500c..590f23f 100644 --- a/src/declarative/qml/qmlcomponent.cpp +++ b/src/declarative/qml/qmlcomponent.cpp @@ -56,6 +56,7 @@ #include <QtCore/qdebug.h> #include <QApplication> +#include "qmlscriptparser_p.h" QT_BEGIN_NAMESPACE class QByteArray; diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 274b542..0fe9111 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -47,6 +47,8 @@ #include <QtCore/qbytearray.h> #include <QtCore/qstring.h> +#include "qmlscriptparser_p.h" + QT_BEGIN_NAMESPACE QmlDomDocumentPrivate::QmlDomDocumentPrivate() @@ -150,7 +152,11 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data) { d->error = QString(); - QmlXmlParser parser; +#ifdef QML_WITH_XML_PARSER + QmlXmlParser parser; +#else + QmlScriptParser parser; +#endif if(!parser.parse(data)) { d->error = parser.errorDescription(); return false; |