LCOV - code coverage report
Current view: top level - src/parsing - token.h (source / functions) Hit Total Coverage
Test: app.info Lines: 20 20 100.0 %
Date: 2019-02-19 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_PARSING_TOKEN_H_
       6             : #define V8_PARSING_TOKEN_H_
       7             : 
       8             : #include "src/base/logging.h"
       9             : #include "src/globals.h"
      10             : #include "src/utils.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : // TOKEN_LIST takes a list of 3 macros M, all of which satisfy the
      16             : // same signature M(name, string, precedence), where name is the
      17             : // symbolic token name, string is the corresponding syntactic symbol
      18             : // (or nullptr, for literals), and precedence is the precedence (or 0).
      19             : // The parameters are invoked for token categories as follows:
      20             : //
      21             : //   T: Non-keyword tokens
      22             : //   K: Keyword tokens
      23             : 
      24             : // IGNORE_TOKEN is a convenience macro that can be supplied as
      25             : // an argument (at any position) for a TOKEN_LIST call. It does
      26             : // nothing with tokens belonging to the respective category.
      27             : 
      28             : #define IGNORE_TOKEN(name, string, precedence)
      29             : 
      30             : /* Binary operators */
      31             : /* ADD and SUB are at the end since they are UnaryOp */
      32             : #define BINARY_OP_TOKEN_LIST(T, E) \
      33             :   E(T, BIT_OR, "|", 6)             \
      34             :   E(T, BIT_XOR, "^", 7)            \
      35             :   E(T, BIT_AND, "&", 8)            \
      36             :   E(T, SHL, "<<", 11)              \
      37             :   E(T, SAR, ">>", 11)              \
      38             :   E(T, SHR, ">>>", 11)             \
      39             :   E(T, MUL, "*", 13)               \
      40             :   E(T, DIV, "/", 13)               \
      41             :   E(T, MOD, "%", 13)               \
      42             :   E(T, EXP, "**", 14)              \
      43             :   E(T, ADD, "+", 12)               \
      44             :   E(T, SUB, "-", 12)
      45             : 
      46             : #define EXPAND_BINOP_ASSIGN_TOKEN(T, name, string, precedence) \
      47             :   T(ASSIGN_##name, string "=", 2)
      48             : 
      49             : #define EXPAND_BINOP_TOKEN(T, name, string, precedence) \
      50             :   T(name, string, precedence)
      51             : 
      52             : #define TOKEN_LIST(T, K)                                           \
      53             :                                                                    \
      54             :   /* BEGIN PropertyOrCall */                                       \
      55             :   /* BEGIN Member */                                               \
      56             :   /* BEGIN Template */                                             \
      57             :   /* ES6 Template Literals */                                      \
      58             :   T(TEMPLATE_SPAN, nullptr, 0)                                     \
      59             :   T(TEMPLATE_TAIL, nullptr, 0)                                     \
      60             :   /* END Template */                                               \
      61             :                                                                    \
      62             :   /* Punctuators (ECMA-262, section 7.7, page 15). */              \
      63             :   /* BEGIN Property */                                             \
      64             :   T(PERIOD, ".", 0)                                                \
      65             :   T(LBRACK, "[", 0)                                                \
      66             :   /* END Property */                                               \
      67             :   /* END Member */                                                 \
      68             :   T(LPAREN, "(", 0)                                                \
      69             :   /* END PropertyOrCall */                                         \
      70             :   T(RPAREN, ")", 0)                                                \
      71             :   T(RBRACK, "]", 0)                                                \
      72             :   T(LBRACE, "{", 0)                                                \
      73             :   T(COLON, ":", 0)                                                 \
      74             :   T(ELLIPSIS, "...", 0)                                            \
      75             :   T(CONDITIONAL, "?", 3)                                           \
      76             :   /* BEGIN AutoSemicolon */                                        \
      77             :   T(SEMICOLON, ";", 0)                                             \
      78             :   T(RBRACE, "}", 0)                                                \
      79             :   /* End of source indicator. */                                   \
      80             :   T(EOS, "EOS", 0)                                                 \
      81             :   /* END AutoSemicolon */                                          \
      82             :                                                                    \
      83             :   /* BEGIN ArrowOrAssignmentOp */                                  \
      84             :   T(ARROW, "=>", 0)                                                \
      85             :   /* BEGIN AssignmentOp */                                         \
      86             :   /* IsAssignmentOp() relies on this block of enum values being */ \
      87             :   /* contiguous and sorted in the same order! */                   \
      88             :   T(INIT, "=init", 2) /* AST-use only. */                          \
      89             :   T(ASSIGN, "=", 2)                                                \
      90             :   BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_ASSIGN_TOKEN)               \
      91             :   /* END AssignmentOp */                                           \
      92             :   /* END ArrowOrAssignmentOp */                                    \
      93             :                                                                    \
      94             :   /* Binary operators sorted by precedence. */                     \
      95             :   /* IsBinaryOp() relies on this block of enum values */           \
      96             :   /* being contiguous and sorted in the same order! */             \
      97             :   T(COMMA, ",", 1)                                                 \
      98             :   T(OR, "||", 4)                                                   \
      99             :   T(AND, "&&", 5)                                                  \
     100             :                                                                    \
     101             :   /* Unary operators, starting at ADD in BINARY_OP_TOKEN_LIST  */  \
     102             :   /* IsUnaryOp() relies on this block of enum values */            \
     103             :   /* being contiguous and sorted in the same order! */             \
     104             :   BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_TOKEN)                      \
     105             :                                                                    \
     106             :   T(NOT, "!", 0)                                                   \
     107             :   T(BIT_NOT, "~", 0)                                               \
     108             :   K(DELETE, "delete", 0)                                           \
     109             :   K(TYPEOF, "typeof", 0)                                           \
     110             :   K(VOID, "void", 0)                                               \
     111             :                                                                    \
     112             :   /* BEGIN IsCountOp */                                            \
     113             :   T(INC, "++", 0)                                                  \
     114             :   T(DEC, "--", 0)                                                  \
     115             :   /* END IsCountOp */                                              \
     116             :   /* END IsUnaryOrCountOp */                                       \
     117             :                                                                    \
     118             :   /* Compare operators sorted by precedence. */                    \
     119             :   /* IsCompareOp() relies on this block of enum values */          \
     120             :   /* being contiguous and sorted in the same order! */             \
     121             :   T(EQ, "==", 9)                                                   \
     122             :   T(EQ_STRICT, "===", 9)                                           \
     123             :   T(NE, "!=", 9)                                                   \
     124             :   T(NE_STRICT, "!==", 9)                                           \
     125             :   T(LT, "<", 10)                                                   \
     126             :   T(GT, ">", 10)                                                   \
     127             :   T(LTE, "<=", 10)                                                 \
     128             :   T(GTE, ">=", 10)                                                 \
     129             :   K(INSTANCEOF, "instanceof", 10)                                  \
     130             :   K(IN, "in", 10)                                                  \
     131             :                                                                    \
     132             :   /* Keywords (ECMA-262, section 7.5.2, page 13). */               \
     133             :   K(BREAK, "break", 0)                                             \
     134             :   K(CASE, "case", 0)                                               \
     135             :   K(CATCH, "catch", 0)                                             \
     136             :   K(CONTINUE, "continue", 0)                                       \
     137             :   K(DEBUGGER, "debugger", 0)                                       \
     138             :   K(DEFAULT, "default", 0)                                         \
     139             :   /* DELETE */                                                     \
     140             :   K(DO, "do", 0)                                                   \
     141             :   K(ELSE, "else", 0)                                               \
     142             :   K(FINALLY, "finally", 0)                                         \
     143             :   K(FOR, "for", 0)                                                 \
     144             :   K(FUNCTION, "function", 0)                                       \
     145             :   K(IF, "if", 0)                                                   \
     146             :   /* IN */                                                         \
     147             :   /* INSTANCEOF */                                                 \
     148             :   K(NEW, "new", 0)                                                 \
     149             :   K(RETURN, "return", 0)                                           \
     150             :   K(SWITCH, "switch", 0)                                           \
     151             :   K(THROW, "throw", 0)                                             \
     152             :   K(TRY, "try", 0)                                                 \
     153             :   /* TYPEOF */                                                     \
     154             :   K(VAR, "var", 0)                                                 \
     155             :   /* VOID */                                                       \
     156             :   K(WHILE, "while", 0)                                             \
     157             :   K(WITH, "with", 0)                                               \
     158             :   K(THIS, "this", 0)                                               \
     159             :                                                                    \
     160             :   /* Literals (ECMA-262, section 7.8, page 16). */                 \
     161             :   K(NULL_LITERAL, "null", 0)                                       \
     162             :   K(TRUE_LITERAL, "true", 0)                                       \
     163             :   K(FALSE_LITERAL, "false", 0)                                     \
     164             :   T(NUMBER, nullptr, 0)                                            \
     165             :   T(SMI, nullptr, 0)                                               \
     166             :   T(BIGINT, nullptr, 0)                                            \
     167             :   T(STRING, nullptr, 0)                                            \
     168             :                                                                    \
     169             :   /* BEGIN Callable */                                             \
     170             :   K(SUPER, "super", 0)                                             \
     171             :   /* BEGIN AnyIdentifier */                                        \
     172             :   /* Identifiers (not keywords or future reserved words). */       \
     173             :   T(IDENTIFIER, nullptr, 0)                                        \
     174             :   K(GET, "get", 0)                                                 \
     175             :   K(SET, "set", 0)                                                 \
     176             :   K(ASYNC, "async", 0)                                             \
     177             :   /* `await` is a reserved word in module code only */             \
     178             :   K(AWAIT, "await", 0)                                             \
     179             :   K(YIELD, "yield", 0)                                             \
     180             :   K(LET, "let", 0)                                                 \
     181             :   K(STATIC, "static", 0)                                           \
     182             :   /* Future reserved words (ECMA-262, section 7.6.1.2). */         \
     183             :   T(FUTURE_STRICT_RESERVED_WORD, nullptr, 0)                       \
     184             :   T(ESCAPED_STRICT_RESERVED_WORD, nullptr, 0)                      \
     185             :   /* END AnyIdentifier */                                          \
     186             :   /* END Callable */                                               \
     187             :   K(ENUM, "enum", 0)                                               \
     188             :   K(CLASS, "class", 0)                                             \
     189             :   K(CONST, "const", 0)                                             \
     190             :   K(EXPORT, "export", 0)                                           \
     191             :   K(EXTENDS, "extends", 0)                                         \
     192             :   K(IMPORT, "import", 0)                                           \
     193             :   T(PRIVATE_NAME, nullptr, 0)                                      \
     194             :                                                                    \
     195             :   /* Illegal token - not able to scan. */                          \
     196             :   T(ILLEGAL, "ILLEGAL", 0)                                         \
     197             :   T(ESCAPED_KEYWORD, nullptr, 0)                                   \
     198             :                                                                    \
     199             :   /* Scanner-internal use only. */                                 \
     200             :   T(WHITESPACE, nullptr, 0)                                        \
     201             :   T(UNINITIALIZED, nullptr, 0)                                     \
     202             :   T(REGEXP_LITERAL, nullptr, 0)
     203             : 
     204             : class Token {
     205             :  public:
     206             :   // All token values.
     207             : #define T(name, string, precedence) name,
     208             :   enum Value : uint8_t { TOKEN_LIST(T, T) NUM_TOKENS };
     209             : #undef T
     210             : 
     211             :   // Returns a string corresponding to the C++ token name
     212             :   // (e.g. "LT" for the token LT).
     213             :   static const char* Name(Value token) {
     214             :     DCHECK_GT(NUM_TOKENS, token);  // token is unsigned
     215        4665 :     return name_[token];
     216             :   }
     217             : 
     218             :   class IsKeywordBits : public BitField8<bool, 0, 1> {};
     219             :   class IsPropertyNameBits : public BitField8<bool, IsKeywordBits::kNext, 1> {};
     220             : 
     221             :   // Predicates
     222             :   static bool IsKeyword(Value token) {
     223             :     return IsKeywordBits::decode(token_flags[token]);
     224             :   }
     225             : 
     226     3096354 :   static bool IsPropertyName(Value token) {
     227    20620275 :     return IsPropertyNameBits::decode(token_flags[token]);
     228             :   }
     229             : 
     230             :   V8_INLINE static bool IsValidIdentifier(Value token,
     231             :                                           LanguageMode language_mode,
     232             :                                           bool is_generator,
     233             :                                           bool disallow_await) {
     234     3145630 :     if (V8_LIKELY(IsInRange(token, IDENTIFIER, ASYNC))) return true;
     235      133782 :     if (token == AWAIT) return !disallow_await;
     236      102107 :     if (token == YIELD) return !is_generator && is_sloppy(language_mode);
     237       73935 :     return IsStrictReservedWord(token) && is_sloppy(language_mode);
     238             :   }
     239             : 
     240             :   static bool IsCallable(Value token) {
     241             :     return IsInRange(token, SUPER, ESCAPED_STRICT_RESERVED_WORD);
     242             :   }
     243             : 
     244             :   static bool IsAutoSemicolon(Value token) {
     245             :     return IsInRange(token, SEMICOLON, EOS);
     246             :   }
     247             : 
     248             :   static bool IsAnyIdentifier(Value token) {
     249             :     return IsInRange(token, IDENTIFIER, ESCAPED_STRICT_RESERVED_WORD);
     250             :   }
     251             : 
     252       73935 :   static bool IsStrictReservedWord(Value token) {
     253       73935 :     return IsInRange(token, YIELD, ESCAPED_STRICT_RESERVED_WORD);
     254             :   }
     255             : 
     256             :   static bool IsLiteral(Value token) {
     257             :     return IsInRange(token, NULL_LITERAL, STRING);
     258             :   }
     259             : 
     260             :   static bool IsTemplate(Value token) {
     261             :     return IsInRange(token, TEMPLATE_SPAN, TEMPLATE_TAIL);
     262             :   }
     263             : 
     264   108657782 :   static bool IsMember(Value token) {
     265   108657782 :     return IsInRange(token, TEMPLATE_SPAN, LBRACK);
     266             :   }
     267             : 
     268             :   static bool IsProperty(Value token) {
     269             :     return IsInRange(token, PERIOD, LBRACK);
     270             :   }
     271             : 
     272   108176259 :   static bool IsPropertyOrCall(Value token) {
     273   108176259 :     return IsInRange(token, TEMPLATE_SPAN, LPAREN);
     274             :   }
     275             : 
     276             :   static bool IsArrowOrAssignmentOp(Value token) {
     277             :     return IsInRange(token, ARROW, ASSIGN_SUB);
     278             :   }
     279             : 
     280             :   static bool IsAssignmentOp(Value token) {
     281             :     return IsInRange(token, INIT, ASSIGN_SUB);
     282             :   }
     283             : 
     284             :   static bool IsBinaryOp(Value op) { return IsInRange(op, COMMA, SUB); }
     285             : 
     286             :   static bool IsCompareOp(Value op) { return IsInRange(op, EQ, IN); }
     287             : 
     288             :   static bool IsOrderedRelationalCompareOp(Value op) {
     289             :     return IsInRange(op, LT, GTE);
     290             :   }
     291             : 
     292             :   static bool IsEqualityOp(Value op) { return IsInRange(op, EQ, EQ_STRICT); }
     293             : 
     294             :   static Value BinaryOpForAssignment(Value op) {
     295             :     DCHECK(IsInRange(op, ASSIGN_BIT_OR, ASSIGN_SUB));
     296      102709 :     Value result = static_cast<Value>(op - ASSIGN_BIT_OR + BIT_OR);
     297             :     DCHECK(IsBinaryOp(result));
     298             :     return result;
     299             :   }
     300             : 
     301             :   static bool IsBitOp(Value op) {
     302         560 :     return IsInRange(op, BIT_OR, SHR) || op == BIT_NOT;
     303             :   }
     304             : 
     305             :   static bool IsUnaryOp(Value op) { return IsInRange(op, ADD, VOID); }
     306   213971754 :   static bool IsCountOp(Value op) { return IsInRange(op, INC, DEC); }
     307   220575456 :   static bool IsUnaryOrCountOp(Value op) { return IsInRange(op, ADD, DEC); }
     308             :   static bool IsShiftOp(Value op) { return IsInRange(op, SHL, SHR); }
     309             : 
     310             :   // Returns a string corresponding to the JS token string
     311             :   // (.e., "<" for the token LT) or nullptr if the token doesn't
     312             :   // have a (unique) string (e.g. an IDENTIFIER).
     313             :   static const char* String(Value token) {
     314             :     DCHECK_GT(NUM_TOKENS, token);  // token is unsigned
     315       81180 :     return string_[token];
     316             :   }
     317             : 
     318             :   static uint8_t StringLength(Value token) {
     319             :     DCHECK_GT(NUM_TOKENS, token);  // token is unsigned
     320             :     return string_length_[token];
     321             :   }
     322             : 
     323             :   // Returns the precedence > 0 for binary and compare
     324             :   // operators; returns 0 otherwise.
     325   108014764 :   static int Precedence(Value token, bool accept_IN) {
     326             :     DCHECK_GT(NUM_TOKENS, token);  // token is unsigned
     327   179227214 :     return precedence_[accept_IN][token];
     328             :   }
     329             : 
     330             :  private:
     331             :   static const char* const name_[NUM_TOKENS];
     332             :   static const char* const string_[NUM_TOKENS];
     333             :   static const uint8_t string_length_[NUM_TOKENS];
     334             :   static const int8_t precedence_[2][NUM_TOKENS];
     335             :   static const uint8_t token_flags[NUM_TOKENS];
     336             : };
     337             : 
     338             : }  // namespace internal
     339             : }  // namespace v8
     340             : 
     341             : #endif  // V8_PARSING_TOKEN_H_

Generated by: LCOV version 1.10