• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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