1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #ifndef V8_PREPARSER_H 29 #define V8_PREPARSER_H 30 31 #include "hashmap.h" 32 #include "token.h" 33 #include "scanner.h" 34 35 namespace v8 { 36 namespace internal { 37 38 // Common base class shared between parser and pre-parser. 39 class ParserBase { 40 public: ParserBase(Scanner * scanner,uintptr_t stack_limit)41 ParserBase(Scanner* scanner, uintptr_t stack_limit) 42 : scanner_(scanner), 43 stack_limit_(stack_limit), 44 stack_overflow_(false), 45 allow_lazy_(false), 46 allow_natives_syntax_(false), 47 allow_generators_(false), 48 allow_for_of_(false) { } 49 // TODO(mstarzinger): Only virtual until message reporting has been unified. ~ParserBase()50 virtual ~ParserBase() { } 51 52 // Getters that indicate whether certain syntactical constructs are 53 // allowed to be parsed by this instance of the parser. allow_lazy()54 bool allow_lazy() const { return allow_lazy_; } allow_natives_syntax()55 bool allow_natives_syntax() const { return allow_natives_syntax_; } allow_generators()56 bool allow_generators() const { return allow_generators_; } allow_for_of()57 bool allow_for_of() const { return allow_for_of_; } allow_modules()58 bool allow_modules() const { return scanner()->HarmonyModules(); } allow_harmony_scoping()59 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } allow_harmony_numeric_literals()60 bool allow_harmony_numeric_literals() const { 61 return scanner()->HarmonyNumericLiterals(); 62 } 63 64 // Setters that determine whether certain syntactical constructs are 65 // allowed to be parsed by this instance of the parser. set_allow_lazy(bool allow)66 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } set_allow_natives_syntax(bool allow)67 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } set_allow_generators(bool allow)68 void set_allow_generators(bool allow) { allow_generators_ = allow; } set_allow_for_of(bool allow)69 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } set_allow_modules(bool allow)70 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } set_allow_harmony_scoping(bool allow)71 void set_allow_harmony_scoping(bool allow) { 72 scanner()->SetHarmonyScoping(allow); 73 } set_allow_harmony_numeric_literals(bool allow)74 void set_allow_harmony_numeric_literals(bool allow) { 75 scanner()->SetHarmonyNumericLiterals(allow); 76 } 77 78 protected: scanner()79 Scanner* scanner() const { return scanner_; } position()80 int position() { return scanner_->location().beg_pos; } peek_position()81 int peek_position() { return scanner_->peek_location().beg_pos; } stack_overflow()82 bool stack_overflow() const { return stack_overflow_; } set_stack_overflow()83 void set_stack_overflow() { stack_overflow_ = true; } 84 INLINE(Token::Value peek ())85 INLINE(Token::Value peek()) { 86 if (stack_overflow_) return Token::ILLEGAL; 87 return scanner()->peek(); 88 } 89 INLINE(Token::Value Next ())90 INLINE(Token::Value Next()) { 91 if (stack_overflow_) return Token::ILLEGAL; 92 { 93 int marker; 94 if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) { 95 // Any further calls to Next or peek will return the illegal token. 96 // The current call must return the next token, which might already 97 // have been peek'ed. 98 stack_overflow_ = true; 99 } 100 } 101 return scanner()->Next(); 102 } 103 Consume(Token::Value token)104 void Consume(Token::Value token) { 105 Token::Value next = Next(); 106 USE(next); 107 USE(token); 108 ASSERT(next == token); 109 } 110 Check(Token::Value token)111 bool Check(Token::Value token) { 112 Token::Value next = peek(); 113 if (next == token) { 114 Consume(next); 115 return true; 116 } 117 return false; 118 } 119 Expect(Token::Value token,bool * ok)120 void Expect(Token::Value token, bool* ok) { 121 Token::Value next = Next(); 122 if (next != token) { 123 ReportUnexpectedToken(next); 124 *ok = false; 125 } 126 } 127 128 bool peek_any_identifier(); 129 void ExpectSemicolon(bool* ok); 130 bool CheckContextualKeyword(Vector<const char> keyword); 131 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); 132 133 // Strict mode octal literal validation. 134 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); 135 136 // Determine precedence of given token. 137 static int Precedence(Token::Value token, bool accept_IN); 138 139 // Report syntax errors. 140 virtual void ReportUnexpectedToken(Token::Value token) = 0; 141 virtual void ReportMessageAt(Scanner::Location loc, const char* type) = 0; 142 143 // Used to detect duplicates in object literals. Each of the values 144 // kGetterProperty, kSetterProperty and kValueProperty represents 145 // a type of object literal property. When parsing a property, its 146 // type value is stored in the DuplicateFinder for the property name. 147 // Values are chosen so that having intersection bits means the there is 148 // an incompatibility. 149 // I.e., you can add a getter to a property that already has a setter, since 150 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 151 // already has a getter or a value. Adding the getter to an existing 152 // setter will store the value (kGetterProperty | kSetterProperty), which 153 // is incompatible with adding any further properties. 154 enum PropertyKind { 155 kNone = 0, 156 // Bit patterns representing different object literal property types. 157 kGetterProperty = 1, 158 kSetterProperty = 2, 159 kValueProperty = 7, 160 // Helper constants. 161 kValueFlag = 4 162 }; 163 164 // Validation per ECMA 262 - 11.1.5 "Object Initialiser". 165 class ObjectLiteralChecker { 166 public: ObjectLiteralChecker(ParserBase * parser,LanguageMode mode)167 ObjectLiteralChecker(ParserBase* parser, LanguageMode mode) 168 : parser_(parser), 169 finder_(scanner()->unicode_cache()), 170 language_mode_(mode) { } 171 172 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); 173 174 private: parser()175 ParserBase* parser() const { return parser_; } scanner()176 Scanner* scanner() const { return parser_->scanner(); } 177 178 // Checks the type of conflict based on values coming from PropertyType. HasConflict(PropertyKind type1,PropertyKind type2)179 bool HasConflict(PropertyKind type1, PropertyKind type2) { 180 return (type1 & type2) != 0; 181 } IsDataDataConflict(PropertyKind type1,PropertyKind type2)182 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { 183 return ((type1 & type2) & kValueFlag) != 0; 184 } IsDataAccessorConflict(PropertyKind type1,PropertyKind type2)185 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { 186 return ((type1 ^ type2) & kValueFlag) != 0; 187 } IsAccessorAccessorConflict(PropertyKind type1,PropertyKind type2)188 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { 189 return ((type1 | type2) & kValueFlag) == 0; 190 } 191 192 ParserBase* parser_; 193 DuplicateFinder finder_; 194 LanguageMode language_mode_; 195 }; 196 197 private: 198 Scanner* scanner_; 199 uintptr_t stack_limit_; 200 bool stack_overflow_; 201 202 bool allow_lazy_; 203 bool allow_natives_syntax_; 204 bool allow_generators_; 205 bool allow_for_of_; 206 }; 207 208 209 // Preparsing checks a JavaScript program and emits preparse-data that helps 210 // a later parsing to be faster. 211 // See preparse-data-format.h for the data format. 212 213 // The PreParser checks that the syntax follows the grammar for JavaScript, 214 // and collects some information about the program along the way. 215 // The grammar check is only performed in order to understand the program 216 // sufficiently to deduce some information about it, that can be used 217 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 218 // rather it is to speed up properly written and correct programs. 219 // That means that contextual checks (like a label being declared where 220 // it is used) are generally omitted. 221 class PreParser : public ParserBase { 222 public: 223 enum PreParseResult { 224 kPreParseStackOverflow, 225 kPreParseSuccess 226 }; 227 PreParser(Scanner * scanner,ParserRecorder * log,uintptr_t stack_limit)228 PreParser(Scanner* scanner, 229 ParserRecorder* log, 230 uintptr_t stack_limit) 231 : ParserBase(scanner, stack_limit), 232 log_(log), 233 scope_(NULL), 234 strict_mode_violation_location_(Scanner::Location::invalid()), 235 strict_mode_violation_type_(NULL), 236 parenthesized_function_(false) { } 237 ~PreParser()238 ~PreParser() {} 239 240 // Pre-parse the program from the character stream; returns true on 241 // success (even if parsing failed, the pre-parse data successfully 242 // captured the syntax error), and false if a stack-overflow happened 243 // during parsing. PreParseProgram()244 PreParseResult PreParseProgram() { 245 Scope top_scope(&scope_, kTopLevelScope); 246 bool ok = true; 247 int start_position = scanner()->peek_location().beg_pos; 248 ParseSourceElements(Token::EOS, &ok); 249 if (stack_overflow()) return kPreParseStackOverflow; 250 if (!ok) { 251 ReportUnexpectedToken(scanner()->current_token()); 252 } else if (!scope_->is_classic_mode()) { 253 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 254 } 255 return kPreParseSuccess; 256 } 257 258 // Parses a single function literal, from the opening parentheses before 259 // parameters to the closing brace after the body. 260 // Returns a FunctionEntry describing the body of the function in enough 261 // detail that it can be lazily compiled. 262 // The scanner is expected to have matched the "function" or "function*" 263 // keyword and parameters, and have consumed the initial '{'. 264 // At return, unless an error occurred, the scanner is positioned before the 265 // the final '}'. 266 PreParseResult PreParseLazyFunction(LanguageMode mode, 267 bool is_generator, 268 ParserRecorder* log); 269 270 private: 271 // These types form an algebra over syntactic categories that is just 272 // rich enough to let us recognize and propagate the constructs that 273 // are either being counted in the preparser data, or is important 274 // to throw the correct syntax error exceptions. 275 276 enum ScopeType { 277 kTopLevelScope, 278 kFunctionScope 279 }; 280 281 enum VariableDeclarationContext { 282 kSourceElement, 283 kStatement, 284 kForStatement 285 }; 286 287 // If a list of variable declarations includes any initializers. 288 enum VariableDeclarationProperties { 289 kHasInitializers, 290 kHasNoInitializers 291 }; 292 293 class Expression; 294 295 class Identifier { 296 public: Default()297 static Identifier Default() { 298 return Identifier(kUnknownIdentifier); 299 } Eval()300 static Identifier Eval() { 301 return Identifier(kEvalIdentifier); 302 } Arguments()303 static Identifier Arguments() { 304 return Identifier(kArgumentsIdentifier); 305 } FutureReserved()306 static Identifier FutureReserved() { 307 return Identifier(kFutureReservedIdentifier); 308 } FutureStrictReserved()309 static Identifier FutureStrictReserved() { 310 return Identifier(kFutureStrictReservedIdentifier); 311 } Yield()312 static Identifier Yield() { 313 return Identifier(kYieldIdentifier); 314 } IsEval()315 bool IsEval() { return type_ == kEvalIdentifier; } IsArguments()316 bool IsArguments() { return type_ == kArgumentsIdentifier; } IsEvalOrArguments()317 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } IsYield()318 bool IsYield() { return type_ == kYieldIdentifier; } IsFutureReserved()319 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } IsFutureStrictReserved()320 bool IsFutureStrictReserved() { 321 return type_ == kFutureStrictReservedIdentifier; 322 } IsValidStrictVariable()323 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 324 325 private: 326 enum Type { 327 kUnknownIdentifier, 328 kFutureReservedIdentifier, 329 kFutureStrictReservedIdentifier, 330 kYieldIdentifier, 331 kEvalIdentifier, 332 kArgumentsIdentifier 333 }; Identifier(Type type)334 explicit Identifier(Type type) : type_(type) { } 335 Type type_; 336 337 friend class Expression; 338 }; 339 340 // Bits 0 and 1 are used to identify the type of expression: 341 // If bit 0 is set, it's an identifier. 342 // if bit 1 is set, it's a string literal. 343 // If neither is set, it's no particular type, and both set isn't 344 // use yet. 345 // Bit 2 is used to mark the expression as being parenthesized, 346 // so "(foo)" isn't recognized as a pure identifier (and possible label). 347 class Expression { 348 public: Default()349 static Expression Default() { 350 return Expression(kUnknownExpression); 351 } 352 FromIdentifier(Identifier id)353 static Expression FromIdentifier(Identifier id) { 354 return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift)); 355 } 356 StringLiteral()357 static Expression StringLiteral() { 358 return Expression(kUnknownStringLiteral); 359 } 360 UseStrictStringLiteral()361 static Expression UseStrictStringLiteral() { 362 return Expression(kUseStrictString); 363 } 364 This()365 static Expression This() { 366 return Expression(kThisExpression); 367 } 368 ThisProperty()369 static Expression ThisProperty() { 370 return Expression(kThisPropertyExpression); 371 } 372 StrictFunction()373 static Expression StrictFunction() { 374 return Expression(kStrictFunctionExpression); 375 } 376 IsIdentifier()377 bool IsIdentifier() { 378 return (code_ & kIdentifierFlag) != 0; 379 } 380 381 // Only works corretly if it is actually an identifier expression. AsIdentifier()382 PreParser::Identifier AsIdentifier() { 383 return PreParser::Identifier( 384 static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift)); 385 } 386 IsParenthesized()387 bool IsParenthesized() { 388 // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized. 389 return (code_ & 7) > 4; 390 } 391 IsRawIdentifier()392 bool IsRawIdentifier() { 393 return !IsParenthesized() && IsIdentifier(); 394 } 395 IsStringLiteral()396 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 397 IsRawStringLiteral()398 bool IsRawStringLiteral() { 399 return !IsParenthesized() && IsStringLiteral(); 400 } 401 IsUseStrictLiteral()402 bool IsUseStrictLiteral() { 403 return (code_ & kStringLiteralMask) == kUseStrictString; 404 } 405 IsThis()406 bool IsThis() { 407 return code_ == kThisExpression; 408 } 409 IsThisProperty()410 bool IsThisProperty() { 411 return code_ == kThisPropertyExpression; 412 } 413 IsStrictFunction()414 bool IsStrictFunction() { 415 return code_ == kStrictFunctionExpression; 416 } 417 Parenthesize()418 Expression Parenthesize() { 419 int type = code_ & 3; 420 if (type != 0) { 421 // Identifiers and string literals can be parenthesized. 422 // They no longer work as labels or directive prologues, 423 // but are still recognized in other contexts. 424 return Expression(code_ | kParenthesizedExpressionFlag); 425 } 426 // For other types of expressions, it's not important to remember 427 // the parentheses. 428 return *this; 429 } 430 431 private: 432 // First two/three bits are used as flags. 433 // Bit 0 and 1 represent identifiers or strings literals, and are 434 // mutually exclusive, but can both be absent. 435 // If bit 0 or 1 are set, bit 2 marks that the expression has 436 // been wrapped in parentheses (a string literal can no longer 437 // be a directive prologue, and an identifier can no longer be 438 // a label. 439 enum { 440 kUnknownExpression = 0, 441 // Identifiers 442 kIdentifierFlag = 1, // Used to detect labels. 443 kIdentifierShift = 3, 444 445 kStringLiteralFlag = 2, // Used to detect directive prologue. 446 kUnknownStringLiteral = kStringLiteralFlag, 447 kUseStrictString = kStringLiteralFlag | 8, 448 kStringLiteralMask = kUseStrictString, 449 450 // Only if identifier or string literal. 451 kParenthesizedExpressionFlag = 4, 452 453 // Below here applies if neither identifier nor string literal. 454 kThisExpression = 4, 455 kThisPropertyExpression = 8, 456 kStrictFunctionExpression = 12 457 }; 458 Expression(int expression_code)459 explicit Expression(int expression_code) : code_(expression_code) { } 460 461 int code_; 462 }; 463 464 class Statement { 465 public: Default()466 static Statement Default() { 467 return Statement(kUnknownStatement); 468 } 469 FunctionDeclaration()470 static Statement FunctionDeclaration() { 471 return Statement(kFunctionDeclaration); 472 } 473 474 // Creates expression statement from expression. 475 // Preserves being an unparenthesized string literal, possibly 476 // "use strict". ExpressionStatement(Expression expression)477 static Statement ExpressionStatement(Expression expression) { 478 if (!expression.IsParenthesized()) { 479 if (expression.IsUseStrictLiteral()) { 480 return Statement(kUseStrictExpressionStatement); 481 } 482 if (expression.IsStringLiteral()) { 483 return Statement(kStringLiteralExpressionStatement); 484 } 485 } 486 return Default(); 487 } 488 IsStringLiteral()489 bool IsStringLiteral() { 490 return code_ == kStringLiteralExpressionStatement; 491 } 492 IsUseStrictLiteral()493 bool IsUseStrictLiteral() { 494 return code_ == kUseStrictExpressionStatement; 495 } 496 IsFunctionDeclaration()497 bool IsFunctionDeclaration() { 498 return code_ == kFunctionDeclaration; 499 } 500 501 private: 502 enum Type { 503 kUnknownStatement, 504 kStringLiteralExpressionStatement, 505 kUseStrictExpressionStatement, 506 kFunctionDeclaration 507 }; 508 Statement(Type code)509 explicit Statement(Type code) : code_(code) {} 510 Type code_; 511 }; 512 513 enum SourceElements { 514 kUnknownSourceElements 515 }; 516 517 typedef int Arguments; 518 519 class Scope { 520 public: Scope(Scope ** variable,ScopeType type)521 Scope(Scope** variable, ScopeType type) 522 : variable_(variable), 523 prev_(*variable), 524 type_(type), 525 materialized_literal_count_(0), 526 expected_properties_(0), 527 with_nesting_count_(0), 528 language_mode_( 529 (prev_ != NULL) ? prev_->language_mode() : CLASSIC_MODE), 530 is_generator_(false) { 531 *variable = this; 532 } ~Scope()533 ~Scope() { *variable_ = prev_; } NextMaterializedLiteralIndex()534 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } AddProperty()535 void AddProperty() { expected_properties_++; } type()536 ScopeType type() { return type_; } expected_properties()537 int expected_properties() { return expected_properties_; } materialized_literal_count()538 int materialized_literal_count() { return materialized_literal_count_; } IsInsideWith()539 bool IsInsideWith() { return with_nesting_count_ != 0; } is_generator()540 bool is_generator() { return is_generator_; } set_is_generator(bool is_generator)541 void set_is_generator(bool is_generator) { is_generator_ = is_generator; } is_classic_mode()542 bool is_classic_mode() { 543 return language_mode_ == CLASSIC_MODE; 544 } language_mode()545 LanguageMode language_mode() { 546 return language_mode_; 547 } set_language_mode(LanguageMode language_mode)548 void set_language_mode(LanguageMode language_mode) { 549 language_mode_ = language_mode; 550 } 551 552 class InsideWith { 553 public: InsideWith(Scope * scope)554 explicit InsideWith(Scope* scope) : scope_(scope) { 555 scope->with_nesting_count_++; 556 } 557 ~InsideWith()558 ~InsideWith() { scope_->with_nesting_count_--; } 559 560 private: 561 Scope* scope_; 562 DISALLOW_COPY_AND_ASSIGN(InsideWith); 563 }; 564 565 private: 566 Scope** const variable_; 567 Scope* const prev_; 568 const ScopeType type_; 569 int materialized_literal_count_; 570 int expected_properties_; 571 int with_nesting_count_; 572 LanguageMode language_mode_; 573 bool is_generator_; 574 }; 575 576 // Report syntax error 577 void ReportUnexpectedToken(Token::Value token); ReportMessageAt(Scanner::Location location,const char * type)578 void ReportMessageAt(Scanner::Location location, const char* type) { 579 ReportMessageAt(location, type, NULL); 580 } ReportMessageAt(Scanner::Location location,const char * type,const char * name_opt)581 void ReportMessageAt(Scanner::Location location, 582 const char* type, 583 const char* name_opt) { 584 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); 585 } ReportMessageAt(int start_pos,int end_pos,const char * type,const char * name_opt)586 void ReportMessageAt(int start_pos, 587 int end_pos, 588 const char* type, 589 const char* name_opt) { 590 log_->LogMessage(start_pos, end_pos, type, name_opt); 591 } 592 593 // All ParseXXX functions take as the last argument an *ok parameter 594 // which is set to false if parsing failed; it is unchanged otherwise. 595 // By making the 'exception handling' explicit, we are forced to check 596 // for failure at the call sites. 597 Statement ParseSourceElement(bool* ok); 598 SourceElements ParseSourceElements(int end_token, bool* ok); 599 Statement ParseStatement(bool* ok); 600 Statement ParseFunctionDeclaration(bool* ok); 601 Statement ParseBlock(bool* ok); 602 Statement ParseVariableStatement(VariableDeclarationContext var_context, 603 bool* ok); 604 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, 605 VariableDeclarationProperties* decl_props, 606 int* num_decl, 607 bool* ok); 608 Statement ParseExpressionOrLabelledStatement(bool* ok); 609 Statement ParseIfStatement(bool* ok); 610 Statement ParseContinueStatement(bool* ok); 611 Statement ParseBreakStatement(bool* ok); 612 Statement ParseReturnStatement(bool* ok); 613 Statement ParseWithStatement(bool* ok); 614 Statement ParseSwitchStatement(bool* ok); 615 Statement ParseDoWhileStatement(bool* ok); 616 Statement ParseWhileStatement(bool* ok); 617 Statement ParseForStatement(bool* ok); 618 Statement ParseThrowStatement(bool* ok); 619 Statement ParseTryStatement(bool* ok); 620 Statement ParseDebuggerStatement(bool* ok); 621 622 Expression ParseExpression(bool accept_IN, bool* ok); 623 Expression ParseAssignmentExpression(bool accept_IN, bool* ok); 624 Expression ParseYieldExpression(bool* ok); 625 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 626 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 627 Expression ParseUnaryExpression(bool* ok); 628 Expression ParsePostfixExpression(bool* ok); 629 Expression ParseLeftHandSideExpression(bool* ok); 630 Expression ParseNewExpression(bool* ok); 631 Expression ParseMemberExpression(bool* ok); 632 Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok); 633 Expression ParsePrimaryExpression(bool* ok); 634 Expression ParseArrayLiteral(bool* ok); 635 Expression ParseObjectLiteral(bool* ok); 636 Expression ParseRegExpLiteral(bool seen_equal, bool* ok); 637 Expression ParseV8Intrinsic(bool* ok); 638 639 Arguments ParseArguments(bool* ok); 640 Expression ParseFunctionLiteral(bool is_generator, bool* ok); 641 void ParseLazyFunctionLiteralBody(bool* ok); 642 643 Identifier ParseIdentifier(bool* ok); 644 Identifier ParseIdentifierName(bool* ok); 645 Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, 646 bool* is_set, 647 bool* ok); 648 649 // Logs the currently parsed literal as a symbol in the preparser data. 650 void LogSymbol(); 651 // Log the currently parsed identifier. 652 Identifier GetIdentifierSymbol(); 653 // Log the currently parsed string literal. 654 Expression GetStringSymbol(); 655 set_language_mode(LanguageMode language_mode)656 void set_language_mode(LanguageMode language_mode) { 657 scope_->set_language_mode(language_mode); 658 } 659 is_classic_mode()660 bool is_classic_mode() { 661 return scope_->language_mode() == CLASSIC_MODE; 662 } 663 is_extended_mode()664 bool is_extended_mode() { 665 return scope_->language_mode() == EXTENDED_MODE; 666 } 667 language_mode()668 LanguageMode language_mode() { return scope_->language_mode(); } 669 670 bool CheckInOrOf(bool accept_OF); 671 672 void SetStrictModeViolation(Scanner::Location, 673 const char* type, 674 bool* ok); 675 676 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); 677 678 void StrictModeIdentifierViolation(Scanner::Location, 679 const char* eval_args_type, 680 Identifier identifier, 681 bool* ok); 682 683 ParserRecorder* log_; 684 Scope* scope_; 685 Scanner::Location strict_mode_violation_location_; 686 const char* strict_mode_violation_type_; 687 bool parenthesized_function_; 688 }; 689 690 } } // v8::internal 691 692 #endif // V8_PREPARSER_H 693