(lval *sqlSymType)
| 495 | } |
| 496 | |
| 497 | func (s *scanner) scanIdent(lval *sqlSymType) { |
| 498 | s.pos-- |
| 499 | start := s.pos |
| 500 | isASCII := true |
| 501 | isLower := true |
| 502 | |
| 503 | // Consume the scanner character by character, stopping after the last legal |
| 504 | // identifier character. By the end of this function, we need to |
| 505 | // lowercase and unicode normalize this identifier, which is expensive if |
| 506 | // there are actual unicode characters in it. If not, it's quite cheap - and |
| 507 | // if it's lowercase already, there's no work to do. Therefore, we keep track |
| 508 | // of whether the string is only ASCII or only ASCII lowercase for later. |
| 509 | for { |
| 510 | ch := s.peek() |
| 511 | //fmt.Println(ch, ch >= utf8.RuneSelf, ch >= 'A' && ch <= 'Z') |
| 512 | |
| 513 | if ch >= utf8.RuneSelf { |
| 514 | isASCII = false |
| 515 | } else if ch >= 'A' && ch <= 'Z' { |
| 516 | isLower = false |
| 517 | } |
| 518 | |
| 519 | if !lex.IsIdentMiddle(ch) { |
| 520 | break |
| 521 | } |
| 522 | |
| 523 | s.pos++ |
| 524 | } |
| 525 | //fmt.Println("parsed: ", s.in[start:s.pos], isASCII, isLower) |
| 526 | |
| 527 | if isLower { |
| 528 | // Already lowercased - nothing to do. |
| 529 | lval.str = s.in[start:s.pos] |
| 530 | } else if isASCII { |
| 531 | // We know that the identifier we've seen so far is ASCII, so we don't need |
| 532 | // to unicode normalize. Instead, just lowercase as normal. |
| 533 | b := s.allocBytes(s.pos - start) |
| 534 | _ = b[s.pos-start-1] // For bounds check elimination. |
| 535 | for i, c := range s.in[start:s.pos] { |
| 536 | if c >= 'A' && c <= 'Z' { |
| 537 | c += 'a' - 'A' |
| 538 | } |
| 539 | b[i] = byte(c) |
| 540 | } |
| 541 | lval.str = *(*string)(unsafe.Pointer(&b)) |
| 542 | } else { |
| 543 | // The string has unicode in it. No choice but to run Normalize. |
| 544 | lval.str = lex.NormalizeName(s.in[start:s.pos]) |
| 545 | } |
| 546 | |
| 547 | isExperimental := false |
| 548 | kw := lval.str |
| 549 | switch { |
| 550 | case strings.HasPrefix(lval.str, "experimental_"): |
| 551 | kw = lval.str[13:] |
| 552 | isExperimental = true |
| 553 | case strings.HasPrefix(lval.str, "testing_"): |
| 554 | kw = lval.str[8:] |
no test coverage detected