1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.parser;
  27 
  28 import java.util.Locale;
  29 import static jdk.nashorn.internal.parser.TokenKind.BINARY;
  30 import static jdk.nashorn.internal.parser.TokenKind.BRACKET;
  31 import static jdk.nashorn.internal.parser.TokenKind.FUTURE;
  32 import static jdk.nashorn.internal.parser.TokenKind.FUTURESTRICT;
  33 import static jdk.nashorn.internal.parser.TokenKind.IR;
  34 import static jdk.nashorn.internal.parser.TokenKind.KEYWORD;
  35 import static jdk.nashorn.internal.parser.TokenKind.LITERAL;
  36 import static jdk.nashorn.internal.parser.TokenKind.SPECIAL;
  37 import static jdk.nashorn.internal.parser.TokenKind.UNARY;
  38 
  39 /**
  40  * Description of all the JavaScript tokens.
  41  */
  42 @SuppressWarnings("javadoc")
  43 public enum TokenType {
  44     ERROR          (SPECIAL,  null),
  45     EOF            (SPECIAL,  null),
  46     EOL            (SPECIAL,  null),
  47 
  48     NOT            (UNARY,   "!",    14, false),
  49     NE             (BINARY,  "!=",    9, true),
  50     NE_STRICT      (BINARY,  "!==",   9, true),
  51     MOD            (BINARY,  "%",    13, true),
  52     ASSIGN_MOD     (BINARY,  "%=",    2, false),
  53     BIT_AND        (BINARY,  "&",     8, true),
  54     AND            (BINARY,  "&&",    5, true),
  55     ASSIGN_BIT_AND (BINARY,  "&=",    2, false),
  56     LPAREN         (BRACKET, "(",    16, true),
  57     RPAREN         (BRACKET, ")",     0, true),
  58     MUL            (BINARY,  "*",    13, true),
  59     ASSIGN_MUL     (BINARY,  "*=",    2, false),
  60     ADD            (BINARY,  "+",    12, true),
  61     INCPREFIX      (UNARY,   "++",   15, true),
  62     ASSIGN_ADD     (BINARY,  "+=",    2, false),
  63     COMMARIGHT     (BINARY,  ",",     1, true),
  64     SUB            (BINARY,  "-",    12, true),
  65     DECPREFIX      (UNARY,   "--",   15, true),
  66     ASSIGN_SUB     (BINARY,  "-=",    2, false),
  67     PERIOD         (BRACKET, ".",    17, true),
  68     DIV            (BINARY,  "/",    13, true),
  69     ASSIGN_DIV     (BINARY,  "/=",    2, false),
  70     COLON          (BINARY,  ":"),
  71     SEMICOLON      (BINARY,  ";"),
  72     LT             (BINARY,  "<",    10, true),
  73     SHL            (BINARY,  "<<",   11, true),
  74     ASSIGN_SHL     (BINARY,  "<<=",   2, false),
  75     LE             (BINARY,  "<=",   10, true),
  76     ASSIGN         (BINARY,  "=",     2, false),
  77     EQ             (BINARY,  "==",    9, true),
  78     EQ_STRICT      (BINARY,  "===",   9, true),
  79     BIND           (BINARY,  "=>",    9, true),
  80     GT             (BINARY,  ">",    10, true),
  81     GE             (BINARY,  ">=",   10, true),
  82     SAR            (BINARY,  ">>",   11, true),
  83     ASSIGN_SAR     (BINARY,  ">>=",   2, false),
  84     SHR            (BINARY,  ">>>",  11, true),
  85     ASSIGN_SHR     (BINARY,  ">>>=",  2, false),
  86     TERNARY        (BINARY,  "?",     3, false),
  87     LBRACKET       (BRACKET, "[",    17, true),
  88     RBRACKET       (BRACKET, "]",     0, true),
  89     BIT_XOR        (BINARY,  "^",     7, true),
  90     ASSIGN_BIT_XOR (BINARY,  "^=",    2, false),
  91     LBRACE         (BRACKET,  "{"),
  92     BIT_OR         (BINARY,  "|",     6, true),
  93     ASSIGN_BIT_OR  (BINARY,  "|=",    2, false),
  94     OR             (BINARY,  "||",    4, true),
  95     RBRACE         (BRACKET, "}"),
  96     BIT_NOT        (BINARY,  "~",    14, false),
  97 
  98     // ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words.
  99     // All other Java keywords are commented out.
 100 
 101 //  ABSTRACT       (FUTURE,   "abstract"),
 102 //  BOOLEAN        (FUTURE,   "boolean"),
 103     BREAK          (KEYWORD,  "break"),
 104 //  BYTE           (FUTURE,   "byte"),
 105     CASE           (KEYWORD,  "case"),
 106     CATCH          (KEYWORD,  "catch"),
 107 //  CHAR           (FUTURE,   "char"),
 108     CLASS          (FUTURE,   "class"),
 109     CONST          (FUTURE,  "const"),
 110     CONTINUE       (KEYWORD,  "continue"),
 111     DEBUGGER       (KEYWORD,  "debugger"),
 112     DEFAULT        (KEYWORD,  "default"),
 113     DELETE         (UNARY,    "delete",     14, false),
 114     DO             (KEYWORD,  "do"),
 115 //  DOUBLE         (FUTURE,   "double"),
 116 //  EACH           (KEYWORD,  "each"),  // Contextual.
 117     ELSE           (KEYWORD,  "else"),
 118     ENUM           (FUTURE,   "enum"),
 119     EXPORT         (FUTURE,   "export"),
 120     EXTENDS        (FUTURE,   "extends"),
 121     FALSE          (LITERAL,  "false"),
 122 //  FINAL          (FUTURE,   "final"),
 123     FINALLY        (KEYWORD,  "finally"),
 124 //  FLOAT          (FUTURE,   "float"),
 125     FOR            (KEYWORD,  "for"),
 126     FUNCTION       (KEYWORD,  "function"),
 127 //  GET            (KEYWORD,  "get"), // Contextual.
 128 //  GOTO           (FUTURE,   "goto"),
 129     IF             (KEYWORD,   "if"),
 130     IMPLEMENTS     (FUTURESTRICT,   "implements"),
 131     IMPORT         (FUTURE,   "import"),
 132     IN             (BINARY,   "in",         10, true),
 133     INSTANCEOF     (BINARY,   "instanceof", 10, true),
 134 //  INT            (FUTURE,   "int"),
 135     INTERFACE      (FUTURESTRICT,   "interface"),
 136     LET            (FUTURESTRICT,   "let"),
 137 //  LONG           (FUTURE,   "long"),
 138 //  NATIVE         (FUTURE,   "native"),
 139     NEW            (UNARY,    "new",        17, false),
 140     NULL           (LITERAL,  "null"),
 141     PACKAGE        (FUTURESTRICT,   "package"),
 142     PRIVATE        (FUTURESTRICT,   "private"),
 143     PROTECTED      (FUTURESTRICT,   "protected"),
 144     PUBLIC         (FUTURESTRICT,   "public"),
 145     RETURN         (KEYWORD,  "return"),
 146 //  SET            (KEYWORD,  "set"), // Contextual.
 147 //  SHORT          (FUTURE,   "short"),
 148     STATIC         (FUTURESTRICT,   "static"),
 149     SUPER          (FUTURE,   "super"),
 150     SWITCH         (KEYWORD,  "switch"),
 151 //  SYNCHRONIZED   (FUTURE,   "synchronized"),
 152     THIS           (KEYWORD,  "this"),
 153     THROW          (KEYWORD,  "throw"),
 154 //  THROWS         (FUTURE,   "throws"),
 155 //  TRANSIENT      (FUTURE,   "transient"),
 156     TRUE           (LITERAL,  "true"),
 157     TRY            (KEYWORD,  "try"),
 158     TYPEOF         (UNARY,    "typeof",     14, false),
 159     VAR            (KEYWORD,  "var"),
 160     VOID           (UNARY,    "void",       14, false),
 161 //  VOLATILE       (FUTURE,   "volatile"),
 162     WHILE          (KEYWORD,  "while"),
 163     WITH           (KEYWORD,  "with"),
 164     YIELD          (FUTURESTRICT,  "yield"),
 165 
 166     DECIMAL        (LITERAL,  null),
 167     OCTAL          (LITERAL,  null),
 168     HEXADECIMAL    (LITERAL,  null),
 169     FLOATING       (LITERAL,  null),
 170     STRING         (LITERAL,  null),
 171     ESCSTRING      (LITERAL,  null),
 172     EXECSTRING     (LITERAL,  null),
 173     IDENT          (LITERAL,  null),
 174     REGEX          (LITERAL,  null),
 175     XML            (LITERAL,  null),
 176     OBJECT         (LITERAL,  null),
 177     ARRAY          (LITERAL,  null),
 178 
 179     COMMALEFT      (IR,       null),
 180     CONVERT        (IR,       null),
 181     DISCARD        (IR,       null),
 182     DECPOSTFIX     (IR,       null),
 183     INCPOSTFIX     (IR,       null);
 184 
 185     /** Next token kind in token lookup table. */
 186     private TokenType next;
 187 
 188     /** Classification of token. */
 189     private final TokenKind kind;
 190 
 191     /** Printable name of token. */
 192     private final String name;
 193 
 194     /** Operator precedence. */
 195     private final int precedence;
 196 
 197     /** Left associativity */
 198     private final boolean isLeftAssociative;
 199 
 200     /** Cache values to avoid cloning. */
 201     private static final TokenType[] values;
 202 
 203     TokenType(final TokenKind kind, final String name) {
 204         next              = null;
 205         this.kind         = kind;
 206         this.name         = name;
 207         precedence        = 0;
 208         isLeftAssociative = false;
 209     }
 210 
 211     TokenType(final TokenKind kind, final String name, final int precedence, final boolean isLeftAssociative) {
 212         next                   = null;
 213         this.kind              = kind;
 214         this.name              = name;
 215         this.precedence        = precedence;
 216         this.isLeftAssociative = isLeftAssociative;
 217     }
 218 
 219     /**
 220      * Determines if the token has greater precedence than other.
 221      * @param other  Compare token.
 222      * @param isLeft Is to the left of the other.
 223      * @return True if greater precedence.
 224      */
 225     public boolean needsParens(final TokenType other, final boolean isLeft) {
 226         return other.precedence != 0 &&
 227                (precedence > other.precedence ||
 228                precedence == other.precedence && isLeftAssociative && !isLeft);
 229     }
 230 
 231     /**
 232      * Determines if the type is a valid operator.
 233      * @param noIn TRUE if IN operator should be ignored.
 234      * @return TRUE if valid operator.
 235      */
 236     public boolean isOperator(final boolean noIn) {
 237         return kind == BINARY && (!noIn || this != IN) && precedence != 0;
 238     }
 239 
 240     /**
 241      * Accessors.
 242      */
 243     public int getLength() {
 244         assert name != null : "Token name not set";
 245         return name.length();
 246     }
 247 
 248     public String getName() {
 249         return name;
 250     }
 251 
 252     public String getNameOrType() {
 253         return name == null ? super.name().toLowerCase(Locale.ENGLISH) : name;
 254     }
 255 
 256     public TokenType getNext() {
 257         return next;
 258     }
 259 
 260     public void setNext(final TokenType next) {
 261         this.next = next;
 262     }
 263 
 264     public TokenKind getKind() {
 265         return kind;
 266     }
 267 
 268     public int getPrecedence() {
 269         return precedence;
 270     }
 271 
 272     public boolean isLeftAssociative() {
 273         return isLeftAssociative;
 274     }
 275 
 276     boolean startsWith(final char c) {
 277         return name != null && name.length() > 0 && name.charAt(0) == c;
 278     }
 279 
 280     static TokenType[] getValues() {
 281        return values;
 282     }
 283 
 284     @Override
 285     public String toString() {
 286         return name;
 287     }
 288 
 289     static {
 290         // Avoid cloning of enumeration.
 291         values = TokenType.values();
 292     }
 293 }
--- EOF ---