smaliLexer.flex revision 4a5692f8275048c564abc617b91ae72bb008fcca
1package org.jf.smali;
2
3import java.io.*;
4import org.antlr.runtime.*;
5import org.jf.util.*;
6import 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
174HexPrefix = 0 [xX]
175
176HexDigit = [0-9a-fA-F]
177HexDigits = [0-9a-fA-F]{4}
178FewerHexDigits = [0-9a-fA-F]{0,3}
179
180Integer1 = 0
181Integer2 = [1-9] [0-9]*
182Integer3 = 0 [0-7]+
183Integer4 = {HexPrefix} {HexDigit}+
184Integer = {Integer1} | {Integer2} | {Integer3} | {Integer4}
185
186DecimalExponent = [eE] -? [0-9]+
187
188BinaryExponent = [pP] -? [0-9]+
189
190/*This can either be a floating point number or an identifier*/
191FloatOrID1 = -? [0-9]+ {DecimalExponent}
192FloatOrID2 = -? {HexPrefix} {HexDigit}+ {BinaryExponent}
193FloatOrID3 = -? [iI][nN][fF][iI][nN][iI][tT][yY]
194FloatOrID4 = [nN][aA][nN]
195FloatOrID =  {FloatOrID1} | {FloatOrID2} | {FloatOrID3} | {FloatOrID4}
196
197
198/*This can only be a float and not an identifier, due to the decimal point*/
199Float1 = -? [0-9]+ "." [0-9]* {DecimalExponent}?
200Float2 = -? "." [0-9]+ {DecimalExponent}?
201Float3 = -? {HexPrefix} {HexDigit}+ "." {HexDigit}* {BinaryExponent}
202Float4 = -? {HexPrefix} "." {HexDigit}+ {BinaryExponent}
203Float =  {Float1} | {Float2} | {Float3} | {Float4}
204
205HighSurrogate = [\ud800-\udbff]
206
207LowSurrogate = [\udc00-\udfff]
208
209SimpleNameCharacter = ({HighSurrogate} {LowSurrogate}) | [A-Za-z0-9$\-_\u00a1-\u1fff\u2010-\u2027\u2030-\ud7ff\ue000-\uffef]
210
211SimpleName = {SimpleNameCharacter}+
212
213PrimitiveType = [ZBSCIJFD]
214
215ClassDescriptor = L ({SimpleName} "/")* {SimpleName} ;
216
217ArrayDescriptor = "[" + ({PrimitiveType} | {ClassDescriptor})
218
219Type = {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    "inline@0x" {HexDigit}+ { return newToken(INLINE_INDEX); }
373    "vtable@0x" {HexDigit}+ { return newToken(VTABLE_INDEX); }
374    "field@0x" {HexDigit}+ { return newToken(FIELD_OFFSET); }
375
376    "+" {Integer} { return newToken(OFFSET); }
377
378    # [^\r\n]* { return newToken(LINE_COMMENT, true); }
379}
380
381/*Instructions*/
382<YYINITIAL> {
383    "goto" {
384        return newToken(INSTRUCTION_FORMAT10t);
385    }
386
387    "return-void" | "nop" {
388        return newToken(INSTRUCTION_FORMAT10x);
389    }
390
391    "return-void-barrier" {
392        return newToken(INSTRUCTION_FORMAT10x_ODEX);
393    }
394
395    "const/4" {
396        return newToken(INSTRUCTION_FORMAT11n);
397    }
398
399    "move-result" | "move-result-wide" | "move-result-object" | "move-exception" | "return" | "return-wide" |
400    "return-object" | "monitor-enter" | "monitor-exit" | "throw" {
401        return newToken(INSTRUCTION_FORMAT11x);
402    }
403
404    "move" | "move-wide" | "move-object" | "array-length" | "neg-int" | "not-int" | "neg-long" | "not-long" |
405    "neg-float" | "neg-double" | "int-to-long" | "int-to-float" | "int-to-double" | "long-to-int" | "long-to-float" |
406    "long-to-double" | "float-to-int" | "float-to-long" | "float-to-double" | "double-to-int" | "double-to-long" |
407    "double-to-float" | "int-to-byte" | "int-to-char" | "int-to-short" {
408        return newToken(INSTRUCTION_FORMAT12x_OR_ID);
409    }
410
411    "add-int/2addr" | "sub-int/2addr" | "mul-int/2addr" | "div-int/2addr" | "rem-int/2addr" | "and-int/2addr" |
412    "or-int/2addr" | "xor-int/2addr" | "shl-int/2addr" | "shr-int/2addr" | "ushr-int/2addr" | "add-long/2addr" |
413    "sub-long/2addr" | "mul-long/2addr" | "div-long/2addr" | "rem-long/2addr" | "and-long/2addr" | "or-long/2addr" |
414    "xor-long/2addr" | "shl-long/2addr" | "shr-long/2addr" | "ushr-long/2addr" | "add-float/2addr" |
415    "sub-float/2addr" | "mul-float/2addr" | "div-float/2addr" | "rem-float/2addr" | "add-double/2addr" |
416    "sub-double/2addr" | "mul-double/2addr" | "div-double/2addr" | "rem-double/2addr" {
417        return newToken(INSTRUCTION_FORMAT12x);
418    }
419
420    "throw-verification-error" {
421        return newToken(INSTRUCTION_FORMAT20bc);
422    }
423
424    "goto/16" {
425        return newToken(INSTRUCTION_FORMAT20t);
426    }
427
428    "sget" | "sget-wide" | "sget-object" | "sget-boolean" | "sget-byte" | "sget-char" | "sget-short" | "sput" |
429    "sput-wide" | "sput-object" | "sput-boolean" | "sput-byte" | "sput-char" | "sput-short" {
430        return newToken(INSTRUCTION_FORMAT21c_FIELD);
431    }
432
433    "sget-volatile" | "sget-wide-volatile" | "sget-object-volatile" | "sput-volatile" | "sput-wide-volatile" |
434    "sput-object-volatile" {
435        return newToken(INSTRUCTION_FORMAT21c_FIELD_ODEX);
436    }
437
438    "const-string" {
439        return newToken(INSTRUCTION_FORMAT21c_STRING);
440    }
441
442    "check-cast" | "new-instance" | "const-class" {
443        return newToken(INSTRUCTION_FORMAT21c_TYPE);
444    }
445
446    "const/high16" | "const-wide/high16" {
447        return newToken(INSTRUCTION_FORMAT21h);
448    }
449
450    "const/16" | "const-wide/16" {
451        return newToken(INSTRUCTION_FORMAT21s);
452    }
453
454    "if-eqz" | "if-nez" | "if-ltz" | "if-gez" | "if-gtz" | "if-lez" {
455        return newToken(INSTRUCTION_FORMAT21t);
456    }
457
458    "add-int/lit8" | "rsub-int/lit8" | "mul-int/lit8" | "div-int/lit8" | "rem-int/lit8" | "and-int/lit8" |
459    "or-int/lit8" | "xor-int/lit8" | "shl-int/lit8" | "shr-int/lit8" | "ushr-int/lit8" {
460        return newToken(INSTRUCTION_FORMAT22b);
461    }
462
463    "iget" | "iget-wide" | "iget-object" | "iget-boolean" | "iget-byte" | "iget-char" | "iget-short" | "iput" |
464    "iput-wide" | "iput-object" | "iput-boolean" | "iput-byte" | "iput-char" | "iput-short" {
465        return newToken(INSTRUCTION_FORMAT22c_FIELD);
466    }
467
468    "iget-volatile" | "iget-wide-volatile" | "iget-object-volatile" | "iput-volatile" | "iput-wide-volatile" |
469    "iput-object-volatile" {
470        return newToken(INSTRUCTION_FORMAT22c_FIELD_ODEX);
471    }
472
473    "instance-of" | "new-array" {
474        return newToken(INSTRUCTION_FORMAT22c_TYPE);
475    }
476
477    "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" {
478        return newToken(INSTRUCTION_FORMAT22cs_FIELD);
479    }
480
481    "rsub-int" {
482        return newToken(INSTRUCTION_FORMAT22s_OR_ID);
483    }
484
485    "add-int/lit16" | "mul-int/lit16" | "div-int/lit16" | "rem-int/lit16" | "and-int/lit16" | "or-int/lit16" |
486    "xor-int/lit16" {
487        return newToken(INSTRUCTION_FORMAT22s);
488    }
489
490    "if-eq" | "if-ne" | "if-lt" | "if-ge" | "if-gt" | "if-le" {
491        return newToken(INSTRUCTION_FORMAT22t);
492    }
493
494    "move/from16" | "move-wide/from16" | "move-object/from16" {
495        return newToken(INSTRUCTION_FORMAT22x);
496    }
497
498    "cmpl-float" | "cmpg-float" | "cmpl-double" | "cmpg-double" | "cmp-long" | "aget" | "aget-wide" | "aget-object" |
499    "aget-boolean" | "aget-byte" | "aget-char" | "aget-short" | "aput" | "aput-wide" | "aput-object" | "aput-boolean" |
500    "aput-byte" | "aput-char" | "aput-short" | "add-int" | "sub-int" | "mul-int" | "div-int" | "rem-int" | "and-int" |
501    "or-int" | "xor-int" | "shl-int" | "shr-int" | "ushr-int" | "add-long" | "sub-long" | "mul-long" | "div-long" |
502    "rem-long" | "and-long" | "or-long" | "xor-long" | "shl-long" | "shr-long" | "ushr-long" | "add-float" |
503    "sub-float" | "mul-float" | "div-float" | "rem-float" | "add-double" | "sub-double" | "mul-double" | "div-double" |
504    "rem-double" {
505        return newToken(INSTRUCTION_FORMAT23x);
506    }
507
508    "goto/32" {
509        return newToken(INSTRUCTION_FORMAT30t);
510    }
511
512    "const-string/jumbo" {
513        return newToken(INSTRUCTION_FORMAT31c);
514    }
515
516    "const" {
517        return newToken(INSTRUCTION_FORMAT31i_OR_ID);
518    }
519
520    "const-wide/32" {
521        return newToken(INSTRUCTION_FORMAT31i);
522    }
523
524    "fill-array-data" | "packed-switch" | "sparse-switch" {
525        return newToken(INSTRUCTION_FORMAT31t);
526    }
527
528    "move/16" | "move-wide/16" | "move-object/16" {
529        return newToken(INSTRUCTION_FORMAT32x);
530    }
531
532    "invoke-virtual" | "invoke-super" | "invoke-direct" | "invoke-static" | "invoke-interface" {
533        return newToken(INSTRUCTION_FORMAT35c_METHOD);
534    }
535
536    "invoke-direct-empty" {
537        return newToken(INSTRUCTION_FORMAT35c_METHOD_ODEX);
538    }
539
540    "filled-new-array" {
541        return newToken(INSTRUCTION_FORMAT35c_TYPE);
542    }
543
544    "execute-inline" {
545        return newToken(INSTRUCTION_FORMAT35mi_METHOD);
546    }
547
548    "invoke-virtual-quick" | "invoke-super-quick" {
549        return newToken(INSTRUCTION_FORMAT35ms_METHOD);
550    }
551
552    "invoke-virtual/range" | "invoke-super/range" | "invoke-direct/range" | "invoke-static/range" |
553    "invoke-interface/range" {
554        return newToken(INSTRUCTION_FORMAT3rc_METHOD);
555    }
556
557    "invoke-object-init/range" {
558        return newToken(INSTRUCTION_FORMAT3rc_METHOD_ODEX);
559    }
560
561    "filled-new-array/range" {
562        return newToken(INSTRUCTION_FORMAT3rc_TYPE);
563    }
564
565    "execute-inline/range" {
566        return newToken(INSTRUCTION_FORMAT3rmi_METHOD);
567    }
568
569    "invoke-virtual-quick/range" | "invoke-super-quick/range" {
570        return newToken(INSTRUCTION_FORMAT3rms_METHOD);
571    }
572
573    "check-cast/jumbo" | "new-instance/jumbo" | "const-class/jumbo" {
574        return newToken(INSTRUCTION_FORMAT41c_TYPE);
575    }
576
577    "sget/jumbo" | "sget-wide/jumbo" | "sget-object/jumbo" | "sget-boolean/jumbo" | "sget-byte/jumbo" |
578    "sget-char/jumbo" | "sget-short/jumbo" | "sput/jumbo" | "sput-wide/jumbo" | "sput-object/jumbo" |
579    "sput-boolean/jumbo" | "sput-byte/jumbo" | "sput-char/jumbo" | "sput-short/jumbo" {
580        return newToken(INSTRUCTION_FORMAT41c_FIELD);
581    }
582
583    "const-wide" {
584        return newToken(INSTRUCTION_FORMAT51l);
585    }
586
587    "instance-of/jumbo" | "new-array/jumbo" {
588        return newToken(INSTRUCTION_FORMAT52c_TYPE);
589    }
590
591    "iget/jumbo" | "iget-wide/jumbo" | "iget-object/jumbo" | "iget-boolean/jumbo" | "iget-byte/jumbo" |
592    "iget-char/jumbo" | "iget-short/jumbo" | "iput/jumbo" | "iput-wide/jumbo" | "iput-object/jumbo" |
593    "iput-boolean/jumbo" | "iput-byte/jumbo" | "iput-char/jumbo" | "iput-short/jumbo" {
594        return newToken(INSTRUCTION_FORMAT52c_FIELD);
595    }
596
597    "invoke-virtual/jumbo" | "invoke-super/jumbo" | "invoke-direct/jumbo" | "invoke-static/jumbo" |
598    "invoke-interface/jumbo" {
599        return newToken(INSTRUCTION_FORMAT5rc_METHOD);
600    }
601
602    "filled-new-array/jumbo" {
603        return newToken(INSTRUCTION_FORMAT5rc_TYPE);
604    }
605}
606
607/*Types*/
608<YYINITIAL> {
609    {PrimitiveType} { return newToken(PRIMITIVE_TYPE); }
610    V { return newToken(VOID_TYPE); }
611    {ClassDescriptor} { return newToken(CLASS_DESCRIPTOR); }
612    {ArrayDescriptor} { return newToken(ARRAY_DESCRIPTOR); }
613    {PrimitiveType} {PrimitiveType}+ { return newToken(PARAM_LIST_OR_ID); }
614    {Type} {Type}+ { return newToken(PARAM_LIST); }
615    {SimpleName} { return newToken(SIMPLE_NAME); }
616    "<init>" | "<clinit>" { return newToken(METHOD_NAME); }
617}
618
619/*Symbols/Whitespace/EOF*/
620<YYINITIAL> {
621    ".." { return newToken(DOTDOT); }
622    "->" { return newToken(ARROW); }
623    "=" { return newToken(EQUAL); }
624    ":" { return newToken(COLON); }
625    "," { return newToken(COMMA); }
626    "{" { return newToken(OPEN_BRACE); }
627    "}" { return newToken(CLOSE_BRACE); }
628    "(" { return newToken(OPEN_PAREN); }
629    ")" { return newToken(CLOSE_PAREN); }
630    [\r\n\t ]+ { return newToken(WHITE_SPACE, true); }
631    <<EOF>> { return newToken(EOF); }
632}
633
634/*catch all*/
635<YYINITIAL> {
636    "." { return invalidToken("Invalid directive"); }
637    "." [a-zA-z\-_] { return invalidToken("Invalid directive"); }
638    "." [a-zA-z\-_] [a-zA-z0-9\-_]* { return invalidToken("Invalid directive"); }
639    . { return invalidToken("Invalid text"); }
640}
641