eatIdentifier consumes a bare or double-quoted identifier.
()
| 357 | |
| 358 | // eatIdentifier consumes a bare or double-quoted identifier. |
| 359 | func (t *tokenizer) eatIdentifier() (string, bool) { |
| 360 | t.skipSpace() |
| 361 | if t.i >= len(t.s) { |
| 362 | return "", false |
| 363 | } |
| 364 | if t.s[t.i] == '"' { |
| 365 | end := skipQuoted(t.s, t.i, '"') |
| 366 | if end <= t.i+1 || t.s[end-1] != '"' { |
| 367 | return "", false |
| 368 | } |
| 369 | name := strings.ReplaceAll(t.s[t.i+1:end-1], `""`, `"`) |
| 370 | if name == "" { |
| 371 | return "", false |
| 372 | } |
| 373 | t.i = end |
| 374 | return name, true |
| 375 | } |
| 376 | if !isIdentStart(t.s[t.i]) { |
| 377 | return "", false |
| 378 | } |
| 379 | start := t.i |
| 380 | for t.i < len(t.s) && isIdentChar(t.s[t.i]) { |
| 381 | t.i++ |
| 382 | } |
| 383 | return t.s[start:t.i], true |
| 384 | } |
| 385 | |
| 386 | func isIdentStart(c byte) bool { |
| 387 | return c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') |
no test coverage detected