smaliLexer.flex revision d12c76927616b9f5193864c2d834e84a57c08787
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 "const/4" { 392 return newToken(INSTRUCTION_FORMAT11n); 393 } 394 395 "move-result" | "move-result-wide" | "move-result-object" | "move-exception" | "return" | "return-wide" | 396 "return-object" | "monitor-enter" | "monitor-exit" | "throw" { 397 return newToken(INSTRUCTION_FORMAT11x); 398 } 399 400 "move" | "move-wide" | "move-object" | "array-length" | "neg-int" | "not-int" | "neg-long" | "not-long" | 401 "neg-float" | "neg-double" | "int-to-long" | "int-to-float" | "int-to-double" | "long-to-int" | "long-to-float" | 402 "long-to-double" | "float-to-int" | "float-to-long" | "float-to-double" | "double-to-int" | "double-to-long" | 403 "double-to-float" | "int-to-byte" | "int-to-char" | "int-to-short" { 404 return newToken(INSTRUCTION_FORMAT12x_OR_ID); 405 } 406 407 "add-int/2addr" | "sub-int/2addr" | "mul-int/2addr" | "div-int/2addr" | "rem-int/2addr" | "and-int/2addr" | 408 "or-int/2addr" | "xor-int/2addr" | "shl-int/2addr" | "shr-int/2addr" | "ushr-int/2addr" | "add-long/2addr" | 409 "sub-long/2addr" | "mul-long/2addr" | "div-long/2addr" | "rem-long/2addr" | "and-long/2addr" | "or-long/2addr" | 410 "xor-long/2addr" | "shl-long/2addr" | "shr-long/2addr" | "ushr-long/2addr" | "add-float/2addr" | 411 "sub-float/2addr" | "mul-float/2addr" | "div-float/2addr" | "rem-float/2addr" | "add-double/2addr" | 412 "sub-double/2addr" | "mul-double/2addr" | "div-double/2addr" | "rem-double/2addr" { 413 return newToken(INSTRUCTION_FORMAT12x); 414 } 415 416 "throw-verification-error" { 417 return newToken(INSTRUCTION_FORMAT20bc); 418 } 419 420 "goto/16" { 421 return newToken(INSTRUCTION_FORMAT20t); 422 } 423 424 "sget" | "sget-wide" | "sget-object" | "sget-boolean" | "sget-byte" | "sget-char" | "sget-short" | "sput" | 425 "sput-wide" | "sput-object" | "sput-boolean" | "sput-byte" | "sput-char" | "sput-short" { 426 return newToken(INSTRUCTION_FORMAT21c_FIELD); 427 } 428 429 "sget-volatile" | "sget-wide-volatile" | "sget-object-volatile" | "sput-volatile" | "sput-wide-volatile" | 430 "sput-object-volatile" { 431 return newToken(INSTRUCTION_FORMAT21c_FIELD_ODEX); 432 } 433 434 "const-string" { 435 return newToken(INSTRUCTION_FORMAT21c_STRING); 436 } 437 438 "check-cast" | "new-instance" | "const-class" { 439 return newToken(INSTRUCTION_FORMAT21c_TYPE); 440 } 441 442 "const/high16" | "const-wide/high16" { 443 return newToken(INSTRUCTION_FORMAT21h); 444 } 445 446 "const/16" | "const-wide/16" { 447 return newToken(INSTRUCTION_FORMAT21s); 448 } 449 450 "if-eqz" | "if-nez" | "if-ltz" | "if-gez" | "if-gtz" | "if-lez" { 451 return newToken(INSTRUCTION_FORMAT21t); 452 } 453 454 "add-int/lit8" | "rsub-int/lit8" | "mul-int/lit8" | "div-int/lit8" | "rem-int/lit8" | "and-int/lit8" | 455 "or-int/lit8" | "xor-int/lit8" | "shl-int/lit8" | "shr-int/lit8" | "ushr-int/lit8" { 456 return newToken(INSTRUCTION_FORMAT22b); 457 } 458 459 "iget" | "iget-wide" | "iget-object" | "iget-boolean" | "iget-byte" | "iget-char" | "iget-short" | "iput" | 460 "iput-wide" | "iput-object" | "iput-boolean" | "iput-byte" | "iput-char" | "iput-short" { 461 return newToken(INSTRUCTION_FORMAT22c_FIELD); 462 } 463 464 "iget-volatile" | "iget-wide-volatile" | "iget-object-volatile" | "iput-volatile" | "iput-wide-volatile" | 465 "iput-object-volatile" { 466 return newToken(INSTRUCTION_FORMAT22c_FIELD_ODEX); 467 } 468 469 "instance-of" | "new-array" { 470 return newToken(INSTRUCTION_FORMAT22c_TYPE); 471 } 472 473 "iget-quick" | "iget-wide-quick" | "iget-object-quick" | "iput-quick" | "iput-wide-quick" | "iput-object-quick" { 474 return newToken(INSTRUCTION_FORMAT22cs_FIELD); 475 } 476 477 "rsub-int" { 478 return newToken(INSTRUCTION_FORMAT22s_OR_ID); 479 } 480 481 "add-int/lit16" | "mul-int/lit16" | "div-int/lit16" | "rem-int/lit16" | "and-int/lit16" | "or-int/lit16" | 482 "xor-int/lit16" { 483 return newToken(INSTRUCTION_FORMAT22s); 484 } 485 486 "if-eq" | "if-ne" | "if-lt" | "if-ge" | "if-gt" | "if-le" { 487 return newToken(INSTRUCTION_FORMAT22t); 488 } 489 490 "move/from16" | "move-wide/from16" | "move-object/from16" { 491 return newToken(INSTRUCTION_FORMAT22x); 492 } 493 494 "cmpl-float" | "cmpg-float" | "cmpl-double" | "cmpg-double" | "cmp-long" | "aget" | "aget-wide" | "aget-object" | 495 "aget-boolean" | "aget-byte" | "aget-char" | "aget-short" | "aput" | "aput-wide" | "aput-object" | "aput-boolean" | 496 "aput-byte" | "aput-char" | "aput-short" | "add-int" | "sub-int" | "mul-int" | "div-int" | "rem-int" | "and-int" | 497 "or-int" | "xor-int" | "shl-int" | "shr-int" | "ushr-int" | "add-long" | "sub-long" | "mul-long" | "div-long" | 498 "rem-long" | "and-long" | "or-long" | "xor-long" | "shl-long" | "shr-long" | "ushr-long" | "add-float" | 499 "sub-float" | "mul-float" | "div-float" | "rem-float" | "add-double" | "sub-double" | "mul-double" | "div-double" | 500 "rem-double" { 501 return newToken(INSTRUCTION_FORMAT23x); 502 } 503 504 "goto/32" { 505 return newToken(INSTRUCTION_FORMAT30t); 506 } 507 508 "const-string/jumbo" { 509 return newToken(INSTRUCTION_FORMAT31c); 510 } 511 512 "const" { 513 return newToken(INSTRUCTION_FORMAT31i_OR_ID); 514 } 515 516 "const-wide/32" { 517 return newToken(INSTRUCTION_FORMAT31i); 518 } 519 520 "fill-array-data" | "packed-switch" | "sparse-switch" { 521 return newToken(INSTRUCTION_FORMAT31t); 522 } 523 524 "move/16" | "move-wide/16" | "move-object/16" { 525 return newToken(INSTRUCTION_FORMAT32x); 526 } 527 528 "invoke-virtual" | "invoke-super" | "invoke-direct" | "invoke-static" | "invoke-interface" { 529 return newToken(INSTRUCTION_FORMAT35c_METHOD); 530 } 531 532 "filled-new-array" { 533 return newToken(INSTRUCTION_FORMAT35c_TYPE); 534 } 535 536 "invoke-direct-empty" { 537 return newToken(INSTRUCTION_FORMAT35s_METHOD); 538 } 539 540 "execute-inline" { 541 return newToken(INSTRUCTION_FORMAT35mi_METHOD); 542 } 543 544 "invoke-virtual-quick" | "invoke-super-quick" { 545 return newToken(INSTRUCTION_FORMAT35ms_METHOD); 546 } 547 548 "invoke-virtual/range" | "invoke-super/range" | "invoke-direct/range" | "invoke-static/range" | 549 "invoke-interface/range" { 550 return newToken(INSTRUCTION_FORMAT3rc_METHOD); 551 } 552 553 "filled-new-array/range" { 554 return newToken(INSTRUCTION_FORMAT3rc_TYPE); 555 } 556 557 "execute-inline/range" { 558 return newToken(INSTRUCTION_FORMAT3rmi_METHOD); 559 } 560 561 "invoke-virtual-quick/range" | "invoke-super-quick/range" { 562 return newToken(INSTRUCTION_FORMAT3rms_METHOD); 563 } 564 565 "check-cast/jumbo" | "new-instance/jumbo" | "const-class/jumbo" { 566 return newToken(INSTRUCTION_FORMAT41c_TYPE); 567 } 568 569 "const-wide" { 570 return newToken(INSTRUCTION_FORMAT51l); 571 } 572} 573 574/*Types*/ 575<YYINITIAL> { 576 {PrimitiveType} { return newToken(PRIMITIVE_TYPE); } 577 V { return newToken(VOID_TYPE); } 578 {ClassDescriptor} { return newToken(CLASS_DESCRIPTOR); } 579 {ArrayDescriptor} { return newToken(ARRAY_DESCRIPTOR); } 580 {PrimitiveType} {PrimitiveType}+ { return newToken(PARAM_LIST_OR_ID); } 581 {Type} {Type}+ { return newToken(PARAM_LIST); } 582 {SimpleName} { return newToken(SIMPLE_NAME); } 583 "<init>" | "<clinit>" { return newToken(METHOD_NAME); } 584} 585 586/*Symbols/Whitespace/EOF*/ 587<YYINITIAL> { 588 ".." { return newToken(DOTDOT); } 589 "->" { return newToken(ARROW); } 590 "=" { return newToken(EQUAL); } 591 ":" { return newToken(COLON); } 592 "," { return newToken(COMMA); } 593 "{" { return newToken(OPEN_BRACE); } 594 "}" { return newToken(CLOSE_BRACE); } 595 "(" { return newToken(OPEN_PAREN); } 596 ")" { return newToken(CLOSE_PAREN); } 597 [\r\n\t ]+ { return newToken(WHITE_SPACE, true); } 598 <<EOF>> { return newToken(EOF); } 599} 600 601/*catch all*/ 602<YYINITIAL> { 603 "." { return invalidToken("Invalid directive"); } 604 "." [a-zA-z\-_] { return invalidToken("Invalid directive"); } 605 "." [a-zA-z\-_] [a-zA-z0-9\-_]* { return invalidToken("Invalid directive"); } 606 . { return invalidToken("Invalid text"); } 607} 608