CharacterEscape ::= | `c` ControlLetter | IdentityEscape | (Other sequences handled by `scanEscapeSequence`) IdentityEscape ::= | '^' | '$' | '/' | '\' | '.' | '*' | '+' | '?' | '(' | ')' | '[' | ']' | '{' | '}' | '|' | [~AnyUnicodeMode] (any other non-identifier characters)
(atomEscape bool)
| 434 | // | '^' | '$' | '/' | '\' | '.' | '*' | '+' | '?' | '(' | ')' | '[' | ']' | '{' | '}' | '|' |
| 435 | // | [~AnyUnicodeMode] (any other non-identifier characters) |
| 436 | func (p *regExpParser) scanCharacterEscape(atomEscape bool) string { |
| 437 | debug.Assert(p.pos() > 0 && p.text()[p.pos()-1] == '\\') |
| 438 | ch := p.char() |
| 439 | switch ch { |
| 440 | case -1: |
| 441 | p.error(diagnostics.Undetermined_character_escape, p.pos()-1, 1) |
| 442 | return "\\" |
| 443 | case 'c': |
| 444 | p.incPos(1) |
| 445 | ch = p.char() |
| 446 | if stringutil.IsASCIILetter(ch) { |
| 447 | p.incPos(1) |
| 448 | return string(ch & 0x1f) |
| 449 | } |
| 450 | if p.anyUnicodeModeOrNonAnnexB { |
| 451 | p.error(diagnostics.X_c_must_be_followed_by_an_ASCII_letter, p.pos()-2, 2) |
| 452 | } else if atomEscape { |
| 453 | p.incPos(-1) |
| 454 | return "\\" |
| 455 | } |
| 456 | return string(ch) |
| 457 | case '^', '$', '/', '\\', '.', '*', '+', '?', '(', ')', '[', ']', '{', '}', '|': |
| 458 | p.incPos(1) |
| 459 | return string(ch) |
| 460 | default: |
| 461 | p.incPos(-1) // back up to include the backslash for scanEscapeSequence |
| 462 | flags := EscapeSequenceScanningFlagsRegularExpression |
| 463 | if p.annexB { |
| 464 | flags |= EscapeSequenceScanningFlagsAnnexB |
| 465 | } |
| 466 | if p.anyUnicodeMode { |
| 467 | flags |= EscapeSequenceScanningFlagsAnyUnicodeMode |
| 468 | } |
| 469 | if atomEscape { |
| 470 | flags |= EscapeSequenceScanningFlagsAtomEscape |
| 471 | } |
| 472 | return p.scanner.scanEscapeSequence(flags) |
| 473 | } |
| 474 | } |
| 475 | |
| 476 | func (p *regExpParser) scanGroupName(isReference bool) { |
| 477 | debug.Assert(p.pos() > 0 && p.text()[p.pos()-1] == '<') |
no test coverage detected