View Javadoc

    1   /*
    2    $Id: Types.java 2120 2005-04-12 15:05:51Z jstrachan $
    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 2120 2005-04-12 15:05:51Z jstrachan $
    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 }