001    /*
002     $Id: Types.java 2120 2005-04-12 15:05:51Z jstrachan $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    
047    package org.codehaus.groovy.syntax;
048    
049    import java.util.HashMap;
050    import java.util.Iterator;
051    import java.util.Map;
052    
053    import org.codehaus.groovy.GroovyBugError;
054    
055    
056    /**
057     *  Typing information for the CST system.  The types here are those
058     *  used by CSTNode, Token, and Reduction.
059     *
060     *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
061     *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
062     *
063     *  @version $Id: Types.java 2120 2005-04-12 15:05:51Z jstrachan $
064     */
065    
066    public class Types
067    {
068    
069    
070      //---------------------------------------------------------------------------
071      // TYPES: NOTE THAT ORDERING AND VALUES ARE IMPORTANT TO LOCAL ROUTINES!
072    
073    
074        //
075        // SPECIAL TOKENS
076    
077        public static final int EOF                         = -1;    // end of file
078        public static final int UNKNOWN                     = 0;     // the unknown token
079    
080    
081        //
082        // RELEVANT WHITESPACE
083    
084        public static final int NEWLINE                     = 5;     // \n
085    
086    
087        //
088        // OPERATORS AND OTHER MARKERS
089    
090        public static final int LEFT_CURLY_BRACE            = 10;    // {
091        public static final int RIGHT_CURLY_BRACE           = 20;    // }
092        public static final int LEFT_SQUARE_BRACKET         = 30;    // [
093        public static final int RIGHT_SQUARE_BRACKET        = 40;    // ]
094        public static final int LEFT_PARENTHESIS            = 50;    // (
095        public static final int RIGHT_PARENTHESIS           = 60;    // )
096    
097        public static final int DOT                         = 70;    // .
098        public static final int DOT_DOT                     = 75;    // ..
099        public static final int DOT_DOT_DOT                 = 77;    // ...
100    
101        public static final int NAVIGATE                    = 80;    // ->
102    
103        public static final int FIND_REGEX                  = 90;    // =~
104        public static final int MATCH_REGEX                 = 94;    // ==~
105        public static final int REGEX_PATTERN               = 97;    // ~
106    
107        public static final int EQUAL                       = 100;   // =
108        public static final int EQUALS                      = EQUAL;
109        public static final int ASSIGN                      = EQUAL;
110    
111        public static final int COMPARE_NOT_EQUAL           = 120;   // !=
112        public static final int COMPARE_IDENTICAL           = 121;   // ===
113        public static final int COMPARE_NOT_IDENTICAL       = 122;   // !==
114        public static final int COMPARE_EQUAL               = 123;   // ==
115        public static final int COMPARE_LESS_THAN           = 124;   // <
116        public static final int COMPARE_LESS_THAN_EQUAL     = 125;   // <=
117        public static final int COMPARE_GREATER_THAN        = 126;   // >
118        public static final int COMPARE_GREATER_THAN_EQUAL  = 127;   // >=
119        public static final int COMPARE_TO                  = 128;   // <=>
120    
121        public static final int NOT                         = 160;   // !
122        public static final int LOGICAL_OR                  = 162;   // ||
123        public static final int LOGICAL_AND                 = 164;   // &&
124    
125        public static final int LOGICAL_OR_EQUAL            = 166;   // ||=
126        public static final int LOGICAL_AND_EQUAL           = 168;   // &&=
127    
128        public static final int PLUS                        = 200;   // +
129        public static final int MINUS                       = 201;   // -
130        public static final int MULTIPLY                    = 202;   // *
131        public static final int DIVIDE                      = 203;   // /
132        public static final int INTDIV                      = 204;   // \
133        public static final int MOD                         = 205;   // %
134        public static final int STAR_STAR                   = 206;   // **
135        public static final int POWER                       = STAR_STAR;   // **
136    
137        public static final int PLUS_EQUAL                  = 210;   // +=
138        public static final int MINUS_EQUAL                 = 211;   // -=
139        public static final int MULTIPLY_EQUAL              = 212;   // *=
140        public static final int DIVIDE_EQUAL                = 213;   // /=
141        public static final int INTDIV_EQUAL                = 214;   // \=
142        public static final int MOD_EQUAL                   = 215;   // %=
143        public static final int POWER_EQUAL                 = 216;   // **=
144    
145        public static final int PLUS_PLUS                   = 250;   // ++
146        public static final int PREFIX_PLUS_PLUS            = 251;   // ++
147        public static final int POSTFIX_PLUS_PLUS           = 252;   // ++
148        public static final int PREFIX_PLUS                 = 253;   // +
149    
150        public static final int MINUS_MINUS                 = 260;   // --
151        public static final int PREFIX_MINUS_MINUS          = 261;   // --
152        public static final int POSTFIX_MINUS_MINUS         = 262;   // --
153        public static final int PREFIX_MINUS                = 263;   // - (negation)
154    
155        public static final int LEFT_SHIFT                  = 280;   // <<
156        public static final int RIGHT_SHIFT                 = 281;   // >>
157        public static final int RIGHT_SHIFT_UNSIGNED        = 282;   // >>>
158    
159        public static final int LEFT_SHIFT_EQUAL            = 285;   // <<=
160        public static final int RIGHT_SHIFT_EQUAL           = 286;   // >>=
161        public static final int RIGHT_SHIFT_UNSIGNED_EQUAL  = 287;   // >>>=
162    
163        public static final int STAR                        = MULTIPLY;
164    
165        public static final int COMMA                       = 300;   // -
166        public static final int COLON                       = 310;   // :
167        public static final int SEMICOLON                   = 320;   // ;
168        public static final int QUESTION                    = 330;   // ?
169    
170        // TODO refactor PIPE to be BITWISE_OR
171        public static final int PIPE                        = 340;   // |
172        public static final int DOUBLE_PIPE                 = LOGICAL_OR;   // ||
173        public static final int BITWISE_OR                  = PIPE;  // |
174        public static final int BITWISE_AND                 = 341;   // &
175        public static final int BITWISE_XOR                 = 342;   // ^
176    
177        public static final int BITWISE_OR_EQUAL            = 350;   // |=
178        public static final int BITWISE_AND_EQUAL           = 351;   // &=
179        public static final int BITWISE_XOR_EQUAL           = 352;   // ^=
180        public static final int BITWISE_NEGATION            = REGEX_PATTERN;    // ~
181    
182    
183        //
184        // LITERALS
185    
186        public static final int STRING                      = 400;   // any bare string data
187    
188        public static final int IDENTIFIER                  = 440;   // anything text and not a keyword
189    
190        public static final int INTEGER_NUMBER              = 450;   // integer
191        public static final int DECIMAL_NUMBER              = 451;   // decimal
192    
193    
194        //
195        // KEYWORDS: (PRIMARILY) CLASS/METHOD DECLARATION MODIFIERS
196    
197        public static final int KEYWORD_PRIVATE             = 500;   // declaration visibility
198        public static final int KEYWORD_PROTECTED           = 501;   // declaration visibility
199        public static final int KEYWORD_PUBLIC              = 502;   // declaration visibility
200    
201        public static final int KEYWORD_ABSTRACT            = 510;   // method body missing
202        public static final int KEYWORD_FINAL               = 511;   // declaration cannot be overridden
203        public static final int KEYWORD_NATIVE              = 512;   // a native code entry point
204        public static final int KEYWORD_TRANSIENT           = 513;   // property should not be persisted
205        public static final int KEYWORD_VOLATILE            = 514;   // compiler should never cache property
206    
207        public static final int KEYWORD_SYNCHRONIZED        = 520;   // modifier and block type
208        public static final int KEYWORD_STATIC              = 521;   // modifier and block type
209    
210    
211        //
212        // KEYWORDS: TYPE SYSTEM
213    
214        public static final int KEYWORD_DEF                 = 530;   // identifies a function declaration
215        public static final int KEYWORD_DEFMACRO            = 539;   // XXX br identifies a macro declaration
216        public static final int KEYWORD_CLASS               = 531;   // identifies a class declaration
217        public static final int KEYWORD_INTERFACE           = 532;   // identifies an interface declaration
218        public static final int KEYWORD_MIXIN               = 533;   // identifies a mixin declaration
219    
220        public static final int KEYWORD_IMPLEMENTS          = 540;   // specifies the interfaces implemented by a class
221        public static final int KEYWORD_EXTENDS             = 541;   // specifies the base class/interface for a new one
222        public static final int KEYWORD_THIS                = 542;   // method variable points to the current instance
223        public static final int KEYWORD_SUPER               = 543;   // method variable points to the base instance
224        public static final int KEYWORD_INSTANCEOF          = 544;   // type comparator
225        public static final int KEYWORD_PROPERTY            = 545;   // deprecated; identifies a property
226        public static final int KEYWORD_NEW                 = 546;   // used to create a new instance of a class
227    
228        public static final int KEYWORD_PACKAGE             = 550;   // declares the package scope
229        public static final int KEYWORD_IMPORT              = 551;   // declares an external class
230        public static final int KEYWORD_AS                  = 552;   // used in import statements to create an alias
231    
232    
233        //
234        // KEYWORDS: CONTROL STRUCTURES
235    
236        public static final int KEYWORD_RETURN              = 560;   // returns from a closure or method
237        public static final int KEYWORD_IF                  = 561;   // if
238        public static final int KEYWORD_ELSE                = 562;   // else
239        public static final int KEYWORD_DO                  = 570;   // do loop
240        public static final int KEYWORD_WHILE               = 571;   // while loop
241        public static final int KEYWORD_FOR                 = 572;   // for loop
242        public static final int KEYWORD_IN                  = 573;   // for (each) loop separator
243        public static final int KEYWORD_BREAK               = 574;   // exits a loop or block
244        public static final int KEYWORD_CONTINUE            = 575;   // restarts a loop on the next iteration
245        public static final int KEYWORD_SWITCH              = 576;   // switch block
246        public static final int KEYWORD_CASE                = 577;   // item in a switch block
247        public static final int KEYWORD_DEFAULT             = 578;   // catch-all item in a switch block
248    
249        public static final int KEYWORD_TRY                 = 580;   // block to monitor for exceptions
250        public static final int KEYWORD_CATCH               = 581;   // catch block for a particular exception
251        public static final int KEYWORD_FINALLY             = 582;   // block to always execute on exit of the try
252        public static final int KEYWORD_THROW               = 583;   // statement to throw an exception
253        public static final int KEYWORD_THROWS              = 584;   // method modifier to declare thrown transactions
254        public static final int KEYWORD_ASSERT              = 585;   // alternate throw for code invariants
255    
256    
257        //
258        // KEYWORDS: PRIMITIVE TYPES
259    
260        public static final int KEYWORD_VOID                = 600;   // void
261        public static final int KEYWORD_BOOLEAN             = 601;   // boolean
262        public static final int KEYWORD_BYTE                = 602;   // 1 byte integer
263        public static final int KEYWORD_SHORT               = 603;   // 2 byte integer
264        public static final int KEYWORD_INT                 = 604;   // 4 byte integer
265        public static final int KEYWORD_LONG                = 605;   // 8 byte integer
266        public static final int KEYWORD_FLOAT               = 606;   // 32 bit floating point number
267        public static final int KEYWORD_DOUBLE              = 607;   // 64 bit floating point number
268        public static final int KEYWORD_CHAR                = 608;   // unicode character code
269    
270    
271        //
272        // KEYWORDS: SPECIAL VALUES
273    
274        public static final int KEYWORD_TRUE                = 610;   // boolean truth
275        public static final int KEYWORD_FALSE               = 611;   // boolean false
276        public static final int KEYWORD_NULL                = 612;   // missing instance
277    
278    
279        //
280        // KEYWORDS: RESERVED
281    
282        public static final int KEYWORD_CONST               = 700;   // reserved in java and groovy
283        public static final int KEYWORD_GOTO                = 701;   // reserved in java and groovy
284    
285    
286        //
287        // SPECIAL (CALCULATED) MEANINGS
288    
289        public static final int SYNTH_COMPILATION_UNIT      = 800;   // reserved: a synthetic root for a CST
290    
291        public static final int SYNTH_CLASS                 = 801;   // applied to class names
292        public static final int SYNTH_INTERFACE             = 802;   // applied to interface names
293        public static final int SYNTH_MIXIN                 = 803;   // applied to mixin names
294        public static final int SYNTH_METHOD                = 804;   // applied to method names
295        public static final int SYNTH_PROPERTY              = 805;   // applied to property names
296        public static final int SYNTH_PARAMETER_DECLARATION = 806;   // applied to method/closure parameter names
297    
298        public static final int SYNTH_LIST                  = 810;   // applied to "[" that marks a list
299        public static final int SYNTH_MAP                   = 811;   // applied to "[" that marks a map
300        public static final int SYNTH_GSTRING               = 812;   // a complete GString
301    
302        public static final int SYNTH_METHOD_CALL           = 814;   // applied to the optional "(" that marks a call to a method
303        public static final int SYNTH_CAST                  = 815;   // applied to "(" that marks a type cast
304        public static final int SYNTH_BLOCK                 = 816;   // applied to "{" that marks a block
305        public static final int SYNTH_CLOSURE               = 817;   // applied to "{" that marks a closure
306        public static final int SYNTH_LABEL                 = 818;   // applied to a statement label
307        public static final int SYNTH_TERNARY               = 819;   // applied to "?" that marks a ternary expression
308        public static final int SYNTH_TUPLE                 = 820;   // applied to "{" that marks an array initializer
309    
310        public static final int SYNTH_VARIABLE_DECLARATION  = 830;   // applied to an identifier that specifies
311                                                                     // the type of a variable declaration
312    
313        //
314        // GSTRING TOKENS
315    
316        public static final int GSTRING_START               = 901;   // any marker tha begins a GString
317        public static final int GSTRING_END                 = 902;   // any matching marker that ends a GString
318        public static final int GSTRING_EXPRESSION_START    = 903;   // the ${ marker that starts a GString expression
319        public static final int GSTRING_EXPRESSION_END      = 904;   // the } marker that ends a GString expresssion
320    
321    
322        //
323        // TYPE CLASSES
324    
325        public static final int ANY                         = 1000;  // anything
326        public static final int NOT_EOF                     = 1001;  // anything but EOF
327        public static final int GENERAL_END_OF_STATEMENT    = 1002;  // ";", "\n", EOF
328        public static final int ANY_END_OF_STATEMENT        = 1003;  // ";", "\n", EOF, "}"
329    
330        public static final int ASSIGNMENT_OPERATOR         = 1100;  // =, +=, etc.
331        public static final int COMPARISON_OPERATOR         = 1101;  // ==, ===, >, <, etc.
332        public static final int MATH_OPERATOR               = 1102;  // +, -, / *, %, plus the LOGICAL_OPERATORS
333        public static final int LOGICAL_OPERATOR            = 1103;  // ||, &&, !
334        public static final int RANGE_OPERATOR              = 1104;  // .., ...
335        public static final int REGEX_COMPARISON_OPERATOR   = 1105;  // =~, etc.
336        public static final int DEREFERENCE_OPERATOR        = 1106;  // ., ->
337        public static final int BITWISE_OPERATOR            = 1107;  // |, &, <<, >>, >>>, ^, ~
338    
339        public static final int PREFIX_OPERATOR             = 1200;  // ++, !, etc.
340        public static final int POSTFIX_OPERATOR            = 1210;  // ++, etc.
341        public static final int INFIX_OPERATOR              = 1220;  // +, -, =, etc.
342        public static final int PREFIX_OR_INFIX_OPERATOR    = 1230;  // +, -
343        public static final int PURE_PREFIX_OPERATOR        = 1235;  // prefix +, prefix -
344    
345        public static final int KEYWORD                     = 1300;  // any keyword
346        public static final int SYMBOL                      = 1301;  // any symbol
347        public static final int LITERAL                     = 1310;  // strings, numbers, identifiers
348        public static final int NUMBER                      = 1320;  // integers and decimals
349        public static final int SIGN                        = 1325;  // "+", "-"
350        public static final int NAMED_VALUE                 = 1330;  // true, false, null
351        public static final int TRUTH_VALUE                 = 1331;  // true, false
352        public static final int PRIMITIVE_TYPE              = 1340;  // void, byte, short, int, etc.
353        public static final int CREATABLE_PRIMITIVE_TYPE    = 1341;  // any PRIMITIVE_TYPE except void
354        public static final int LOOP                        = 1350;  // do, while, etc.
355        public static final int RESERVED_KEYWORD            = 1360;  // const, goto, etc.
356        public static final int KEYWORD_IDENTIFIER          = 1361;  // keywords that can appear as identifiers
357        public static final int SYNTHETIC                   = 1370;  // any of the SYNTH types
358    
359        public static final int TYPE_DECLARATION            = 1400;  // class, interface, mixin
360        public static final int DECLARATION_MODIFIER        = 1410;  // public, private, abstract, etc.
361    
362        public static final int TYPE_NAME                   = 1420;  // identifiers, primitive types
363        public static final int CREATABLE_TYPE_NAME         = 1430;  // identifiers, primitive types except void
364    
365        public static final int MATCHED_CONTAINER           = 1500;  // (, ), [, ], {, }
366        public static final int LEFT_OF_MATCHED_CONTAINER   = 1501;  // (, [, {
367        public static final int RIGHT_OF_MATCHED_CONTAINER  = 1502;  // ), ], }
368    
369        public static final int EXPRESSION                  = 1900;  // all of the below 1900 series
370    
371        public static final int OPERATOR_EXPRESSION         = 1901;  // "."-"<<"
372        public static final int SYNTH_EXPRESSION            = 1902;  // cast, ternary, and closure expression
373        public static final int KEYWORD_EXPRESSION          = 1903;  // new, this, super, instanceof, true, false, null
374        public static final int LITERAL_EXPRESSION          = 1904;  // LITERAL
375        public static final int ARRAY_EXPRESSION            = 1905;  // "["
376    
377        public static final int SIMPLE_EXPRESSION           = 1910;  // LITERAL, this, true, false, null
378        public static final int COMPLEX_EXPRESSION          = 1911;  // SIMPLE_EXPRESSION, and various molecules
379    
380    
381    
382        //
383        // TYPE GROUPS (OPERATIONS SUPPORT)
384    
385        public static final int PARAMETER_TERMINATORS       = 2000;  // ")", ","
386        public static final int ARRAY_ITEM_TERMINATORS      = 2001;  // "]", ","
387        public static final int TYPE_LIST_TERMINATORS       = 2002;  // "implements", "throws", "{", ","
388        public static final int OPTIONAL_DATATYPE_FOLLOWERS = 2003;  // identifier, "[", "."
389    
390        public static final int SWITCH_BLOCK_TERMINATORS    = 2004;  // "case", "default", "}"
391        public static final int SWITCH_ENTRIES              = 2005;  // "case", "default"
392    
393        public static final int METHOD_CALL_STARTERS        = 2006;  // LITERAL, "(", "{"
394        public static final int UNSAFE_OVER_NEWLINES        = 2007;  // things the expression parser should cross lines for in it doesn't have to
395    
396        public static final int PRECLUDES_CAST_OPERATOR     = 2008;  // anything that prevents (X) from being a cast
397    
398    
399    
400    
401    
402      //---------------------------------------------------------------------------
403      // TYPE HIERARCHIES
404    
405    
406       /**
407        *  Given two types, returns true if the second describes the first.
408        */
409    
410        public static boolean ofType( int specific, int general )
411        {
412    
413            if( general == specific )
414            {
415                return true;
416            }
417    
418            switch( general )
419            {
420                case ANY:
421                    return true;
422    
423                case NOT_EOF:
424                    return specific >= UNKNOWN && specific <= SYNTH_VARIABLE_DECLARATION;
425    
426                case GENERAL_END_OF_STATEMENT:
427                    switch( specific )
428                    {
429                        case EOF:
430                        case NEWLINE:
431                        case SEMICOLON:
432                            return true;
433                    }
434                    break;
435    
436                case ANY_END_OF_STATEMENT:
437                    switch( specific )
438                    {
439                        case EOF:
440                        case NEWLINE:
441                        case SEMICOLON:
442                        case RIGHT_CURLY_BRACE:
443                            return true;
444                    }
445                    break;
446    
447                case ASSIGNMENT_OPERATOR:
448                    return specific == EQUAL || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL)
449                                             || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL)
450                                             || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL);
451    
452                case COMPARISON_OPERATOR:
453                    return specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO;
454    
455                case MATH_OPERATOR:
456                    return (specific >= PLUS && specific <= RIGHT_SHIFT_UNSIGNED) || (specific >= NOT && specific <= LOGICAL_AND)
457                                     || (specific >= BITWISE_OR && specific <= BITWISE_XOR);
458    
459                case LOGICAL_OPERATOR:
460                    return specific >= NOT && specific <= LOGICAL_AND;
461    
462                case BITWISE_OPERATOR:
463                    return (specific >= BITWISE_OR && specific <= BITWISE_XOR) || specific == BITWISE_NEGATION;
464    
465                case RANGE_OPERATOR:
466                    return specific == DOT_DOT || specific == DOT_DOT_DOT;
467    
468                case REGEX_COMPARISON_OPERATOR:
469                    return specific == FIND_REGEX || specific == MATCH_REGEX;
470    
471                case DEREFERENCE_OPERATOR:
472                    return specific == DOT || specific == NAVIGATE;
473    
474                case PREFIX_OPERATOR:
475                    switch( specific )
476                    {
477                        case MINUS:
478                        case PLUS_PLUS:
479                        case MINUS_MINUS:
480                            return true;
481                    }
482    
483                    /* FALL THROUGH */
484    
485                case PURE_PREFIX_OPERATOR:
486                    switch( specific )
487                    {
488                        case REGEX_PATTERN:
489                        case NOT:
490                        case PREFIX_PLUS:
491                        case PREFIX_PLUS_PLUS:
492                        case PREFIX_MINUS:
493                        case PREFIX_MINUS_MINUS:
494                        case SYNTH_CAST:
495                            return true;
496                    }
497                    break;
498    
499                case POSTFIX_OPERATOR:
500                    switch( specific )
501                    {
502                        case PLUS_PLUS:
503                        case POSTFIX_PLUS_PLUS:
504                        case MINUS_MINUS:
505                        case POSTFIX_MINUS_MINUS:
506                            return true;
507                    }
508                    break;
509    
510                case INFIX_OPERATOR:
511                    switch( specific )
512                    {
513                        case DOT:
514                        case NAVIGATE:
515                        case LOGICAL_OR:
516                        case LOGICAL_AND:
517                        case BITWISE_OR:
518                        case BITWISE_AND:
519                        case BITWISE_XOR:
520                        case LEFT_SHIFT:
521                        case RIGHT_SHIFT:
522                        case RIGHT_SHIFT_UNSIGNED:
523                        case FIND_REGEX:
524                        case MATCH_REGEX:
525                        case DOT_DOT:
526                        case DOT_DOT_DOT:
527                        case KEYWORD_INSTANCEOF:
528                            return true;
529                    }
530    
531                    return (specific >= COMPARE_NOT_EQUAL && specific <= COMPARE_TO) || (specific >= PLUS && specific <= MOD_EQUAL) || specific == EQUAL || (specific >= PLUS_EQUAL && specific <= POWER_EQUAL) || (specific >= LOGICAL_OR_EQUAL && specific <= LOGICAL_AND_EQUAL)
532                                     || (specific >= LEFT_SHIFT_EQUAL && specific <= RIGHT_SHIFT_UNSIGNED_EQUAL) || (specific >= BITWISE_OR_EQUAL && specific <= BITWISE_XOR_EQUAL);
533    
534                case PREFIX_OR_INFIX_OPERATOR:
535                    switch( specific )
536                    {
537                        case POWER:
538                        case PLUS:
539                        case MINUS:
540                        case PREFIX_PLUS:
541                        case PREFIX_MINUS:
542                            return true;
543                    }
544                    break;
545    
546    
547                case KEYWORD:
548                    return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_GOTO;
549    
550                case SYMBOL:
551                    return specific >= NEWLINE && specific <= PIPE;
552    
553                case LITERAL:
554                    return specific >= STRING && specific <= DECIMAL_NUMBER;
555    
556                case NUMBER:
557                    return specific == INTEGER_NUMBER || specific == DECIMAL_NUMBER;
558    
559                case SIGN:
560                    switch( specific )
561                    {
562                        case PLUS:
563                        case MINUS:
564                            return true;
565                    }
566                    break;
567    
568                case NAMED_VALUE:
569                    return specific >= KEYWORD_TRUE && specific <= KEYWORD_NULL;
570    
571                case TRUTH_VALUE:
572                    return specific == KEYWORD_TRUE || specific == KEYWORD_FALSE;
573    
574                case TYPE_NAME:
575                    if( specific == IDENTIFIER )
576                    {
577                        return true;
578                    }
579    
580                    /* FALL THROUGH */
581    
582                case PRIMITIVE_TYPE:
583                    return specific >= KEYWORD_VOID && specific <= KEYWORD_CHAR;
584    
585                case CREATABLE_TYPE_NAME:
586                    if( specific == IDENTIFIER )
587                    {
588                        return true;
589                    }
590    
591                    /* FALL THROUGH */
592    
593                case CREATABLE_PRIMITIVE_TYPE:
594                    return specific >= KEYWORD_BOOLEAN && specific <= KEYWORD_CHAR;
595    
596                case LOOP:
597                    switch( specific )
598                    {
599                        case KEYWORD_DO:
600                        case KEYWORD_WHILE:
601                        case KEYWORD_FOR:
602                            return true;
603                    }
604                    break;
605    
606                case RESERVED_KEYWORD:
607                    return specific >= KEYWORD_CONST && specific <= KEYWORD_GOTO;
608    
609                case KEYWORD_IDENTIFIER:
610                    switch( specific )
611                    {
612                        case KEYWORD_CLASS:
613                        case KEYWORD_INTERFACE:
614                        case KEYWORD_MIXIN:
615                        case KEYWORD_DEF:
616                        case KEYWORD_DEFMACRO:
617                        case KEYWORD_IN:
618                        case KEYWORD_PROPERTY:
619                            return true;
620                    }
621                    break;
622    
623                case SYNTHETIC:
624                    return specific >= SYNTH_COMPILATION_UNIT && specific <= SYNTH_VARIABLE_DECLARATION;
625    
626                case TYPE_DECLARATION:
627                    return specific >= KEYWORD_CLASS && specific <= KEYWORD_MIXIN;
628    
629                case DECLARATION_MODIFIER:
630                    return specific >= KEYWORD_PRIVATE && specific <= KEYWORD_STATIC;
631    
632                case MATCHED_CONTAINER:
633                    switch( specific )
634                    {
635                        case LEFT_CURLY_BRACE:
636                        case RIGHT_CURLY_BRACE:
637                        case LEFT_SQUARE_BRACKET:
638                        case RIGHT_SQUARE_BRACKET:
639                        case LEFT_PARENTHESIS:
640                        case RIGHT_PARENTHESIS:
641                            return true;
642                    }
643                    break;
644    
645                case LEFT_OF_MATCHED_CONTAINER:
646                    switch( specific )
647                    {
648                        case LEFT_CURLY_BRACE:
649                        case LEFT_SQUARE_BRACKET:
650                        case LEFT_PARENTHESIS:
651                            return true;
652                    }
653                    break;
654    
655                case RIGHT_OF_MATCHED_CONTAINER:
656                    switch( specific )
657                    {
658                        case RIGHT_CURLY_BRACE:
659                        case RIGHT_SQUARE_BRACKET:
660                        case RIGHT_PARENTHESIS:
661                            return true;
662                    }
663                    break;
664    
665    
666                case PARAMETER_TERMINATORS:
667                    return specific == RIGHT_PARENTHESIS || specific == COMMA;
668    
669                case ARRAY_ITEM_TERMINATORS:
670                    return specific == RIGHT_SQUARE_BRACKET || specific == COMMA;
671    
672                case TYPE_LIST_TERMINATORS:
673                    switch( specific )
674                    {
675                        case KEYWORD_IMPLEMENTS:
676                        case KEYWORD_THROWS:
677                        case LEFT_CURLY_BRACE:
678                        case COMMA:
679                            return true;
680                    }
681                    break;
682    
683                case OPTIONAL_DATATYPE_FOLLOWERS:
684                    switch( specific )
685                    {
686                        case IDENTIFIER:
687                        case LEFT_SQUARE_BRACKET:
688                        case DOT:
689                            return true;
690                    }
691                    break;
692    
693                case SWITCH_BLOCK_TERMINATORS:
694                    if( specific == RIGHT_CURLY_BRACE )
695                    {
696                        return true;
697                    }
698    
699                    /* FALL THROUGH */
700    
701                case SWITCH_ENTRIES:
702                    return specific == KEYWORD_CASE || specific == KEYWORD_DEFAULT;
703    
704                case METHOD_CALL_STARTERS:
705                    if( specific >= STRING && specific <= DECIMAL_NUMBER )
706                    {
707                        return true;
708                    }
709                    switch( specific )
710                                    {
711                            case LEFT_PARENTHESIS:
712                        case GSTRING_START:
713                        case SYNTH_GSTRING:
714                        case KEYWORD_NEW:
715                            return true;
716                    }
717                    break;
718    
719                case UNSAFE_OVER_NEWLINES:
720                    if( ofType(specific, SYMBOL) )
721                    {
722                        switch( specific )
723                        {
724                            case LEFT_CURLY_BRACE:
725                            case LEFT_PARENTHESIS:
726                            case LEFT_SQUARE_BRACKET:
727                            case PLUS:
728                            case PLUS_PLUS:
729                            case MINUS:
730                            case MINUS_MINUS:
731                            case REGEX_PATTERN:
732                            case NOT:
733                                return true;
734                        }
735    
736                        return false;
737                    }
738    
739                    switch( specific )
740                    {
741                        case KEYWORD_INSTANCEOF:
742                        case GSTRING_EXPRESSION_START:
743                        case GSTRING_EXPRESSION_END:
744                        case GSTRING_END:
745                            return false;
746                    }
747    
748                    return true;
749    
750                case PRECLUDES_CAST_OPERATOR:
751                    switch( specific )
752                    {
753                        case PLUS:
754                        case MINUS:
755                        case PREFIX_MINUS:
756                        case PREFIX_MINUS_MINUS:
757                        case PREFIX_PLUS:
758                        case PREFIX_PLUS_PLUS:
759                        case LEFT_PARENTHESIS:
760                            return false;
761                    }
762    
763                    return !ofType( specific, COMPLEX_EXPRESSION );
764    
765    
766    
767    
768                case OPERATOR_EXPRESSION:
769                    return specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED;
770    
771                case SYNTH_EXPRESSION:
772                    switch( specific )
773                    {
774                        case SYNTH_CAST:
775                        case SYNTH_CLOSURE:
776                        case SYNTH_TERNARY:
777                            return true;
778                    }
779                    break;
780    
781                case KEYWORD_EXPRESSION:
782                    switch( specific )
783                    {
784                        case KEYWORD_NEW:
785                        case KEYWORD_THIS:
786                        case KEYWORD_SUPER:
787                        case KEYWORD_INSTANCEOF:
788                        case KEYWORD_TRUE:
789                        case KEYWORD_FALSE:
790                        case KEYWORD_NULL:
791                            return true;
792                    }
793                    break;
794    
795                case LITERAL_EXPRESSION:
796                    return specific >= STRING && specific <= DECIMAL_NUMBER;
797    
798                case ARRAY_EXPRESSION:
799                    return specific == LEFT_SQUARE_BRACKET;
800    
801                case EXPRESSION:
802                    if( specific >= DOT && specific <= RIGHT_SHIFT_UNSIGNED )
803                    {
804                        return true;
805                    }
806    
807                    if( specific >= STRING && specific <= DECIMAL_NUMBER )
808                    {
809                        return true;
810                    }
811    
812                    switch( specific )
813                    {
814                        case SYNTH_CAST:
815                        case SYNTH_CLOSURE:
816                        case SYNTH_TERNARY:
817                        case SYNTH_GSTRING:
818                        case KEYWORD_NEW:
819                        case KEYWORD_THIS:
820                        case KEYWORD_SUPER:
821                        case KEYWORD_INSTANCEOF:
822                        case KEYWORD_TRUE:
823                        case KEYWORD_FALSE:
824                        case KEYWORD_NULL:
825                        case LEFT_SQUARE_BRACKET:
826                            return true;
827                    }
828                    break;
829    
830                case COMPLEX_EXPRESSION:
831                    switch( specific )
832                    {
833                        case KEYWORD_NEW:
834                        case SYNTH_METHOD_CALL:
835                        case SYNTH_GSTRING:
836                        case SYNTH_LIST:
837                        case SYNTH_MAP:
838                        case SYNTH_CLOSURE:
839                        case SYNTH_TERNARY:
840                        case SYNTH_VARIABLE_DECLARATION:
841                            return true;
842                    }
843    
844                    /* FALL THROUGH */
845    
846                case SIMPLE_EXPRESSION:
847                    if( specific >= STRING && specific <= DECIMAL_NUMBER ) {
848                        return true;
849                    }
850    
851                    switch( specific ) {
852                        case KEYWORD_SUPER:
853                        case KEYWORD_THIS:
854                        case KEYWORD_TRUE:
855                        case KEYWORD_FALSE:
856                        case KEYWORD_NULL:
857                            return true;
858                    }
859    
860                    break;
861            }
862    
863            return false;
864        }
865    
866    
867    
868    
869      //---------------------------------------------------------------------------
870      // TYPE COERSIONS
871    
872    
873       /**
874        *  Given two types, returns true if the first can be viewed as the second.
875        *  NOTE that <code>canMean()</code> is orthogonal to <code>ofType()</code>.
876        */
877    
878        public static boolean canMean( int actual, int preferred ) {
879    
880            if( actual == preferred ) {
881                return true;
882            }
883    
884            switch( preferred ) {
885    
886                case SYNTH_PARAMETER_DECLARATION:
887                case IDENTIFIER:
888                    switch( actual ) {
889                        case IDENTIFIER:
890                        case KEYWORD_DEF:
891                        case KEYWORD_DEFMACRO:
892                        case KEYWORD_CLASS:
893                        case KEYWORD_INTERFACE:
894                        case KEYWORD_MIXIN:
895                            return true;
896                    }
897                    break;
898    
899                case SYNTH_CLASS:
900                case SYNTH_INTERFACE:
901                case SYNTH_MIXIN:
902                case SYNTH_METHOD:
903                case SYNTH_PROPERTY:
904                    return actual == IDENTIFIER;
905    
906                case SYNTH_LIST:
907                case SYNTH_MAP:
908                    return actual == LEFT_SQUARE_BRACKET;
909    
910                case SYNTH_CAST:
911                    return actual == LEFT_PARENTHESIS;
912    
913                case SYNTH_BLOCK:
914                case SYNTH_CLOSURE:
915                    return actual == LEFT_CURLY_BRACE;
916    
917                case SYNTH_LABEL:
918                    return actual == COLON;
919    
920                case SYNTH_VARIABLE_DECLARATION:
921                    return actual == IDENTIFIER;
922            }
923    
924            return false;
925        }
926    
927    
928    
929       /**
930        *  Converts a node from a generic type to a specific prefix type.
931        *  Throws a <code>GroovyBugError</code> if the type can't be converted
932        *  and requested.
933        */
934    
935        public static void makePrefix( CSTNode node, boolean throwIfInvalid ) {
936    
937            switch( node.getMeaning() ) {
938                case PLUS:
939                    node.setMeaning( PREFIX_PLUS );
940                    break;
941    
942                case MINUS:
943                    node.setMeaning( PREFIX_MINUS );
944                    break;
945    
946                case PLUS_PLUS:
947                    node.setMeaning( PREFIX_PLUS_PLUS );
948                    break;
949    
950                case MINUS_MINUS:
951                    node.setMeaning( PREFIX_MINUS_MINUS );
952                    break;
953    
954                default:
955                    if( throwIfInvalid ) {
956                        throw new GroovyBugError( "cannot convert to prefix for type [" + node.getMeaning() + "]" );
957                    }
958            }
959    
960        }
961    
962    
963    
964       /**
965        *  Converts a node from a generic type to a specific postfix type.
966        *  Throws a <code>GroovyBugError</code> if the type can't be converted.
967        */
968    
969        public static void makePostfix( CSTNode node, boolean throwIfInvalid ) {
970    
971            switch( node.getMeaning() ) {
972                case PLUS_PLUS:
973                    node.setMeaning( POSTFIX_PLUS_PLUS );
974                    break;
975    
976                case MINUS_MINUS:
977                    node.setMeaning( POSTFIX_MINUS_MINUS );
978                    break;
979    
980                default:
981                    if( throwIfInvalid ) {
982                        throw new GroovyBugError( "cannot convert to postfix for type [" + node.getMeaning() + "]" );
983                    }
984            }
985    
986        }
987    
988    
989    
990    
991      //---------------------------------------------------------------------------
992      // OPERATOR PRECEDENCE
993    
994    
995       /**
996        *  Returns the precendence of the specified operator.  Non-operator's will
997        *  receive -1 or a GroovyBugError, depending on your preference.
998        */
999    
1000        public static int getPrecedence( int type, boolean throwIfInvalid ) {
1001    
1002            switch( type ) {
1003    
1004                case LEFT_PARENTHESIS:
1005                    return 0;
1006    
1007                case EQUAL:
1008                case PLUS_EQUAL:
1009                case MINUS_EQUAL:
1010                case MULTIPLY_EQUAL:
1011                case DIVIDE_EQUAL:
1012                case INTDIV_EQUAL:
1013                case MOD_EQUAL:
1014                case POWER_EQUAL:
1015                case LOGICAL_OR_EQUAL:
1016                case LOGICAL_AND_EQUAL:
1017                case LEFT_SHIFT_EQUAL:
1018                case RIGHT_SHIFT_EQUAL:
1019                case RIGHT_SHIFT_UNSIGNED_EQUAL:
1020                case BITWISE_OR_EQUAL:
1021                case BITWISE_AND_EQUAL:
1022                case BITWISE_XOR_EQUAL:
1023                    return 5;
1024    
1025                case QUESTION:
1026                    return 10;
1027    
1028                case LOGICAL_OR:
1029                    return 15;
1030    
1031                case LOGICAL_AND:
1032                    return 20;
1033    
1034                case BITWISE_OR:
1035                case BITWISE_AND:
1036                case BITWISE_XOR:
1037                    return 22;
1038    
1039                case COMPARE_IDENTICAL:
1040                case COMPARE_NOT_IDENTICAL:
1041                    return 24;
1042    
1043                case COMPARE_NOT_EQUAL:
1044                case COMPARE_EQUAL:
1045                case COMPARE_LESS_THAN:
1046                case COMPARE_LESS_THAN_EQUAL:
1047                case COMPARE_GREATER_THAN:
1048                case COMPARE_GREATER_THAN_EQUAL:
1049                case COMPARE_TO:
1050                case FIND_REGEX:
1051                case MATCH_REGEX:
1052                case KEYWORD_INSTANCEOF:
1053                    return 25;
1054    
1055                case DOT_DOT:
1056                case DOT_DOT_DOT:
1057                    return 30;
1058    
1059                case LEFT_SHIFT:
1060                case RIGHT_SHIFT:
1061                case RIGHT_SHIFT_UNSIGNED:
1062                    return 35;
1063    
1064                case PLUS:
1065                case MINUS:
1066                    return 40;
1067    
1068                case MULTIPLY:
1069                case DIVIDE:
1070                case INTDIV:
1071                case MOD:
1072                    return 45;
1073    
1074                case NOT:
1075                case REGEX_PATTERN:
1076                    return 50;
1077    
1078                case SYNTH_CAST:
1079                    return 55;
1080    
1081                case PLUS_PLUS:
1082                case MINUS_MINUS:
1083                case PREFIX_PLUS_PLUS:
1084                case PREFIX_MINUS_MINUS:
1085                case POSTFIX_PLUS_PLUS:
1086                case POSTFIX_MINUS_MINUS:
1087                    return 65;
1088    
1089                case PREFIX_PLUS:
1090                case PREFIX_MINUS:
1091                    return 70;
1092    
1093                case POWER:
1094                    return 72;
1095    
1096                case SYNTH_METHOD:
1097                case LEFT_SQUARE_BRACKET:
1098                    return 75;
1099    
1100                case DOT:
1101                case NAVIGATE:
1102                    return 80;
1103    
1104                case KEYWORD_NEW:
1105                    return 85;
1106            }
1107    
1108            if( throwIfInvalid ) {
1109                throw new GroovyBugError( "precedence requested for non-operator" );
1110            }
1111    
1112            return -1;
1113        }
1114    
1115    
1116    
1117    
1118      //---------------------------------------------------------------------------
1119      // TEXTS
1120    
1121        private static final Map TEXTS  = new HashMap();  // symbol/keyword type -> text
1122        private static final Map LOOKUP = new HashMap();  // text -> symbol/keyword type
1123    
1124    
1125       /**
1126        *  Returns the type for the specified symbol/keyword text.  Returns UNKNOWN
1127        *  if the text isn't found.  You can filter finds on a type.
1128        */
1129    
1130        public static int lookup( String text, int filter ) {
1131            int type = UNKNOWN;
1132    
1133            if( LOOKUP.containsKey(text) ) {
1134                type = ((Integer)LOOKUP.get(text)).intValue();
1135                if( filter != UNKNOWN && !ofType(type, filter) ) {
1136                    type = UNKNOWN;
1137                }
1138            }
1139    
1140            return type;
1141        }
1142    
1143    
1144       /**
1145        *  Returns the type for the specified keyword text.  Returns UNKNOWN
1146        *  if the text isn't found.
1147        */
1148    
1149        public static int lookupKeyword( String text ) {
1150            return lookup( text, KEYWORD );
1151        }
1152    
1153    
1154       /**
1155        *  Returns the type for the specified symbol text.  Returns UNKNOWN
1156        *  if the text isn't found.
1157        */
1158    
1159        public static int lookupSymbol( String text ) {
1160            return lookup( text, SYMBOL );
1161        }
1162    
1163    
1164       /**
1165        *  Returns the text for the specified type.  Returns "" if the
1166        *  text isn't found.
1167        */
1168    
1169        public static String getText( int type ) {
1170            Integer key = new Integer( type );
1171            String text = "";
1172    
1173            if( TEXTS.containsKey(key) ) {
1174                text = (String)TEXTS.get( key );
1175            }
1176    
1177            return text;
1178        }
1179    
1180    
1181       /**
1182        *  Adds a element to the TEXTS and LOOKUP.
1183        */
1184    
1185        private static void addTranslation( String text, int type ) {
1186            Integer key = new Integer( type );
1187    
1188            TEXTS.put( key, text );
1189            LOOKUP.put( text, key );
1190        }
1191    
1192    
1193        static {
1194    
1195            //
1196            // SYMBOLS
1197    
1198            addTranslation( "\n"          , NEWLINE                     );
1199    
1200            addTranslation( "{"           , LEFT_CURLY_BRACE            );
1201            addTranslation( "}"           , RIGHT_CURLY_BRACE           );
1202            addTranslation( "["           , LEFT_SQUARE_BRACKET         );
1203            addTranslation( "]"           , RIGHT_SQUARE_BRACKET        );
1204            addTranslation( "("           , LEFT_PARENTHESIS            );
1205            addTranslation( ")"           , RIGHT_PARENTHESIS           );
1206    
1207            addTranslation( "."           , DOT                         );
1208            addTranslation( ".."          , DOT_DOT                     );
1209            addTranslation( "..."         , DOT_DOT_DOT                 );
1210    
1211            addTranslation( "->"          , NAVIGATE                    );
1212    
1213            addTranslation( "=~"          , FIND_REGEX                  );
1214            addTranslation( "==~"         , MATCH_REGEX                 );
1215            addTranslation( "~"           , REGEX_PATTERN               );
1216    
1217            addTranslation( "="           , EQUAL                       );
1218    
1219            addTranslation( "!="          , COMPARE_NOT_EQUAL           );
1220            addTranslation( "==="         , COMPARE_IDENTICAL           );
1221            addTranslation( "!=="         , COMPARE_NOT_IDENTICAL       );
1222            addTranslation( "=="          , COMPARE_EQUAL               );
1223            addTranslation( "<"           , COMPARE_LESS_THAN           );
1224            addTranslation( "<="          , COMPARE_LESS_THAN_EQUAL     );
1225            addTranslation( ">"           , COMPARE_GREATER_THAN        );
1226            addTranslation( ">="          , COMPARE_GREATER_THAN_EQUAL  );
1227            addTranslation( "<=>"         , COMPARE_TO                  );
1228    
1229            addTranslation( "!"           , NOT                         );
1230            addTranslation( "||"          , LOGICAL_OR                  );
1231            addTranslation( "&&"          , LOGICAL_AND                 );
1232    
1233            addTranslation( "||="         , LOGICAL_OR_EQUAL            );
1234            addTranslation( "&&="         , LOGICAL_AND_EQUAL           );
1235    
1236            addTranslation( "+"           , PLUS                        );
1237            addTranslation( "-"           , MINUS                       );
1238            addTranslation( "*"           , MULTIPLY                    );
1239            addTranslation( "/"           , DIVIDE                      );
1240            addTranslation( "\\"          , INTDIV                      );
1241            addTranslation( "%"           , MOD                         );
1242    
1243            addTranslation( "**"          , POWER                       );
1244    
1245            addTranslation( "+="          , PLUS_EQUAL                  );
1246            addTranslation( "-="          , MINUS_EQUAL                 );
1247            addTranslation( "*="          , MULTIPLY_EQUAL              );
1248            addTranslation( "/="          , DIVIDE_EQUAL                );
1249            addTranslation( "\\="         , INTDIV_EQUAL                );
1250            addTranslation( "%="          , MOD_EQUAL                   );
1251            addTranslation( "**="         , POWER_EQUAL                 );
1252    
1253            addTranslation( "++"          , PLUS_PLUS                   );
1254            addTranslation( "--"          , MINUS_MINUS                 );
1255    
1256            addTranslation( "<<"          , LEFT_SHIFT                  );
1257            addTranslation( ">>"          , RIGHT_SHIFT                 );
1258            addTranslation( ">>>"         , RIGHT_SHIFT_UNSIGNED        );
1259    
1260            addTranslation( "<<="         , LEFT_SHIFT_EQUAL            );
1261            addTranslation( ">>="         , RIGHT_SHIFT_EQUAL           );
1262            addTranslation( ">>>="        , RIGHT_SHIFT_UNSIGNED_EQUAL  );
1263    
1264            addTranslation( "&"           , BITWISE_AND                 );
1265            addTranslation( "^"           , BITWISE_XOR                 );
1266    
1267            addTranslation( "|="          , BITWISE_OR_EQUAL           );
1268            addTranslation( "&="          , BITWISE_AND_EQUAL           );
1269            addTranslation( "^="          , BITWISE_XOR_EQUAL           );
1270    
1271            addTranslation( ","           , COMMA                       );
1272            addTranslation( ":"           , COLON                       );
1273            addTranslation( ";"           , SEMICOLON                   );
1274            addTranslation( "?"           , QUESTION                    );
1275            addTranslation( "|"           , PIPE                        );
1276    
1277            addTranslation( "${}"         , GSTRING_EXPRESSION_START    );
1278    
1279    
1280            //
1281            // Keywords
1282    
1283            addTranslation( "abstract"    , KEYWORD_ABSTRACT            );
1284            addTranslation( "as"          , KEYWORD_AS                  );
1285            addTranslation( "assert"      , KEYWORD_ASSERT              );
1286            addTranslation( "break"       , KEYWORD_BREAK               );
1287            addTranslation( "case"        , KEYWORD_CASE                );
1288            addTranslation( "catch"       , KEYWORD_CATCH               );
1289            addTranslation( "class"       , KEYWORD_CLASS               );
1290            addTranslation( "const"       , KEYWORD_CONST               );
1291            addTranslation( "continue"    , KEYWORD_CONTINUE            );
1292            addTranslation( "def"         , KEYWORD_DEF                 );
1293            addTranslation( "defmacro"    , KEYWORD_DEF                 ); // xxx br defmacro
1294            addTranslation( "default"     , KEYWORD_DEFAULT             );
1295            addTranslation( "do"          , KEYWORD_DO                  );
1296            addTranslation( "else"        , KEYWORD_ELSE                );
1297            addTranslation( "extends"     , KEYWORD_EXTENDS             );
1298            addTranslation( "final"       , KEYWORD_FINAL               );
1299            addTranslation( "finally"     , KEYWORD_FINALLY             );
1300            addTranslation( "for"         , KEYWORD_FOR                 );
1301            addTranslation( "goto"        , KEYWORD_GOTO                );
1302            addTranslation( "if"          , KEYWORD_IF                  );
1303            addTranslation( "in"          , KEYWORD_IN                  );
1304            addTranslation( "implements"  , KEYWORD_IMPLEMENTS          );
1305            addTranslation( "import"      , KEYWORD_IMPORT              );
1306            addTranslation( "instanceof"  , KEYWORD_INSTANCEOF          );
1307            addTranslation( "interface"   , KEYWORD_INTERFACE           );
1308            addTranslation( "mixin"       , KEYWORD_MIXIN               );
1309            addTranslation( "native"      , KEYWORD_NATIVE              );
1310            addTranslation( "new"         , KEYWORD_NEW                 );
1311            addTranslation( "package"     , KEYWORD_PACKAGE             );
1312            addTranslation( "private"     , KEYWORD_PRIVATE             );
1313            addTranslation( "property"    , KEYWORD_PROPERTY            );
1314            addTranslation( "protected"   , KEYWORD_PROTECTED           );
1315            addTranslation( "public"      , KEYWORD_PUBLIC              );
1316            addTranslation( "return"      , KEYWORD_RETURN              );
1317            addTranslation( "static"      , KEYWORD_STATIC              );
1318            addTranslation( "super"       , KEYWORD_SUPER               );
1319            addTranslation( "switch"      , KEYWORD_SWITCH              );
1320            addTranslation( "synchronized", KEYWORD_SYNCHRONIZED        );
1321            addTranslation( "this"        , KEYWORD_THIS                );
1322            addTranslation( "throw"       , KEYWORD_THROW               );
1323            addTranslation( "throws"      , KEYWORD_THROWS              );
1324            addTranslation( "transient"   , KEYWORD_TRANSIENT           );
1325            addTranslation( "try"         , KEYWORD_TRY                 );
1326            addTranslation( "volatile"    , KEYWORD_VOLATILE            );
1327            addTranslation( "while"       , KEYWORD_WHILE               );
1328    
1329            addTranslation( "true"        , KEYWORD_TRUE                );
1330            addTranslation( "false"       , KEYWORD_FALSE               );
1331            addTranslation( "null"        , KEYWORD_NULL                );
1332    
1333            addTranslation( "void"        , KEYWORD_VOID                );
1334            addTranslation( "boolean"     , KEYWORD_BOOLEAN             );
1335            addTranslation( "byte"        , KEYWORD_BYTE                );
1336            addTranslation( "int"         , KEYWORD_INT                 );
1337            addTranslation( "short"       , KEYWORD_SHORT               );
1338            addTranslation( "long"        , KEYWORD_LONG                );
1339            addTranslation( "float"       , KEYWORD_FLOAT               );
1340            addTranslation( "double"      , KEYWORD_DOUBLE              );
1341            addTranslation( "char"        , KEYWORD_CHAR                );
1342        }
1343    
1344    
1345    
1346    
1347      //---------------------------------------------------------------------------
1348      // DESCRIPTIONS
1349    
1350    
1351        private static final Map DESCRIPTIONS = new HashMap();
1352    
1353    
1354       /**
1355        *  Gets the description for the specified type.
1356        */
1357    
1358        public static String getDescription( int type ) {
1359            Integer typeKey = new Integer(type);
1360    
1361            if (DESCRIPTIONS.containsKey(typeKey)) {
1362                return (String)DESCRIPTIONS.get(typeKey);
1363            }
1364    
1365            return "<>";
1366        }
1367    
1368    
1369       /**
1370        *  Adds a description to the set.
1371        */
1372    
1373        private static void addDescription(int type, String description) {
1374            addDescription(new Integer(type), description);
1375        }
1376    
1377    
1378       /**
1379        *  Adds a description to the set.
1380        */
1381    
1382        private static void addDescription(Integer type, String description) {
1383            if (description.startsWith("<") && description.endsWith(">")) {
1384                DESCRIPTIONS.put(type, description);
1385            }
1386            else {
1387                DESCRIPTIONS.put(type, '"' + description + '"');
1388            }
1389        }
1390    
1391    
1392        static {
1393    
1394            Iterator iterator = LOOKUP.keySet().iterator();
1395            while( iterator.hasNext() )
1396            {
1397                String text = (String)iterator.next();
1398                Integer key = (Integer)LOOKUP.get(text);
1399    
1400                addDescription( key, text );
1401            }
1402    
1403            addDescription( NEWLINE                     , "<newline>"        );
1404            addDescription( PREFIX_PLUS_PLUS            , "<prefix ++>"      );
1405            addDescription( POSTFIX_PLUS_PLUS           , "<postfix ++>"     );
1406            addDescription( PREFIX_MINUS_MINUS          , "<prefix -->"      );
1407            addDescription( POSTFIX_MINUS_MINUS         , "<postfix -->"     );
1408            addDescription( PREFIX_PLUS                 , "<positive>"       );
1409            addDescription( PREFIX_MINUS                , "<negative>"       );
1410    
1411            addDescription( STRING                      , "<string literal>" );
1412            addDescription( IDENTIFIER                  , "<identifier>"     );
1413            addDescription( INTEGER_NUMBER              , "<integer>"        );
1414            addDescription( DECIMAL_NUMBER              , "<decimal>"        );
1415    
1416            addDescription( SYNTH_COMPILATION_UNIT      , "<compilation unit>" );
1417            addDescription( SYNTH_CLASS                 , "<class>"          );
1418            addDescription( SYNTH_INTERFACE             , "<interface>"      );
1419            addDescription( SYNTH_MIXIN                 , "<mixin>"          );
1420            addDescription( SYNTH_METHOD                , "<method>"         );
1421            addDescription( SYNTH_METHOD_CALL           , "<method call>"    );
1422            addDescription( SYNTH_PROPERTY              , "<property>"       );
1423            addDescription( SYNTH_PARAMETER_DECLARATION , "<parameter>"      );
1424            addDescription( SYNTH_LIST                  , "<list>"           );
1425            addDescription( SYNTH_MAP                   , "<map>"            );
1426            addDescription( SYNTH_TUPLE                 , "<tuple>"          );
1427            addDescription( SYNTH_GSTRING               , "<gstring>"        );
1428            addDescription( SYNTH_CAST                  , "<cast>"           );
1429            addDescription( SYNTH_BLOCK                 , "<block>"          );
1430            addDescription( SYNTH_CLOSURE               , "<closure>"        );
1431            addDescription( SYNTH_TERNARY               , "<ternary>"        );
1432            addDescription( SYNTH_LABEL                 , "<label>"          );
1433            addDescription( SYNTH_VARIABLE_DECLARATION  , "<variable declaration>"       );
1434    
1435            addDescription( GSTRING_START               , "<start of gstring tokens>"    );
1436            addDescription( GSTRING_END                 , "<end of gstring tokens>"      );
1437            addDescription( GSTRING_EXPRESSION_START    , "<start of gstring expression>");
1438            addDescription( GSTRING_EXPRESSION_END      , "<end of gstring expression>"  );
1439    
1440            addDescription( ASSIGNMENT_OPERATOR         , "<assignment operator>"        );
1441            addDescription( COMPARISON_OPERATOR         , "<comparison operator>"        );
1442            addDescription( MATH_OPERATOR               , "<math operator>"              );
1443            addDescription( LOGICAL_OPERATOR            , "<logical operator>"           );
1444            addDescription( BITWISE_OPERATOR            , "<bitwise operator>"           );
1445            addDescription( RANGE_OPERATOR              , "<range operator>"             );
1446            addDescription( REGEX_COMPARISON_OPERATOR   , "<regex comparison operator>"  );
1447            addDescription( DEREFERENCE_OPERATOR        , "<dereference operator>"       );
1448            addDescription( PREFIX_OPERATOR             , "<prefix operator>"            );
1449            addDescription( POSTFIX_OPERATOR            , "<postfix operator>"           );
1450            addDescription( INFIX_OPERATOR              , "<infix operator>"             );
1451            addDescription( KEYWORD                     , "<keyword>"                    );
1452            addDescription( LITERAL                     , "<literal>"                    );
1453            addDescription( NUMBER                      , "<number>"                     );
1454            addDescription( NAMED_VALUE                 , "<named value>"                );
1455            addDescription( TRUTH_VALUE                 , "<truth value>"                );
1456            addDescription( PRIMITIVE_TYPE              , "<primitive type>"             );
1457            addDescription( CREATABLE_PRIMITIVE_TYPE    , "<creatable primitive type>"   );
1458            addDescription( LOOP                        , "<loop>"                       );
1459            addDescription( RESERVED_KEYWORD            , "<reserved keyword>"           );
1460            addDescription( SYNTHETIC                   , "<synthetic>"                  );
1461            addDescription( TYPE_DECLARATION            , "<type declaration>"           );
1462            addDescription( DECLARATION_MODIFIER        , "<declaration modifier>"       );
1463            addDescription( TYPE_NAME                   , "<type name>"                  );
1464            addDescription( CREATABLE_TYPE_NAME         , "<creatable type name>"        );
1465            addDescription( MATCHED_CONTAINER           , "<matched container>"          );
1466            addDescription( LEFT_OF_MATCHED_CONTAINER   , "<left of matched container>"  );
1467            addDescription( RIGHT_OF_MATCHED_CONTAINER  , "<right of matched container>" );
1468            addDescription( SWITCH_ENTRIES              , "<valid in a switch body>"     );
1469        }
1470    
1471    }