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