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