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