lex.go (31136B)
1 package toml 2 3 import ( 4 "fmt" 5 "reflect" 6 "runtime" 7 "strings" 8 "unicode" 9 "unicode/utf8" 10 ) 11 12 type itemType int 13 14 const ( 15 itemError itemType = iota 16 itemNIL // used in the parser to indicate no type 17 itemEOF 18 itemText 19 itemString 20 itemStringEsc 21 itemRawString 22 itemMultilineString 23 itemRawMultilineString 24 itemBool 25 itemInteger 26 itemFloat 27 itemDatetime 28 itemArray // the start of an array 29 itemArrayEnd 30 itemTableStart 31 itemTableEnd 32 itemArrayTableStart 33 itemArrayTableEnd 34 itemKeyStart 35 itemKeyEnd 36 itemCommentStart 37 itemInlineTableStart 38 itemInlineTableEnd 39 ) 40 41 const eof = 0 42 43 type stateFn func(lx *lexer) stateFn 44 45 func (p Position) String() string { 46 return fmt.Sprintf("at line %d; start %d; length %d", p.Line, p.Start, p.Len) 47 } 48 49 type lexer struct { 50 input string 51 start int 52 pos int 53 line int 54 state stateFn 55 items chan item 56 tomlNext bool 57 esc bool 58 59 // Allow for backing up up to 4 runes. This is necessary because TOML 60 // contains 3-rune tokens (""" and '''). 61 prevWidths [4]int 62 nprev int // how many of prevWidths are in use 63 atEOF bool // If we emit an eof, we can still back up, but it is not OK to call next again. 64 65 // A stack of state functions used to maintain context. 66 // 67 // The idea is to reuse parts of the state machine in various places. For 68 // example, values can appear at the top level or within arbitrarily nested 69 // arrays. The last state on the stack is used after a value has been lexed. 70 // Similarly for comments. 71 stack []stateFn 72 } 73 74 type item struct { 75 typ itemType 76 val string 77 err error 78 pos Position 79 } 80 81 func (lx *lexer) nextItem() item { 82 for { 83 select { 84 case item := <-lx.items: 85 return item 86 default: 87 lx.state = lx.state(lx) 88 //fmt.Printf(" STATE %-24s current: %-10s stack: %s\n", lx.state, lx.current(), lx.stack) 89 } 90 } 91 } 92 93 func lex(input string, tomlNext bool) *lexer { 94 lx := &lexer{ 95 input: input, 96 state: lexTop, 97 items: make(chan item, 10), 98 stack: make([]stateFn, 0, 10), 99 line: 1, 100 tomlNext: tomlNext, 101 } 102 return lx 103 } 104 105 func (lx *lexer) push(state stateFn) { 106 lx.stack = append(lx.stack, state) 107 } 108 109 func (lx *lexer) pop() stateFn { 110 if len(lx.stack) == 0 { 111 return lx.errorf("BUG in lexer: no states to pop") 112 } 113 last := lx.stack[len(lx.stack)-1] 114 lx.stack = lx.stack[0 : len(lx.stack)-1] 115 return last 116 } 117 118 func (lx *lexer) current() string { 119 return lx.input[lx.start:lx.pos] 120 } 121 122 func (lx lexer) getPos() Position { 123 p := Position{ 124 Line: lx.line, 125 Start: lx.start, 126 Len: lx.pos - lx.start, 127 } 128 if p.Len <= 0 { 129 p.Len = 1 130 } 131 return p 132 } 133 134 func (lx *lexer) emit(typ itemType) { 135 // Needed for multiline strings ending with an incomplete UTF-8 sequence. 136 if lx.start > lx.pos { 137 lx.error(errLexUTF8{lx.input[lx.pos]}) 138 return 139 } 140 lx.items <- item{typ: typ, pos: lx.getPos(), val: lx.current()} 141 lx.start = lx.pos 142 } 143 144 func (lx *lexer) emitTrim(typ itemType) { 145 lx.items <- item{typ: typ, pos: lx.getPos(), val: strings.TrimSpace(lx.current())} 146 lx.start = lx.pos 147 } 148 149 func (lx *lexer) next() (r rune) { 150 if lx.atEOF { 151 panic("BUG in lexer: next called after EOF") 152 } 153 if lx.pos >= len(lx.input) { 154 lx.atEOF = true 155 return eof 156 } 157 158 if lx.input[lx.pos] == '\n' { 159 lx.line++ 160 } 161 lx.prevWidths[3] = lx.prevWidths[2] 162 lx.prevWidths[2] = lx.prevWidths[1] 163 lx.prevWidths[1] = lx.prevWidths[0] 164 if lx.nprev < 4 { 165 lx.nprev++ 166 } 167 168 r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) 169 if r == utf8.RuneError && w == 1 { 170 lx.error(errLexUTF8{lx.input[lx.pos]}) 171 return utf8.RuneError 172 } 173 174 // Note: don't use peek() here, as this calls next(). 175 if isControl(r) || (r == '\r' && (len(lx.input)-1 == lx.pos || lx.input[lx.pos+1] != '\n')) { 176 lx.errorControlChar(r) 177 return utf8.RuneError 178 } 179 180 lx.prevWidths[0] = w 181 lx.pos += w 182 return r 183 } 184 185 // ignore skips over the pending input before this point. 186 func (lx *lexer) ignore() { 187 lx.start = lx.pos 188 } 189 190 // backup steps back one rune. Can be called 4 times between calls to next. 191 func (lx *lexer) backup() { 192 if lx.atEOF { 193 lx.atEOF = false 194 return 195 } 196 if lx.nprev < 1 { 197 panic("BUG in lexer: backed up too far") 198 } 199 w := lx.prevWidths[0] 200 lx.prevWidths[0] = lx.prevWidths[1] 201 lx.prevWidths[1] = lx.prevWidths[2] 202 lx.prevWidths[2] = lx.prevWidths[3] 203 lx.nprev-- 204 205 lx.pos -= w 206 if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { 207 lx.line-- 208 } 209 } 210 211 // accept consumes the next rune if it's equal to `valid`. 212 func (lx *lexer) accept(valid rune) bool { 213 if lx.next() == valid { 214 return true 215 } 216 lx.backup() 217 return false 218 } 219 220 // peek returns but does not consume the next rune in the input. 221 func (lx *lexer) peek() rune { 222 r := lx.next() 223 lx.backup() 224 return r 225 } 226 227 // skip ignores all input that matches the given predicate. 228 func (lx *lexer) skip(pred func(rune) bool) { 229 for { 230 r := lx.next() 231 if pred(r) { 232 continue 233 } 234 lx.backup() 235 lx.ignore() 236 return 237 } 238 } 239 240 // error stops all lexing by emitting an error and returning `nil`. 241 // 242 // Note that any value that is a character is escaped if it's a special 243 // character (newlines, tabs, etc.). 244 func (lx *lexer) error(err error) stateFn { 245 if lx.atEOF { 246 return lx.errorPrevLine(err) 247 } 248 lx.items <- item{typ: itemError, pos: lx.getPos(), err: err} 249 return nil 250 } 251 252 // errorfPrevline is like error(), but sets the position to the last column of 253 // the previous line. 254 // 255 // This is so that unexpected EOF or NL errors don't show on a new blank line. 256 func (lx *lexer) errorPrevLine(err error) stateFn { 257 pos := lx.getPos() 258 pos.Line-- 259 pos.Len = 1 260 pos.Start = lx.pos - 1 261 lx.items <- item{typ: itemError, pos: pos, err: err} 262 return nil 263 } 264 265 // errorPos is like error(), but allows explicitly setting the position. 266 func (lx *lexer) errorPos(start, length int, err error) stateFn { 267 pos := lx.getPos() 268 pos.Start = start 269 pos.Len = length 270 lx.items <- item{typ: itemError, pos: pos, err: err} 271 return nil 272 } 273 274 // errorf is like error, and creates a new error. 275 func (lx *lexer) errorf(format string, values ...any) stateFn { 276 if lx.atEOF { 277 pos := lx.getPos() 278 pos.Line-- 279 pos.Len = 1 280 pos.Start = lx.pos - 1 281 lx.items <- item{typ: itemError, pos: pos, err: fmt.Errorf(format, values...)} 282 return nil 283 } 284 lx.items <- item{typ: itemError, pos: lx.getPos(), err: fmt.Errorf(format, values...)} 285 return nil 286 } 287 288 func (lx *lexer) errorControlChar(cc rune) stateFn { 289 return lx.errorPos(lx.pos-1, 1, errLexControl{cc}) 290 } 291 292 // lexTop consumes elements at the top level of TOML data. 293 func lexTop(lx *lexer) stateFn { 294 r := lx.next() 295 if isWhitespace(r) || isNL(r) { 296 return lexSkip(lx, lexTop) 297 } 298 switch r { 299 case '#': 300 lx.push(lexTop) 301 return lexCommentStart 302 case '[': 303 return lexTableStart 304 case eof: 305 if lx.pos > lx.start { 306 return lx.errorf("unexpected EOF") 307 } 308 lx.emit(itemEOF) 309 return nil 310 } 311 312 // At this point, the only valid item can be a key, so we back up 313 // and let the key lexer do the rest. 314 lx.backup() 315 lx.push(lexTopEnd) 316 return lexKeyStart 317 } 318 319 // lexTopEnd is entered whenever a top-level item has been consumed. (A value 320 // or a table.) It must see only whitespace, and will turn back to lexTop 321 // upon a newline. If it sees EOF, it will quit the lexer successfully. 322 func lexTopEnd(lx *lexer) stateFn { 323 r := lx.next() 324 switch { 325 case r == '#': 326 // a comment will read to a newline for us. 327 lx.push(lexTop) 328 return lexCommentStart 329 case isWhitespace(r): 330 return lexTopEnd 331 case isNL(r): 332 lx.ignore() 333 return lexTop 334 case r == eof: 335 lx.emit(itemEOF) 336 return nil 337 } 338 return lx.errorf("expected a top-level item to end with a newline, comment, or EOF, but got %q instead", r) 339 } 340 341 // lexTable lexes the beginning of a table. Namely, it makes sure that 342 // it starts with a character other than '.' and ']'. 343 // It assumes that '[' has already been consumed. 344 // It also handles the case that this is an item in an array of tables. 345 // e.g., '[[name]]'. 346 func lexTableStart(lx *lexer) stateFn { 347 if lx.peek() == '[' { 348 lx.next() 349 lx.emit(itemArrayTableStart) 350 lx.push(lexArrayTableEnd) 351 } else { 352 lx.emit(itemTableStart) 353 lx.push(lexTableEnd) 354 } 355 return lexTableNameStart 356 } 357 358 func lexTableEnd(lx *lexer) stateFn { 359 lx.emit(itemTableEnd) 360 return lexTopEnd 361 } 362 363 func lexArrayTableEnd(lx *lexer) stateFn { 364 if r := lx.next(); r != ']' { 365 return lx.errorf("expected end of table array name delimiter ']', but got %q instead", r) 366 } 367 lx.emit(itemArrayTableEnd) 368 return lexTopEnd 369 } 370 371 func lexTableNameStart(lx *lexer) stateFn { 372 lx.skip(isWhitespace) 373 switch r := lx.peek(); { 374 case r == ']' || r == eof: 375 return lx.errorf("unexpected end of table name (table names cannot be empty)") 376 case r == '.': 377 return lx.errorf("unexpected table separator (table names cannot be empty)") 378 case r == '"' || r == '\'': 379 lx.ignore() 380 lx.push(lexTableNameEnd) 381 return lexQuotedName 382 default: 383 lx.push(lexTableNameEnd) 384 return lexBareName 385 } 386 } 387 388 // lexTableNameEnd reads the end of a piece of a table name, optionally 389 // consuming whitespace. 390 func lexTableNameEnd(lx *lexer) stateFn { 391 lx.skip(isWhitespace) 392 switch r := lx.next(); { 393 case isWhitespace(r): 394 return lexTableNameEnd 395 case r == '.': 396 lx.ignore() 397 return lexTableNameStart 398 case r == ']': 399 return lx.pop() 400 default: 401 return lx.errorf("expected '.' or ']' to end table name, but got %q instead", r) 402 } 403 } 404 405 // lexBareName lexes one part of a key or table. 406 // 407 // It assumes that at least one valid character for the table has already been 408 // read. 409 // 410 // Lexes only one part, e.g. only 'a' inside 'a.b'. 411 func lexBareName(lx *lexer) stateFn { 412 r := lx.next() 413 if isBareKeyChar(r, lx.tomlNext) { 414 return lexBareName 415 } 416 lx.backup() 417 lx.emit(itemText) 418 return lx.pop() 419 } 420 421 // lexBareName lexes one part of a key or table. 422 // 423 // It assumes that at least one valid character for the table has already been 424 // read. 425 // 426 // Lexes only one part, e.g. only '"a"' inside '"a".b'. 427 func lexQuotedName(lx *lexer) stateFn { 428 r := lx.next() 429 switch { 430 case isWhitespace(r): 431 return lexSkip(lx, lexValue) 432 case r == '"': 433 lx.ignore() // ignore the '"' 434 return lexString 435 case r == '\'': 436 lx.ignore() // ignore the "'" 437 return lexRawString 438 case r == eof: 439 return lx.errorf("unexpected EOF; expected value") 440 default: 441 return lx.errorf("expected value but found %q instead", r) 442 } 443 } 444 445 // lexKeyStart consumes all key parts until a '='. 446 func lexKeyStart(lx *lexer) stateFn { 447 lx.skip(isWhitespace) 448 switch r := lx.peek(); { 449 case r == '=' || r == eof: 450 return lx.errorf("unexpected '=': key name appears blank") 451 case r == '.': 452 return lx.errorf("unexpected '.': keys cannot start with a '.'") 453 case r == '"' || r == '\'': 454 lx.ignore() 455 fallthrough 456 default: // Bare key 457 lx.emit(itemKeyStart) 458 return lexKeyNameStart 459 } 460 } 461 462 func lexKeyNameStart(lx *lexer) stateFn { 463 lx.skip(isWhitespace) 464 switch r := lx.peek(); { 465 case r == '=' || r == eof: 466 return lx.errorf("unexpected '='") 467 case r == '.': 468 return lx.errorf("unexpected '.'") 469 case r == '"' || r == '\'': 470 lx.ignore() 471 lx.push(lexKeyEnd) 472 return lexQuotedName 473 default: 474 lx.push(lexKeyEnd) 475 return lexBareName 476 } 477 } 478 479 // lexKeyEnd consumes the end of a key and trims whitespace (up to the key 480 // separator). 481 func lexKeyEnd(lx *lexer) stateFn { 482 lx.skip(isWhitespace) 483 switch r := lx.next(); { 484 case isWhitespace(r): 485 return lexSkip(lx, lexKeyEnd) 486 case r == eof: 487 return lx.errorf("unexpected EOF; expected key separator '='") 488 case r == '.': 489 lx.ignore() 490 return lexKeyNameStart 491 case r == '=': 492 lx.emit(itemKeyEnd) 493 return lexSkip(lx, lexValue) 494 default: 495 if r == '\n' { 496 return lx.errorPrevLine(fmt.Errorf("expected '.' or '=', but got %q instead", r)) 497 } 498 return lx.errorf("expected '.' or '=', but got %q instead", r) 499 } 500 } 501 502 // lexValue starts the consumption of a value anywhere a value is expected. 503 // lexValue will ignore whitespace. 504 // After a value is lexed, the last state on the next is popped and returned. 505 func lexValue(lx *lexer) stateFn { 506 // We allow whitespace to precede a value, but NOT newlines. 507 // In array syntax, the array states are responsible for ignoring newlines. 508 r := lx.next() 509 switch { 510 case isWhitespace(r): 511 return lexSkip(lx, lexValue) 512 case isDigit(r): 513 lx.backup() // avoid an extra state and use the same as above 514 return lexNumberOrDateStart 515 } 516 switch r { 517 case '[': 518 lx.ignore() 519 lx.emit(itemArray) 520 return lexArrayValue 521 case '{': 522 lx.ignore() 523 lx.emit(itemInlineTableStart) 524 return lexInlineTableValue 525 case '"': 526 if lx.accept('"') { 527 if lx.accept('"') { 528 lx.ignore() // Ignore """ 529 return lexMultilineString 530 } 531 lx.backup() 532 } 533 lx.ignore() // ignore the '"' 534 return lexString 535 case '\'': 536 if lx.accept('\'') { 537 if lx.accept('\'') { 538 lx.ignore() // Ignore """ 539 return lexMultilineRawString 540 } 541 lx.backup() 542 } 543 lx.ignore() // ignore the "'" 544 return lexRawString 545 case '.': // special error case, be kind to users 546 return lx.errorf("floats must start with a digit, not '.'") 547 case 'i', 'n': 548 if (lx.accept('n') && lx.accept('f')) || (lx.accept('a') && lx.accept('n')) { 549 lx.emit(itemFloat) 550 return lx.pop() 551 } 552 case '-', '+': 553 return lexDecimalNumberStart 554 } 555 if unicode.IsLetter(r) { 556 // Be permissive here; lexBool will give a nice error if the 557 // user wrote something like 558 // x = foo 559 // (i.e. not 'true' or 'false' but is something else word-like.) 560 lx.backup() 561 return lexBool 562 } 563 if r == eof { 564 return lx.errorf("unexpected EOF; expected value") 565 } 566 if r == '\n' { 567 return lx.errorPrevLine(fmt.Errorf("expected value but found %q instead", r)) 568 } 569 return lx.errorf("expected value but found %q instead", r) 570 } 571 572 // lexArrayValue consumes one value in an array. It assumes that '[' or ',' 573 // have already been consumed. All whitespace and newlines are ignored. 574 func lexArrayValue(lx *lexer) stateFn { 575 r := lx.next() 576 switch { 577 case isWhitespace(r) || isNL(r): 578 return lexSkip(lx, lexArrayValue) 579 case r == '#': 580 lx.push(lexArrayValue) 581 return lexCommentStart 582 case r == ',': 583 return lx.errorf("unexpected comma") 584 case r == ']': 585 return lexArrayEnd 586 } 587 588 lx.backup() 589 lx.push(lexArrayValueEnd) 590 return lexValue 591 } 592 593 // lexArrayValueEnd consumes everything between the end of an array value and 594 // the next value (or the end of the array): it ignores whitespace and newlines 595 // and expects either a ',' or a ']'. 596 func lexArrayValueEnd(lx *lexer) stateFn { 597 switch r := lx.next(); { 598 case isWhitespace(r) || isNL(r): 599 return lexSkip(lx, lexArrayValueEnd) 600 case r == '#': 601 lx.push(lexArrayValueEnd) 602 return lexCommentStart 603 case r == ',': 604 lx.ignore() 605 return lexArrayValue // move on to the next value 606 case r == ']': 607 return lexArrayEnd 608 default: 609 return lx.errorf("expected a comma (',') or array terminator (']'), but got %s", runeOrEOF(r)) 610 } 611 } 612 613 // lexArrayEnd finishes the lexing of an array. 614 // It assumes that a ']' has just been consumed. 615 func lexArrayEnd(lx *lexer) stateFn { 616 lx.ignore() 617 lx.emit(itemArrayEnd) 618 return lx.pop() 619 } 620 621 // lexInlineTableValue consumes one key/value pair in an inline table. 622 // It assumes that '{' or ',' have already been consumed. Whitespace is ignored. 623 func lexInlineTableValue(lx *lexer) stateFn { 624 r := lx.next() 625 switch { 626 case isWhitespace(r): 627 return lexSkip(lx, lexInlineTableValue) 628 case isNL(r): 629 if lx.tomlNext { 630 return lexSkip(lx, lexInlineTableValue) 631 } 632 return lx.errorPrevLine(errLexInlineTableNL{}) 633 case r == '#': 634 lx.push(lexInlineTableValue) 635 return lexCommentStart 636 case r == ',': 637 return lx.errorf("unexpected comma") 638 case r == '}': 639 return lexInlineTableEnd 640 } 641 lx.backup() 642 lx.push(lexInlineTableValueEnd) 643 return lexKeyStart 644 } 645 646 // lexInlineTableValueEnd consumes everything between the end of an inline table 647 // key/value pair and the next pair (or the end of the table): 648 // it ignores whitespace and expects either a ',' or a '}'. 649 func lexInlineTableValueEnd(lx *lexer) stateFn { 650 switch r := lx.next(); { 651 case isWhitespace(r): 652 return lexSkip(lx, lexInlineTableValueEnd) 653 case isNL(r): 654 if lx.tomlNext { 655 return lexSkip(lx, lexInlineTableValueEnd) 656 } 657 return lx.errorPrevLine(errLexInlineTableNL{}) 658 case r == '#': 659 lx.push(lexInlineTableValueEnd) 660 return lexCommentStart 661 case r == ',': 662 lx.ignore() 663 lx.skip(isWhitespace) 664 if lx.peek() == '}' { 665 if lx.tomlNext { 666 return lexInlineTableValueEnd 667 } 668 return lx.errorf("trailing comma not allowed in inline tables") 669 } 670 return lexInlineTableValue 671 case r == '}': 672 return lexInlineTableEnd 673 default: 674 return lx.errorf("expected a comma or an inline table terminator '}', but got %s instead", runeOrEOF(r)) 675 } 676 } 677 678 func runeOrEOF(r rune) string { 679 if r == eof { 680 return "end of file" 681 } 682 return "'" + string(r) + "'" 683 } 684 685 // lexInlineTableEnd finishes the lexing of an inline table. 686 // It assumes that a '}' has just been consumed. 687 func lexInlineTableEnd(lx *lexer) stateFn { 688 lx.ignore() 689 lx.emit(itemInlineTableEnd) 690 return lx.pop() 691 } 692 693 // lexString consumes the inner contents of a string. It assumes that the 694 // beginning '"' has already been consumed and ignored. 695 func lexString(lx *lexer) stateFn { 696 r := lx.next() 697 switch { 698 case r == eof: 699 return lx.errorf(`unexpected EOF; expected '"'`) 700 case isNL(r): 701 return lx.errorPrevLine(errLexStringNL{}) 702 case r == '\\': 703 lx.push(lexString) 704 return lexStringEscape 705 case r == '"': 706 lx.backup() 707 if lx.esc { 708 lx.esc = false 709 lx.emit(itemStringEsc) 710 } else { 711 lx.emit(itemString) 712 } 713 lx.next() 714 lx.ignore() 715 return lx.pop() 716 } 717 return lexString 718 } 719 720 // lexMultilineString consumes the inner contents of a string. It assumes that 721 // the beginning '"""' has already been consumed and ignored. 722 func lexMultilineString(lx *lexer) stateFn { 723 r := lx.next() 724 switch r { 725 default: 726 return lexMultilineString 727 case eof: 728 return lx.errorf(`unexpected EOF; expected '"""'`) 729 case '\\': 730 return lexMultilineStringEscape 731 case '"': 732 /// Found " → try to read two more "". 733 if lx.accept('"') { 734 if lx.accept('"') { 735 /// Peek ahead: the string can contain " and "", including at the 736 /// end: """str""""" 737 /// 6 or more at the end, however, is an error. 738 if lx.peek() == '"' { 739 /// Check if we already lexed 5 's; if so we have 6 now, and 740 /// that's just too many man! 741 /// 742 /// Second check is for the edge case: 743 /// 744 /// two quotes allowed. 745 /// vv 746 /// """lol \"""""" 747 /// ^^ ^^^---- closing three 748 /// escaped 749 /// 750 /// But ugly, but it works 751 if strings.HasSuffix(lx.current(), `"""""`) && !strings.HasSuffix(lx.current(), `\"""""`) { 752 return lx.errorf(`unexpected '""""""'`) 753 } 754 lx.backup() 755 lx.backup() 756 return lexMultilineString 757 } 758 759 lx.backup() /// backup: don't include the """ in the item. 760 lx.backup() 761 lx.backup() 762 lx.esc = false 763 lx.emit(itemMultilineString) 764 lx.next() /// Read over ''' again and discard it. 765 lx.next() 766 lx.next() 767 lx.ignore() 768 return lx.pop() 769 } 770 lx.backup() 771 } 772 return lexMultilineString 773 } 774 } 775 776 // lexRawString consumes a raw string. Nothing can be escaped in such a string. 777 // It assumes that the beginning "'" has already been consumed and ignored. 778 func lexRawString(lx *lexer) stateFn { 779 r := lx.next() 780 switch { 781 default: 782 return lexRawString 783 case r == eof: 784 return lx.errorf(`unexpected EOF; expected "'"`) 785 case isNL(r): 786 return lx.errorPrevLine(errLexStringNL{}) 787 case r == '\'': 788 lx.backup() 789 lx.emit(itemRawString) 790 lx.next() 791 lx.ignore() 792 return lx.pop() 793 } 794 } 795 796 // lexMultilineRawString consumes a raw string. Nothing can be escaped in such a 797 // string. It assumes that the beginning triple-' has already been consumed and 798 // ignored. 799 func lexMultilineRawString(lx *lexer) stateFn { 800 r := lx.next() 801 switch r { 802 default: 803 return lexMultilineRawString 804 case eof: 805 return lx.errorf(`unexpected EOF; expected "'''"`) 806 case '\'': 807 /// Found ' → try to read two more ''. 808 if lx.accept('\'') { 809 if lx.accept('\'') { 810 /// Peek ahead: the string can contain ' and '', including at the 811 /// end: '''str''''' 812 /// 6 or more at the end, however, is an error. 813 if lx.peek() == '\'' { 814 /// Check if we already lexed 5 's; if so we have 6 now, and 815 /// that's just too many man! 816 if strings.HasSuffix(lx.current(), "'''''") { 817 return lx.errorf(`unexpected "''''''"`) 818 } 819 lx.backup() 820 lx.backup() 821 return lexMultilineRawString 822 } 823 824 lx.backup() /// backup: don't include the ''' in the item. 825 lx.backup() 826 lx.backup() 827 lx.emit(itemRawMultilineString) 828 lx.next() /// Read over ''' again and discard it. 829 lx.next() 830 lx.next() 831 lx.ignore() 832 return lx.pop() 833 } 834 lx.backup() 835 } 836 return lexMultilineRawString 837 } 838 } 839 840 // lexMultilineStringEscape consumes an escaped character. It assumes that the 841 // preceding '\\' has already been consumed. 842 func lexMultilineStringEscape(lx *lexer) stateFn { 843 if isNL(lx.next()) { /// \ escaping newline. 844 return lexMultilineString 845 } 846 lx.backup() 847 lx.push(lexMultilineString) 848 return lexStringEscape(lx) 849 } 850 851 func lexStringEscape(lx *lexer) stateFn { 852 lx.esc = true 853 r := lx.next() 854 switch r { 855 case 'e': 856 if !lx.tomlNext { 857 return lx.error(errLexEscape{r}) 858 } 859 fallthrough 860 case 'b': 861 fallthrough 862 case 't': 863 fallthrough 864 case 'n': 865 fallthrough 866 case 'f': 867 fallthrough 868 case 'r': 869 fallthrough 870 case '"': 871 fallthrough 872 case ' ', '\t': 873 // Inside """ .. """ strings you can use \ to escape newlines, and any 874 // amount of whitespace can be between the \ and \n. 875 fallthrough 876 case '\\': 877 return lx.pop() 878 case 'x': 879 if !lx.tomlNext { 880 return lx.error(errLexEscape{r}) 881 } 882 return lexHexEscape 883 case 'u': 884 return lexShortUnicodeEscape 885 case 'U': 886 return lexLongUnicodeEscape 887 } 888 return lx.error(errLexEscape{r}) 889 } 890 891 func lexHexEscape(lx *lexer) stateFn { 892 var r rune 893 for i := 0; i < 2; i++ { 894 r = lx.next() 895 if !isHex(r) { 896 return lx.errorf(`expected two hexadecimal digits after '\x', but got %q instead`, lx.current()) 897 } 898 } 899 return lx.pop() 900 } 901 902 func lexShortUnicodeEscape(lx *lexer) stateFn { 903 var r rune 904 for i := 0; i < 4; i++ { 905 r = lx.next() 906 if !isHex(r) { 907 return lx.errorf(`expected four hexadecimal digits after '\u', but got %q instead`, lx.current()) 908 } 909 } 910 return lx.pop() 911 } 912 913 func lexLongUnicodeEscape(lx *lexer) stateFn { 914 var r rune 915 for i := 0; i < 8; i++ { 916 r = lx.next() 917 if !isHex(r) { 918 return lx.errorf(`expected eight hexadecimal digits after '\U', but got %q instead`, lx.current()) 919 } 920 } 921 return lx.pop() 922 } 923 924 // lexNumberOrDateStart processes the first character of a value which begins 925 // with a digit. It exists to catch values starting with '0', so that 926 // lexBaseNumberOrDate can differentiate base prefixed integers from other 927 // types. 928 func lexNumberOrDateStart(lx *lexer) stateFn { 929 r := lx.next() 930 switch r { 931 case '0': 932 return lexBaseNumberOrDate 933 } 934 935 if !isDigit(r) { 936 // The only way to reach this state is if the value starts 937 // with a digit, so specifically treat anything else as an 938 // error. 939 return lx.errorf("expected a digit but got %q", r) 940 } 941 942 return lexNumberOrDate 943 } 944 945 // lexNumberOrDate consumes either an integer, float or datetime. 946 func lexNumberOrDate(lx *lexer) stateFn { 947 r := lx.next() 948 if isDigit(r) { 949 return lexNumberOrDate 950 } 951 switch r { 952 case '-', ':': 953 return lexDatetime 954 case '_': 955 return lexDecimalNumber 956 case '.', 'e', 'E': 957 return lexFloat 958 } 959 960 lx.backup() 961 lx.emit(itemInteger) 962 return lx.pop() 963 } 964 965 // lexDatetime consumes a Datetime, to a first approximation. 966 // The parser validates that it matches one of the accepted formats. 967 func lexDatetime(lx *lexer) stateFn { 968 r := lx.next() 969 if isDigit(r) { 970 return lexDatetime 971 } 972 switch r { 973 case '-', ':', 'T', 't', ' ', '.', 'Z', 'z', '+': 974 return lexDatetime 975 } 976 977 lx.backup() 978 lx.emitTrim(itemDatetime) 979 return lx.pop() 980 } 981 982 // lexHexInteger consumes a hexadecimal integer after seeing the '0x' prefix. 983 func lexHexInteger(lx *lexer) stateFn { 984 r := lx.next() 985 if isHex(r) { 986 return lexHexInteger 987 } 988 switch r { 989 case '_': 990 return lexHexInteger 991 } 992 993 lx.backup() 994 lx.emit(itemInteger) 995 return lx.pop() 996 } 997 998 // lexOctalInteger consumes an octal integer after seeing the '0o' prefix. 999 func lexOctalInteger(lx *lexer) stateFn { 1000 r := lx.next() 1001 if isOctal(r) { 1002 return lexOctalInteger 1003 } 1004 switch r { 1005 case '_': 1006 return lexOctalInteger 1007 } 1008 1009 lx.backup() 1010 lx.emit(itemInteger) 1011 return lx.pop() 1012 } 1013 1014 // lexBinaryInteger consumes a binary integer after seeing the '0b' prefix. 1015 func lexBinaryInteger(lx *lexer) stateFn { 1016 r := lx.next() 1017 if isBinary(r) { 1018 return lexBinaryInteger 1019 } 1020 switch r { 1021 case '_': 1022 return lexBinaryInteger 1023 } 1024 1025 lx.backup() 1026 lx.emit(itemInteger) 1027 return lx.pop() 1028 } 1029 1030 // lexDecimalNumber consumes a decimal float or integer. 1031 func lexDecimalNumber(lx *lexer) stateFn { 1032 r := lx.next() 1033 if isDigit(r) { 1034 return lexDecimalNumber 1035 } 1036 switch r { 1037 case '.', 'e', 'E': 1038 return lexFloat 1039 case '_': 1040 return lexDecimalNumber 1041 } 1042 1043 lx.backup() 1044 lx.emit(itemInteger) 1045 return lx.pop() 1046 } 1047 1048 // lexDecimalNumber consumes the first digit of a number beginning with a sign. 1049 // It assumes the sign has already been consumed. Values which start with a sign 1050 // are only allowed to be decimal integers or floats. 1051 // 1052 // The special "nan" and "inf" values are also recognized. 1053 func lexDecimalNumberStart(lx *lexer) stateFn { 1054 r := lx.next() 1055 1056 // Special error cases to give users better error messages 1057 switch r { 1058 case 'i': 1059 if !lx.accept('n') || !lx.accept('f') { 1060 return lx.errorf("invalid float: '%s'", lx.current()) 1061 } 1062 lx.emit(itemFloat) 1063 return lx.pop() 1064 case 'n': 1065 if !lx.accept('a') || !lx.accept('n') { 1066 return lx.errorf("invalid float: '%s'", lx.current()) 1067 } 1068 lx.emit(itemFloat) 1069 return lx.pop() 1070 case '0': 1071 p := lx.peek() 1072 switch p { 1073 case 'b', 'o', 'x': 1074 return lx.errorf("cannot use sign with non-decimal numbers: '%s%c'", lx.current(), p) 1075 } 1076 case '.': 1077 return lx.errorf("floats must start with a digit, not '.'") 1078 } 1079 1080 if isDigit(r) { 1081 return lexDecimalNumber 1082 } 1083 1084 return lx.errorf("expected a digit but got %q", r) 1085 } 1086 1087 // lexBaseNumberOrDate differentiates between the possible values which 1088 // start with '0'. It assumes that before reaching this state, the initial '0' 1089 // has been consumed. 1090 func lexBaseNumberOrDate(lx *lexer) stateFn { 1091 r := lx.next() 1092 // Note: All datetimes start with at least two digits, so we don't 1093 // handle date characters (':', '-', etc.) here. 1094 if isDigit(r) { 1095 return lexNumberOrDate 1096 } 1097 switch r { 1098 case '_': 1099 // Can only be decimal, because there can't be an underscore 1100 // between the '0' and the base designator, and dates can't 1101 // contain underscores. 1102 return lexDecimalNumber 1103 case '.', 'e', 'E': 1104 return lexFloat 1105 case 'b': 1106 r = lx.peek() 1107 if !isBinary(r) { 1108 lx.errorf("not a binary number: '%s%c'", lx.current(), r) 1109 } 1110 return lexBinaryInteger 1111 case 'o': 1112 r = lx.peek() 1113 if !isOctal(r) { 1114 lx.errorf("not an octal number: '%s%c'", lx.current(), r) 1115 } 1116 return lexOctalInteger 1117 case 'x': 1118 r = lx.peek() 1119 if !isHex(r) { 1120 lx.errorf("not a hexidecimal number: '%s%c'", lx.current(), r) 1121 } 1122 return lexHexInteger 1123 } 1124 1125 lx.backup() 1126 lx.emit(itemInteger) 1127 return lx.pop() 1128 } 1129 1130 // lexFloat consumes the elements of a float. It allows any sequence of 1131 // float-like characters, so floats emitted by the lexer are only a first 1132 // approximation and must be validated by the parser. 1133 func lexFloat(lx *lexer) stateFn { 1134 r := lx.next() 1135 if isDigit(r) { 1136 return lexFloat 1137 } 1138 switch r { 1139 case '_', '.', '-', '+', 'e', 'E': 1140 return lexFloat 1141 } 1142 1143 lx.backup() 1144 lx.emit(itemFloat) 1145 return lx.pop() 1146 } 1147 1148 // lexBool consumes a bool string: 'true' or 'false. 1149 func lexBool(lx *lexer) stateFn { 1150 var rs []rune 1151 for { 1152 r := lx.next() 1153 if !unicode.IsLetter(r) { 1154 lx.backup() 1155 break 1156 } 1157 rs = append(rs, r) 1158 } 1159 s := string(rs) 1160 switch s { 1161 case "true", "false": 1162 lx.emit(itemBool) 1163 return lx.pop() 1164 } 1165 return lx.errorf("expected value but found %q instead", s) 1166 } 1167 1168 // lexCommentStart begins the lexing of a comment. It will emit 1169 // itemCommentStart and consume no characters, passing control to lexComment. 1170 func lexCommentStart(lx *lexer) stateFn { 1171 lx.ignore() 1172 lx.emit(itemCommentStart) 1173 return lexComment 1174 } 1175 1176 // lexComment lexes an entire comment. It assumes that '#' has been consumed. 1177 // It will consume *up to* the first newline character, and pass control 1178 // back to the last state on the stack. 1179 func lexComment(lx *lexer) stateFn { 1180 switch r := lx.next(); { 1181 case isNL(r) || r == eof: 1182 lx.backup() 1183 lx.emit(itemText) 1184 return lx.pop() 1185 default: 1186 return lexComment 1187 } 1188 } 1189 1190 // lexSkip ignores all slurped input and moves on to the next state. 1191 func lexSkip(lx *lexer, nextState stateFn) stateFn { 1192 lx.ignore() 1193 return nextState 1194 } 1195 1196 func (s stateFn) String() string { 1197 name := runtime.FuncForPC(reflect.ValueOf(s).Pointer()).Name() 1198 if i := strings.LastIndexByte(name, '.'); i > -1 { 1199 name = name[i+1:] 1200 } 1201 if s == nil { 1202 name = "<nil>" 1203 } 1204 return name + "()" 1205 } 1206 1207 func (itype itemType) String() string { 1208 switch itype { 1209 case itemError: 1210 return "Error" 1211 case itemNIL: 1212 return "NIL" 1213 case itemEOF: 1214 return "EOF" 1215 case itemText: 1216 return "Text" 1217 case itemString, itemStringEsc, itemRawString, itemMultilineString, itemRawMultilineString: 1218 return "String" 1219 case itemBool: 1220 return "Bool" 1221 case itemInteger: 1222 return "Integer" 1223 case itemFloat: 1224 return "Float" 1225 case itemDatetime: 1226 return "DateTime" 1227 case itemTableStart: 1228 return "TableStart" 1229 case itemTableEnd: 1230 return "TableEnd" 1231 case itemKeyStart: 1232 return "KeyStart" 1233 case itemKeyEnd: 1234 return "KeyEnd" 1235 case itemArray: 1236 return "Array" 1237 case itemArrayEnd: 1238 return "ArrayEnd" 1239 case itemCommentStart: 1240 return "CommentStart" 1241 case itemInlineTableStart: 1242 return "InlineTableStart" 1243 case itemInlineTableEnd: 1244 return "InlineTableEnd" 1245 } 1246 panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) 1247 } 1248 1249 func (item item) String() string { 1250 return fmt.Sprintf("(%s, %s)", item.typ, item.val) 1251 } 1252 1253 func isWhitespace(r rune) bool { return r == '\t' || r == ' ' } 1254 func isNL(r rune) bool { return r == '\n' || r == '\r' } 1255 func isControl(r rune) bool { // Control characters except \t, \r, \n 1256 switch r { 1257 case '\t', '\r', '\n': 1258 return false 1259 default: 1260 return (r >= 0x00 && r <= 0x1f) || r == 0x7f 1261 } 1262 } 1263 func isDigit(r rune) bool { return r >= '0' && r <= '9' } 1264 func isBinary(r rune) bool { return r == '0' || r == '1' } 1265 func isOctal(r rune) bool { return r >= '0' && r <= '7' } 1266 func isHex(r rune) bool { return (r >= '0' && r <= '9') || (r|0x20 >= 'a' && r|0x20 <= 'f') } 1267 func isBareKeyChar(r rune, tomlNext bool) bool { 1268 if tomlNext { 1269 return (r >= 'A' && r <= 'Z') || 1270 (r >= 'a' && r <= 'z') || 1271 (r >= '0' && r <= '9') || 1272 r == '_' || r == '-' || 1273 r == 0xb2 || r == 0xb3 || r == 0xb9 || (r >= 0xbc && r <= 0xbe) || 1274 (r >= 0xc0 && r <= 0xd6) || (r >= 0xd8 && r <= 0xf6) || (r >= 0xf8 && r <= 0x037d) || 1275 (r >= 0x037f && r <= 0x1fff) || 1276 (r >= 0x200c && r <= 0x200d) || (r >= 0x203f && r <= 0x2040) || 1277 (r >= 0x2070 && r <= 0x218f) || (r >= 0x2460 && r <= 0x24ff) || 1278 (r >= 0x2c00 && r <= 0x2fef) || (r >= 0x3001 && r <= 0xd7ff) || 1279 (r >= 0xf900 && r <= 0xfdcf) || (r >= 0xfdf0 && r <= 0xfffd) || 1280 (r >= 0x10000 && r <= 0xeffff) 1281 } 1282 1283 return (r >= 'A' && r <= 'Z') || 1284 (r >= 'a' && r <= 'z') || 1285 (r >= '0' && r <= '9') || 1286 r == '_' || r == '-' 1287 }