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 ---