Home | History | Annotate | Download | only in src
      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:
     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.
     50   virtual ~ParserBase() { }
     51 
     52   // Getters that indicate whether certain syntactical constructs are
     53   // allowed to be parsed by this instance of the parser.
     54   bool allow_lazy() const { return allow_lazy_; }
     55   bool allow_natives_syntax() const { return allow_natives_syntax_; }
     56   bool allow_generators() const { return allow_generators_; }
     57   bool allow_for_of() const { return allow_for_of_; }
     58   bool allow_modules() const { return scanner()->HarmonyModules(); }
     59   bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
     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.
     66   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
     67   void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
     68   void set_allow_generators(bool allow) { allow_generators_ = allow; }
     69   void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
     70   void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
     71   void set_allow_harmony_scoping(bool allow) {
     72     scanner()->SetHarmonyScoping(allow);
     73   }
     74   void set_allow_harmony_numeric_literals(bool allow) {
     75     scanner()->SetHarmonyNumericLiterals(allow);
     76   }
     77 
     78  protected:
     79   Scanner* scanner() const { return scanner_; }
     80   int position() { return scanner_->location().beg_pos; }
     81   int peek_position() { return scanner_->peek_location().beg_pos; }
     82   bool stack_overflow() const { return stack_overflow_; }
     83   void set_stack_overflow() { stack_overflow_ = true; }
     84 
     85   INLINE(Token::Value peek()) {
     86     if (stack_overflow_) return Token::ILLEGAL;
     87     return scanner()->peek();
     88   }
     89 
     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 
    104   void Consume(Token::Value token) {
    105     Token::Value next = Next();
    106     USE(next);
    107     USE(token);
    108     ASSERT(next == token);
    109   }
    110 
    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 
    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:
    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:
    175     ParserBase* parser() const { return parser_; }
    176     Scanner* scanner() const { return parser_->scanner(); }
    177 
    178     // Checks the type of conflict based on values coming from PropertyType.
    179     bool HasConflict(PropertyKind type1, PropertyKind type2) {
    180       return (type1 & type2) != 0;
    181     }
    182     bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
    183       return ((type1 & type2) & kValueFlag) != 0;
    184     }
    185     bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
    186       return ((type1 ^ type2) & kValueFlag) != 0;
    187     }
    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 
    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 
    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.
    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:
    297     static Identifier Default() {
    298       return Identifier(kUnknownIdentifier);
    299     }
    300     static Identifier Eval()  {
    301       return Identifier(kEvalIdentifier);
    302     }
    303     static Identifier Arguments()  {
    304       return Identifier(kArgumentsIdentifier);
    305     }
    306     static Identifier FutureReserved()  {
    307       return Identifier(kFutureReservedIdentifier);
    308     }
    309     static Identifier FutureStrictReserved()  {
    310       return Identifier(kFutureStrictReservedIdentifier);
    311     }
    312     static Identifier Yield()  {
    313       return Identifier(kYieldIdentifier);
    314     }
    315     bool IsEval() { return type_ == kEvalIdentifier; }
    316     bool IsArguments() { return type_ == kArgumentsIdentifier; }
    317     bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
    318     bool IsYield() { return type_ == kYieldIdentifier; }
    319     bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
    320     bool IsFutureStrictReserved() {
    321       return type_ == kFutureStrictReservedIdentifier;
    322     }
    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     };
    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:
    349     static Expression Default() {
    350       return Expression(kUnknownExpression);
    351     }
    352 
    353     static Expression FromIdentifier(Identifier id) {
    354       return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift));
    355     }
    356 
    357     static Expression StringLiteral() {
    358       return Expression(kUnknownStringLiteral);
    359     }
    360 
    361     static Expression UseStrictStringLiteral() {
    362       return Expression(kUseStrictString);
    363     }
    364 
    365     static Expression This() {
    366       return Expression(kThisExpression);
    367     }
    368 
    369     static Expression ThisProperty() {
    370       return Expression(kThisPropertyExpression);
    371     }
    372 
    373     static Expression StrictFunction() {
    374       return Expression(kStrictFunctionExpression);
    375     }
    376 
    377     bool IsIdentifier() {
    378       return (code_ & kIdentifierFlag) != 0;
    379     }
    380 
    381     // Only works corretly if it is actually an identifier expression.
    382     PreParser::Identifier AsIdentifier() {
    383       return PreParser::Identifier(
    384           static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift));
    385     }
    386 
    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 
    392     bool IsRawIdentifier() {
    393       return !IsParenthesized() && IsIdentifier();
    394     }
    395 
    396     bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
    397 
    398     bool IsRawStringLiteral() {
    399       return !IsParenthesized() && IsStringLiteral();
    400     }
    401 
    402     bool IsUseStrictLiteral() {
    403       return (code_ & kStringLiteralMask) == kUseStrictString;
    404     }
    405 
    406     bool IsThis() {
    407       return code_ == kThisExpression;
    408     }
    409 
    410     bool IsThisProperty() {
    411       return code_ == kThisPropertyExpression;
    412     }
    413 
    414     bool IsStrictFunction() {
    415       return code_ == kStrictFunctionExpression;
    416     }
    417 
    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 
    459     explicit Expression(int expression_code) : code_(expression_code) { }
    460 
    461     int code_;
    462   };
    463 
    464   class Statement {
    465    public:
    466     static Statement Default() {
    467       return Statement(kUnknownStatement);
    468     }
    469 
    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".
    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 
    489     bool IsStringLiteral() {
    490       return code_ == kStringLiteralExpressionStatement;
    491     }
    492 
    493     bool IsUseStrictLiteral() {
    494       return code_ == kUseStrictExpressionStatement;
    495     }
    496 
    497     bool IsFunctionDeclaration() {
    498       return code_ == kFunctionDeclaration;
    499     }
    500 
    501    private:
    502     enum Type {
    503       kUnknownStatement,
    504       kStringLiteralExpressionStatement,
    505       kUseStrictExpressionStatement,
    506       kFunctionDeclaration
    507     };
    508 
    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:
    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     }
    533     ~Scope() { *variable_ = prev_; }
    534     void NextMaterializedLiteralIndex() { materialized_literal_count_++; }
    535     void AddProperty() { expected_properties_++; }
    536     ScopeType type() { return type_; }
    537     int expected_properties() { return expected_properties_; }
    538     int materialized_literal_count() { return materialized_literal_count_; }
    539     bool IsInsideWith() { return with_nesting_count_ != 0; }
    540     bool is_generator() { return is_generator_; }
    541     void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
    542     bool is_classic_mode() {
    543       return language_mode_ == CLASSIC_MODE;
    544     }
    545     LanguageMode language_mode() {
    546       return language_mode_;
    547     }
    548     void set_language_mode(LanguageMode language_mode) {
    549       language_mode_ = language_mode;
    550     }
    551 
    552     class InsideWith {
    553      public:
    554       explicit InsideWith(Scope* scope) : scope_(scope) {
    555         scope->with_nesting_count_++;
    556       }
    557 
    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);
    578   void ReportMessageAt(Scanner::Location location, const char* type) {
    579     ReportMessageAt(location, type, NULL);
    580   }
    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   }
    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 
    656   void set_language_mode(LanguageMode language_mode) {
    657     scope_->set_language_mode(language_mode);
    658   }
    659 
    660   bool is_classic_mode() {
    661     return scope_->language_mode() == CLASSIC_MODE;
    662   }
    663 
    664   bool is_extended_mode() {
    665     return scope_->language_mode() == EXTENDED_MODE;
    666   }
    667 
    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