| 457 | } |
| 458 | |
| 459 | func ParseKeyValues(input string) (result KeyValues, err error) { |
| 460 | // result = append(result, "a", 2) |
| 461 | l := lex(input) |
| 462 | |
| 463 | for { |
| 464 | // alpha key |
| 465 | key := l.acceptRun(unicode.IsLetter) |
| 466 | if key == "" { |
| 467 | err = l.Error("Expected key") |
| 468 | return |
| 469 | } |
| 470 | // equals separator |
| 471 | if !l.accept("=") { |
| 472 | err = l.Error("Expected =") |
| 473 | return |
| 474 | } |
| 475 | // value (string or int) |
| 476 | var value interface{} |
| 477 | if l.accept(`"`) { |
| 478 | // quoted string |
| 479 | str := "" |
| 480 | for { |
| 481 | if l.eof() { |
| 482 | err = l.Error("Unterminated quoted string") |
| 483 | return |
| 484 | } else if l.accept(`\`) { |
| 485 | str += l.acceptAny() |
| 486 | } else if l.accept(`"`) { |
| 487 | break |
| 488 | } else { |
| 489 | str += l.acceptAny() |
| 490 | } |
| 491 | } |
| 492 | value = str |
| 493 | } else if num := l.acceptRun(unicode.IsDigit); num != "" { |
| 494 | value, err = strconv.Atoi(num) |
| 495 | if err != nil { |
| 496 | return |
| 497 | } |
| 498 | } else { |
| 499 | err = l.Error("Unexpected token") |
| 500 | return |
| 501 | } |
| 502 | result = append(result, key, value) |
| 503 | if l.eof() { |
| 504 | break |
| 505 | } |
| 506 | // whitespace between multiple key values |
| 507 | if l.acceptRun(unicode.IsSpace) == "" { |
| 508 | err = l.Error("Expected whitespace") |
| 509 | return |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | return |
| 514 | } |