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