Home | History | Annotate | Download | only in jflex
      1 package org.jf.smali;
      2 
      3 import java.io.*;
      4 import org.antlr.runtime.*;
      5 import org.jf.util.*;
      6 import static org.jf.smali.smaliParser.*;
      7 
      8 %%
      9 
     10 %public
     11 %class smaliFlexLexer
     12 %implements TokenSource
     13 %implements LexerErrorInterface
     14 %type Token
     15 %unicode
     16 %line
     17 %column
     18 %char
     19 
     20 %{
     21     private StringBuffer sb = new StringBuffer();
     22     private String stringOrCharError = null;
     23     private int stringStartLine;
     24     private int stringStartCol;
     25     private int stringStartChar;
     26 
     27     private int lexerErrors = 0;
     28 
     29     private File sourceFile;
     30 
     31     private boolean suppressErrors;
     32 
     33     public Token nextToken() {
     34         try {
     35             Token token = yylex();
     36             if (token instanceof InvalidToken) {
     37                 InvalidToken invalidToken = (InvalidToken)token;
     38                 if (!suppressErrors) {
     39                     System.err.println(getErrorHeader(invalidToken) + " Error for input '" +
     40                         invalidToken.getText() + "': " + invalidToken.getMessage());
     41                 }
     42                 lexerErrors++;
     43             }
     44             return token;
     45         }
     46         catch (java.io.IOException e) {
     47             System.err.println("shouldn't happen: " + e.getMessage());
     48             return Token.EOF_TOKEN;
     49         }
     50     }
     51 
     52     public void setLine(int line) {
     53         this.yyline = line-1;
     54     }
     55 
     56     public void setColumn(int column) {
     57         this.yycolumn = column;
     58     }
     59 
     60     public int getLine() {
     61         return this.yyline+1;
     62     }
     63 
     64     public int getColumn() {
     65         return this.yycolumn;
     66     }
     67 
     68     public void setSuppressErrors(boolean suppressErrors) {
     69         this.suppressErrors = suppressErrors;
     70     }
     71 
     72     public void setSourceFile(File sourceFile) {
     73         this.sourceFile = sourceFile;
     74     }
     75 
     76     public String getSourceName() {
     77         try {
     78             return  PathUtil.getRelativeFile(new File("."), sourceFile).getPath();
     79         } catch (IOException ex) {
     80             return sourceFile.getAbsolutePath();
     81         }
     82     }
     83 
     84     public int getNumberOfSyntaxErrors() {
     85         return lexerErrors;
     86     }
     87 
     88     private Token newToken(int type, String text, boolean hidden) {
     89         CommonToken token = new CommonToken(type, text);
     90         if (hidden) {
     91             token.setChannel(Token.HIDDEN_CHANNEL);
     92         }
     93 
     94         token.setStartIndex(yychar);
     95         token.setStopIndex(yychar + yylength() - 1);
     96         token.setLine(getLine());
     97         token.setCharPositionInLine(getColumn());
     98         return token;
     99     }
    100 
    101     private Token newToken(int type, String text) {
    102         return newToken(type, text, false);
    103     }
    104 
    105     private Token newToken(int type, boolean hidden) {
    106         return newToken(type, yytext(), hidden);
    107     }
    108 
    109     private Token newToken(int type) {
    110         return newToken(type, yytext(), false);
    111     }
    112 
    113     private Token invalidToken(String message, String text) {
    114         InvalidToken token = new InvalidToken(message, text);
    115 
    116         token.setStartIndex(yychar);
    117         token.setStopIndex(yychar + yylength() - 1);
    118         token.setLine(getLine());
    119         token.setCharPositionInLine(getColumn());
    120 
    121         return token;
    122     }
    123 
    124     private Token invalidToken(String message) {
    125         return invalidToken(message, yytext());
    126     }
    127 
    128     private void beginStringOrChar(int state) {
    129         yybegin(state);
    130         sb.setLength(0);
    131         stringStartLine = getLine();
    132         stringStartCol = getColumn();
    133         stringStartChar = yychar;
    134         stringOrCharError = null;
    135     }
    136 
    137     private Token endStringOrChar(int type) {
    138         yybegin(YYINITIAL);
    139 
    140         if (stringOrCharError != null) {
    141             return invalidStringOrChar(stringOrCharError);
    142         }
    143 
    144         CommonToken token = new CommonToken(type, sb.toString());
    145         token.setStartIndex(stringStartChar);
    146         token.setStopIndex(yychar + yylength() - 1);
    147         token.setLine(stringStartLine);
    148         token.setCharPositionInLine(stringStartCol);
    149         return token;
    150     }
    151 
    152     private void setStringOrCharError(String message) {
    153         if (stringOrCharError == null) {
    154             stringOrCharError = message;
    155         }
    156     }
    157 
    158     private Token invalidStringOrChar(String message) {
    159         yybegin(YYINITIAL);
    160 
    161         InvalidToken token = new InvalidToken(message, sb.toString());
    162         token.setStartIndex(stringStartChar);
    163         token.setStopIndex(yychar + yylength() - 1);
    164         token.setLine(stringStartLine);
    165         token.setCharPositionInLine(stringStartCol);
    166         return token;
    167     }
    168 
    169     public String getErrorHeader(InvalidToken token) {
    170         return getSourceName()+"["+ token.getLine()+","+token.getCharPositionInLine()+"]";
    171     }
    172 %}
    173 
    174 HexPrefix = 0 [xX]
    175 
    176 HexDigit = [0-9a-fA-F]
    177 HexDigits = [0-9a-fA-F]{4}
    178 FewerHexDigits = [0-9a-fA-F]{0,3}
    179 
    180 Integer1 = 0
    181 Integer2 = [1-9] [0-9]*
    182 Integer3 = 0 [0-7]+
    183 Integer4 = {HexPrefix} {HexDigit}+
    184 Integer = {Integer1} | {Integer2} | {Integer3} | {Integer4}
    185 
    186 DecimalExponent = [eE] -? [0-9]+
    187 
    188 BinaryExponent = [pP] -? [0-9]+
    189 
    190 /*This can either be a floating point number or an identifier*/
    191 FloatOrID1 = -? [0-9]+ {DecimalExponent}
    192 FloatOrID2 = -? {HexPrefix} {HexDigit}+ {BinaryExponent}
    193 FloatOrID3 = -? [iI][nN][fF][iI][nN][iI][tT][yY]
    194 FloatOrID4 = [nN][aA][nN]
    195 FloatOrID =  {FloatOrID1} | {FloatOrID2} | {FloatOrID3} | {FloatOrID4}
    196 
    197 
    198 /*This can only be a float and not an identifier, due to the decimal point*/
    199 Float1 = -? [0-9]+ "." [0-9]* {DecimalExponent}?
    200 Float2 = -? "." [0-9]+ {DecimalExponent}?
    201 Float3 = -? {HexPrefix} {HexDigit}+ "." {HexDigit}* {BinaryExponent}
    202 Float4 = -? {HexPrefix} "." {HexDigit}+ {BinaryExponent}
    203 Float =  {Float1} | {Float2} | {Float3} | {Float4}
    204 
    205 HighSurrogate = [\ud800-\udbff]
    206 
    207 LowSurrogate = [\udc00-\udfff]
    208 
    209 SimpleNameCharacter = ({HighSurrogate} {LowSurrogate}) | [A-Za-z0-9$\-_\u00a1-\u1fff\u2010-\u2027\u2030-\ud7ff\ue000-\uffef]
    210 
    211 SimpleName = {SimpleNameCharacter}+
    212 
    213 PrimitiveType = [ZBSCIJFD]
    214 
    215 ClassDescriptor = L ({SimpleName} "/")* {SimpleName} ;
    216 
    217 ArrayDescriptor = "[" + ({PrimitiveType} | {ClassDescriptor})
    218 
    219 Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
    220 
    221 
    222 %state STRING
    223 %state CHAR
    224 
    225 %%
    226 
    227 /*Directives*/
    228 <YYINITIAL>
    229 {
    230     ".class" { return newToken(CLASS_DIRECTIVE); }
    231     ".super" { return newToken(SUPER_DIRECTIVE); }
    232     ".implements" { return newToken(IMPLEMENTS_DIRECTIVE); }
    233     ".source" { return newToken(SOURCE_DIRECTIVE); }
    234     ".field" { return newToken(FIELD_DIRECTIVE); }
    235     ".end field" { return newToken(END_FIELD_DIRECTIVE); }
    236     ".subannotation" { return newToken(SUBANNOTATION_DIRECTIVE); }
    237     ".end subannotation" { return newToken(END_SUBANNOTATION_DIRECTIVE); }
    238     ".annotation" { return newToken(ANNOTATION_DIRECTIVE); }
    239     ".end annotation" { return newToken(END_ANNOTATION_DIRECTIVE); }
    240     ".enum" { return newToken(ENUM_DIRECTIVE); }
    241     ".method" { return newToken(METHOD_DIRECTIVE); }
    242     ".end method" { return newToken(END_METHOD_DIRECTIVE); }
    243     ".registers" { return newToken(REGISTERS_DIRECTIVE); }
    244     ".locals" { return newToken(LOCALS_DIRECTIVE); }
    245     ".array-data" { return newToken(ARRAY_DATA_DIRECTIVE); }
    246     ".end array-data" { return newToken(END_ARRAY_DATA_DIRECTIVE); }
    247     ".packed-switch" { return newToken(PACKED_SWITCH_DIRECTIVE); }
    248     ".end packed-switch" { return newToken(END_PACKED_SWITCH_DIRECTIVE); }
    249     ".sparse-switch" { return newToken(SPARSE_SWITCH_DIRECTIVE); }
    250     ".end sparse-switch" { return newToken(END_SPARSE_SWITCH_DIRECTIVE); }
    251     ".catch" { return newToken(CATCH_DIRECTIVE); }
    252     ".catchall" { return newToken(CATCHALL_DIRECTIVE); }
    253     ".line" { return newToken(LINE_DIRECTIVE); }
    254     ".parameter" { return newToken(PARAMETER_DIRECTIVE); }
    255     ".end parameter" { return newToken(END_PARAMETER_DIRECTIVE); }
    256     ".local" { return newToken(LOCAL_DIRECTIVE); }
    257     ".end local" { return newToken(END_LOCAL_DIRECTIVE); }
    258     ".restart local" { return newToken(RESTART_LOCAL_DIRECTIVE); }
    259     ".prologue" { return newToken(PROLOGUE_DIRECTIVE); }
    260     ".epilogue" { return newToken(EPILOGUE_DIRECTIVE); }
    261 
    262     ".end" { return invalidToken("Invalid directive"); }
    263     ".end " [a-zA-z0-9\-_]+ { return invalidToken("Invalid directive"); }
    264     ".restart" { return invalidToken("Invalid directive"); }
    265     ".restart " [a-zA-z0-9\-_]+ { return invalidToken("Invalid directive"); }
    266 }
    267 
    268 /*Literals*/
    269 <YYINITIAL> {
    270     -? {Integer} { return newToken(INTEGER_LITERAL); }
    271     -? {Integer} [lL] { return newToken(LONG_LITERAL); }
    272     -? {Integer} [sS] { return newToken(SHORT_LITERAL); }
    273     -? {Integer} [tT] { return newToken(BYTE_LITERAL); }
    274 
    275     {FloatOrID} [fF] | -? [0-9]+ [fF] { return newToken(FLOAT_LITERAL_OR_ID); }
    276     {FloatOrID} [dD]? | -? [0-9]+ [dD] { return newToken(DOUBLE_LITERAL_OR_ID); }
    277     {Float} [fF] { return newToken(FLOAT_LITERAL); }
    278     {Float} [dD]? { return newToken(DOUBLE_LITERAL); }
    279 
    280     "true"|"false" { return newToken(BOOL_LITERAL); }
    281     "null" { return newToken(NULL_LITERAL); }
    282 
    283     "\"" { beginStringOrChar(STRING); sb.append('"'); }
    284 
    285     ' { beginStringOrChar(CHAR); sb.append('\''); }
    286 }
    287 
    288 <STRING> {
    289     "\""  { sb.append('"'); return endStringOrChar(STRING_LITERAL); }
    290 
    291     [^\r\n\"\\]+ { sb.append(yytext()); }
    292     "\\b" { sb.append('\b'); }
    293     "\\t" { sb.append('\t'); }
    294     "\\n" { sb.append('\n'); }
    295     "\\f" { sb.append('\f'); }
    296     "\\r" { sb.append('\r'); }
    297     "\\'" { sb.append('\''); }
    298     "\\\"" { sb.append('"'); }
    299     "\\\\" { sb.append('\\'); }
    300     "\\u" {HexDigits} { sb.append((char)Integer.parseInt(yytext().substring(2,6), 16)); }
    301 
    302     "\\u" {FewerHexDigits} {
    303         sb.append(yytext());
    304         setStringOrCharError("Invalid \\u sequence. \\u must be followed by 4 hex digits");
    305     }
    306 
    307     "\\" [^btnfr'\"\\u] {
    308         sb.append(yytext());
    309         setStringOrCharError("Invalid escape sequence " + yytext());
    310     }
    311 
    312     [\r\n] { return invalidStringOrChar("Unterminated string literal"); }
    313     <<EOF>> { return invalidStringOrChar("Unterminated string literal"); }
    314 }
    315 
    316 <CHAR> {
    317     ' {
    318         sb.append('\'');
    319         if (sb.length() == 2) {
    320             return invalidStringOrChar("Empty character literal");
    321         } else if (sb.length() > 3) {
    322             return invalidStringOrChar("Character literal with multiple chars");
    323         }
    324 
    325         return endStringOrChar(CHAR_LITERAL);
    326     }
    327 
    328     [^\r\n'\\]+ { sb.append(yytext()); }
    329     "\\b" { sb.append('\b'); }
    330     "\\t" { sb.append('\t'); }
    331     "\\n" { sb.append('\n'); }
    332     "\\f" { sb.append('\f'); }
    333     "\\r" { sb.append('\r'); }
    334     "\\'" { sb.append('\''); }
    335     "\\\"" { sb.append('"'); }
    336     "\\\\" { sb.append('\\'); }
    337     "\\u" {HexDigits} { sb.append((char)Integer.parseInt(yytext().substring(2,6), 16)); }
    338 
    339     "\\u" {HexDigit}* {
    340         sb.append(yytext());
    341         setStringOrCharError("Invalid \\u sequence. \\u must be followed by exactly 4 hex digits");
    342     }
    343 
    344     "\\" [^btnfr'\"\\u] {
    345         sb.append(yytext());
    346         setStringOrCharError("Invalid escape sequence " + yytext());
    347     }
    348 
    349     [\r\n] { return invalidStringOrChar("Unterminated character literal"); }
    350     <<EOF>> { return invalidStringOrChar("Unterminated character literal"); }
    351 }
    352 
    353 /*Misc*/
    354 <YYINITIAL> {
    355     [vp] [0-9]+ { return newToken(REGISTER); }
    356 
    357     "build" | "runtime" | "system" {
    358         return newToken(ANNOTATION_VISIBILITY);
    359     }
    360 
    361     "public" | "private" | "protected" | "static" | "final" | "synchronized" | "bridge" | "varargs" | "native" |
    362     "abstract" | "strictfp" | "synthetic" | "constructor" | "declared-synchronized" | "interface" | "enum" |
    363     "annotation" | "volatile" | "transient" {
    364         return newToken(ACCESS_SPEC);
    365     }
    366 
    367     "no-error" | "generic-error" | "no-such-class" | "no-such-field" | "no-such-method" | "illegal-class-access" |
    368     "illegal-field-access" | "illegal-method-access" | "class-change-error" | "instantiation-error" {
    369         return newToken(VERIFICATION_ERROR_TYPE);
    370     }
    371 
    372     "vtable@0x" {HexDigit}+ { return newToken(VTABLE_OFFSET); }
    373     "field@0x" {HexDigit}+ { return newToken(FIELD_OFFSET); }
    374 
    375     "+" {Integer} { return newToken(OFFSET); }
    376 
    377     # [^\r\n]* { return newToken(LINE_COMMENT, true); }
    378 }
    379 
    380 /*Instructions*/
    381 <YYINITIAL> {
    382     "goto" {
    383         return newToken(INSTRUCTION_FORMAT10t);
    384     }
    385 
    386     "return-void" | "nop" {
    387         return newToken(INSTRUCTION_FORMAT10x);
    388     }
    389 
    390     "const/4" {
    391         return newToken(INSTRUCTION_FORMAT11n);
    392     }
    393 
    394     "move-result" | "move-result-wide" | "move-result-object" | "move-exception" | "return" | "return-wide" |
    395     "return-object" | "monitor-enter" | "monitor-exit" | "throw" {
    396         return newToken(INSTRUCTION_FORMAT11x);
    397     }
    398 
    399     "move" | "move-wide" | "move-object" | "array-length" | "neg-int" | "not-int" | "neg-long" | "not-long" |
    400     "neg-float" | "neg-double" | "int-to-long" | "int-to-float" | "int-to-double" | "long-to-int" | "long-to-float" |
    401     "long-to-double" | "float-to-int" | "float-to-long" | "float-to-double" | "double-to-int" | "double-to-long" |
    402     "double-to-float" | "int-to-byte" | "int-to-char" | "int-to-short" {
    403         return newToken(INSTRUCTION_FORMAT12x_OR_ID);
    404     }
    405 
    406     "add-int/2addr" | "sub-int/2addr" | "mul-int/2addr" | "div-int/2addr" | "rem-int/2addr" | "and-int/2addr" |
    407     "or-int/2addr" | "xor-int/2addr" | "shl-int/2addr" | "shr-int/2addr" | "ushr-int/2addr" | "add-long/2addr" |
    408     "sub-long/2addr" | "mul-long/2addr" | "div-long/2addr" | "rem-long/2addr" | "and-long/2addr" | "or-long/2addr" |
    409     "xor-long/2addr" | "shl-long/2addr" | "shr-long/2addr" | "ushr-long/2addr" | "add-float/2addr" |
    410     "sub-float/2addr" | "mul-float/2addr" | "div-float/2addr" | "rem-float/2addr" | "add-double/2addr" |
    411     "sub-double/2addr" | "mul-double/2addr" | "div-double/2addr" | "rem-double/2addr" {
    412         return newToken(INSTRUCTION_FORMAT12x);
    413     }
    414 
    415     "throw-verification-error" {
    416         return newToken(INSTRUCTION_FORMAT20bc);
    417     }
    418 
    419     "goto/16" {
    420         return newToken(INSTRUCTION_FORMAT20t);
    421     }
    422 
    423     "sget" | "sget-wide" | "sget-object" | "sget-boolean" | "sget-byte" | "sget-char" | "sget-short" | "sput" |
    424     "sput-wide" | "sput-object" | "sput-boolean" | "sput-byte" | "sput-char" | "sput-short" {
    425         return newToken(INSTRUCTION_FORMAT21c_FIELD);
    426     }
    427 
    428     "sget-volatile" | "sget-wide-volatile" | "sget-object-volatile" | "sput-volatile" | "sput-wide-volatile" |
    429     "sput-object-volatile" {
    430         return newToken(INSTRUCTION_FORMAT21c_FIELD_ODEX);
    431     }
    432 
    433     "const-string" {
    434         return newToken(INSTRUCTION_FORMAT21c_STRING);
    435     }
    436 
    437     "check-cast" | "new-instance" | "const-class" {
    438         return newToken(INSTRUCTION_FORMAT21c_TYPE);
    439     }
    440 
    441     "const/high16" | "const-wide/high16" {
    442         return newToken(INSTRUCTION_FORMAT21h);
    443     }
    444 
    445     "const/16" | "const-wide/16" {
    446         return newToken(INSTRUCTION_FORMAT21s);
    447     }
    448 
    449     "if-eqz" | "if-nez" | "if-ltz" | "if-gez" | "if-gtz" | "if-lez" {
    450         return newToken(INSTRUCTION_FORMAT21t);
    451     }
    452 
    453     "add-int/lit8" | "rsub-int/lit8" | "mul-int/lit8" | "div-int/lit8" | "rem-int/lit8" | "and-int/lit8" |
    454     "or-int/lit8" | "xor-int/lit8" | "shl-int/lit8" | "shr-int/lit8" | "ushr-int/lit8" {
    455         return newToken(INSTRUCTION_FORMAT22b);
    456     }
    457 
    458     "iget" | "iget-wide" | "iget-object" | "iget-boolean" | "iget-byte" | "iget-char" | "iget-short" | "iput" |
    459     "iput-wide" | "iput-object" | "iput-boolean" | "iput-byte" | "iput-char" | "iput-short" {
    460         return newToken(INSTRUCTION_FORMAT22c_FIELD);
    461     }
    462 
    463     "iget-volatile" | "iget-wide-volatile" | "iget-object-volatile" | "iput-volatile" | "iput-wide-volatile" |
    464     "iput-object-volatile" {
    465         return newToken(INSTRUCTION_FORMAT22c_FIELD_ODEX);
    466     }
    467 
    468     "instance-of" | "new-array" {
    469         return newToken(INSTRUCTION_FORMAT22c_TYPE);
    470     }
    471 
    472     "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" {
    473         return newToken(INSTRUCTION_FORMAT22cs_FIELD);
    474     }
    475 
    476     "rsub-int" {
    477         return newToken(INSTRUCTION_FORMAT22s_OR_ID);
    478     }
    479 
    480     "add-int/lit16" | "mul-int/lit16" | "div-int/lit16" | "rem-int/lit16" | "and-int/lit16" | "or-int/lit16" |
    481     "xor-int/lit16" {
    482         return newToken(INSTRUCTION_FORMAT22s);
    483     }
    484 
    485     "if-eq" | "if-ne" | "if-lt" | "if-ge" | "if-gt" | "if-le" {
    486         return newToken(INSTRUCTION_FORMAT22t);
    487     }
    488 
    489     "move/from16" | "move-wide/from16" | "move-object/from16" {
    490         return newToken(INSTRUCTION_FORMAT22x);
    491     }
    492 
    493     "cmpl-float" | "cmpg-float" | "cmpl-double" | "cmpg-double" | "cmp-long" | "aget" | "aget-wide" | "aget-object" |
    494     "aget-boolean" | "aget-byte" | "aget-char" | "aget-short" | "aput" | "aput-wide" | "aput-object" | "aput-boolean" |
    495     "aput-byte" | "aput-char" | "aput-short" | "add-int" | "sub-int" | "mul-int" | "div-int" | "rem-int" | "and-int" |
    496     "or-int" | "xor-int" | "shl-int" | "shr-int" | "ushr-int" | "add-long" | "sub-long" | "mul-long" | "div-long" |
    497     "rem-long" | "and-long" | "or-long" | "xor-long" | "shl-long" | "shr-long" | "ushr-long" | "add-float" |
    498     "sub-float" | "mul-float" | "div-float" | "rem-float" | "add-double" | "sub-double" | "mul-double" | "div-double" |
    499     "rem-double" {
    500         return newToken(INSTRUCTION_FORMAT23x);
    501     }
    502 
    503     "goto/32" {
    504         return newToken(INSTRUCTION_FORMAT30t);
    505     }
    506 
    507     "const-string/jumbo" {
    508         return newToken(INSTRUCTION_FORMAT31c);
    509     }
    510 
    511     "const" {
    512         return newToken(INSTRUCTION_FORMAT31i_OR_ID);
    513     }
    514 
    515     "const-wide/32" {
    516         return newToken(INSTRUCTION_FORMAT31i);
    517     }
    518 
    519     "fill-array-data" | "packed-switch" | "sparse-switch" {
    520         return newToken(INSTRUCTION_FORMAT31t);
    521     }
    522 
    523     "move/16" | "move-wide/16" | "move-object/16" {
    524         return newToken(INSTRUCTION_FORMAT32x);
    525     }
    526 
    527     "invoke-virtual" | "invoke-super" | "invoke-direct" | "invoke-static" | "invoke-interface" {
    528         return newToken(INSTRUCTION_FORMAT35c_METHOD);
    529     }
    530 
    531     "filled-new-array" {
    532         return newToken(INSTRUCTION_FORMAT35c_TYPE);
    533     }
    534 
    535     "invoke-direct-empty" {
    536         return newToken(INSTRUCTION_FORMAT35s_METHOD);
    537     }
    538 
    539     "execute-inline" | "invoke-virtual-quick" | "invoke-super-quick" {
    540         return newToken(INSTRUCTION_FORMAT35ms_METHOD);
    541     }
    542 
    543     "invoke-virtual/range" | "invoke-super/range" | "invoke-direct/range" | "invoke-static/range" |
    544     "invoke-interface/range" {
    545         return newToken(INSTRUCTION_FORMAT3rc_METHOD);
    546     }
    547 
    548     "filled-new-array/range" {
    549         return newToken(INSTRUCTION_FORMAT3rc_TYPE);
    550     }
    551 
    552     "execute-inline/range" | "invoke-virtual-quick/range" | "invoke-super-quick/range" {
    553         return newToken(INSTRUCTION_FORMAT3rms_METHOD);
    554     }
    555 
    556     "const-wide" {
    557         return newToken(INSTRUCTION_FORMAT51l);
    558     }
    559 }
    560 
    561 /*Types*/
    562 <YYINITIAL> {
    563     {PrimitiveType} { return newToken(PRIMITIVE_TYPE); }
    564     V { return newToken(VOID_TYPE); }
    565     {ClassDescriptor} { return newToken(CLASS_DESCRIPTOR); }
    566     {ArrayDescriptor} { return newToken(ARRAY_DESCRIPTOR); }
    567     {PrimitiveType} {PrimitiveType}+ { return newToken(PARAM_LIST_OR_ID); }
    568     {Type} {Type}+ { return newToken(PARAM_LIST); }
    569     {SimpleName} { return newToken(SIMPLE_NAME); }
    570     "<init>" | "<clinit>" { return newToken(METHOD_NAME); }
    571 }
    572 
    573 /*Symbols/Whitespace/EOF*/
    574 <YYINITIAL> {
    575     ".." { return newToken(DOTDOT); }
    576     "->" { return newToken(ARROW); }
    577     "=" { return newToken(EQUAL); }
    578     ":" { return newToken(COLON); }
    579     "," { return newToken(COMMA); }
    580     "{" { return newToken(OPEN_BRACE); }
    581     "}" { return newToken(CLOSE_BRACE); }
    582     "(" { return newToken(OPEN_PAREN); }
    583     ")" { return newToken(CLOSE_PAREN); }
    584     [\r\n\t ]+ { return newToken(WHITE_SPACE, true); }
    585     <<EOF>> { return newToken(EOF); }
    586 }
    587 
    588 /*catch all*/
    589 <YYINITIAL> {
    590     "." { return invalidToken("Invalid directive"); }
    591     "." [a-zA-z\-_] { return invalidToken("Invalid directive"); }
    592     "." [a-zA-z\-_] [a-zA-z0-9\-_]* { return invalidToken("Invalid directive"); }
    593     . { return invalidToken("Invalid text"); }
    594 }
    595