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