View Javadoc

1   /*
2    $Id: Types.java,v 1.11 2005/04/12 15:04:59 jstrachan Exp $
3   
4    Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
5   
6    Redistribution and use of this software and associated documentation
7    ("Software"), with or without modification, are permitted provided
8    that the following conditions are met:
9   
10   1. Redistributions of source code must retain copyright
11      statements and notices.  Redistributions must also contain a
12      copy of this document.
13  
14   2. Redistributions in binary form must reproduce the
15      above copyright notice, this list of conditions and the
16      following disclaimer in the documentation and/or other
17      materials provided with the distribution.
18  
19   3. The name "groovy" must not be used to endorse or promote
20      products derived from this Software without prior written
21      permission of The Codehaus.  For written permission,
22      please contact info@codehaus.org.
23  
24   4. Products derived from this Software may not be called "groovy"
25      nor may "groovy" appear in their names without prior written
26      permission of The Codehaus. "groovy" is a registered
27      trademark of The Codehaus.
28  
29   5. Due credit should be given to The Codehaus -
30      http://groovy.codehaus.org/
31  
32   THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
33   ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
34   NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
35   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
36   THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43   OF THE POSSIBILITY OF SUCH DAMAGE.
44  
45   */
46  
47  package org.codehaus.groovy.syntax;
48  
49  import java.util.HashMap;
50  import java.util.Iterator;
51  import java.util.Map;
52  
53  import org.codehaus.groovy.GroovyBugError;
54  
55  
56  /***
57   *  Typing information for the CST system.  The types here are those
58   *  used by CSTNode, Token, and Reduction.
59   *
60   *  @author <a href="mailto:bob@werken.com">bob mcwhirter</a>
61   *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
62   *
63   *  @version $Id: Types.java,v 1.11 2005/04/12 15:04:59 jstrachan Exp $
64   */
65  
66  public class Types
67  {
68  
69  
70    //---------------------------------------------------------------------------
71    // TYPES: NOTE THAT ORDERING AND VALUES ARE IMPORTANT TO LOCAL ROUTINES!
72  
73  
74      //
75      // SPECIAL TOKENS
76  
77      public static final int EOF                         = -1;    // end of file
78      public static final int UNKNOWN                     = 0;     // the unknown token
79  
80  
81      //
82      // RELEVANT WHITESPACE
83  
84      public static final int NEWLINE                     = 5;     // \n
85  
86  
87      //
88      // OPERATORS AND OTHER MARKERS
89  
90      public static final int LEFT_CURLY_BRACE            = 10;    // {
91      public static final int RIGHT_CURLY_BRACE           = 20;    // }
92      public static final int LEFT_SQUARE_BRACKET         = 30;    // [
93      public static final int RIGHT_SQUARE_BRACKET        = 40;    // ]
94      public static final int LEFT_PARENTHESIS            = 50;    // (
95      public static final int RIGHT_PARENTHESIS           = 60;    // )
96  
97      public static final int DOT                         = 70;    // .
98      public static final int DOT_DOT                     = 75;    // ..
99      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 }