View Javadoc

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