TokenType.java revision 1312:d1689c1df3aa
1/*
2 * Copyright (c) 2010, 2015, 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     *
226     * @param other  Compare token.
227     * @param isLeft Is to the left of the other.
228     *
229     * @return {@code true} if greater precedence.
230     */
231    public boolean needsParens(final TokenType other, final boolean isLeft) {
232        return other.precedence != 0 &&
233               (precedence > other.precedence ||
234               precedence == other.precedence && isLeftAssociative && !isLeft);
235    }
236
237    /**
238     * Determines if the type is a valid operator.
239     *
240     * @param noIn {@code true} if IN operator should be ignored.
241     *
242     * @return {@code true} if valid operator.
243     */
244    public boolean isOperator(final boolean noIn) {
245        return kind == BINARY && (!noIn || this != IN) && precedence != 0;
246    }
247
248
249    public int getLength() {
250        assert name != null : "Token name not set";
251        return name.length();
252    }
253
254    public String getName() {
255        return name;
256    }
257
258    public String getNameOrType() {
259        return name == null ? super.name().toLowerCase(Locale.ENGLISH) : name;
260    }
261
262    public TokenType getNext() {
263        return next;
264    }
265
266    public void setNext(final TokenType next) {
267        this.next = next;
268    }
269
270    public TokenKind getKind() {
271        return kind;
272    }
273
274    public int getPrecedence() {
275        return precedence;
276    }
277
278    public boolean isLeftAssociative() {
279        return isLeftAssociative;
280    }
281
282    boolean startsWith(final char c) {
283        return name != null && name.length() > 0 && name.charAt(0) == c;
284    }
285
286    static TokenType[] getValues() {
287       return values;
288    }
289
290    @Override
291    public String toString() {
292        return getNameOrType();
293    }
294
295    static {
296        // Avoid cloning of enumeration.
297        values = TokenType.values();
298    }
299}
300