The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / preparser.h @ f230a1cf

History | View | Annotate | Download (23.1 KB)

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