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