Parse a unit at index i (advancing it), and return its string representation + whether it's a literal.
()
| 524 | return '"' + txt + '"' if is_literal else txt |
| 525 | |
| 526 | def transform() -> Tuple[str, bool]: |
| 527 | """ |
| 528 | Parse a unit at index i (advancing it), and return its string representation + whether it's a literal. |
| 529 | """ |
| 530 | nonlocal i |
| 531 | nonlocal pattern |
| 532 | nonlocal sub_rule_ids |
| 533 | |
| 534 | start = i |
| 535 | # For each component of this sequence, store its string representation and whether it's a literal. |
| 536 | # We only need a flat structure here to apply repetition operators to the last item, and |
| 537 | # to merge literals at the and (we're parsing grouped ( sequences ) recursively and don't treat '|' specially |
| 538 | # (GBNF's syntax is luckily very close to regular expressions!) |
| 539 | seq: list[Tuple[str, bool]] = [] |
| 540 | |
| 541 | def get_dot(): |
| 542 | if self._dotall: |
| 543 | rule = DOTALL |
| 544 | else: |
| 545 | # Accept any character... except \n and \r line break chars (\x0A and \xOD) |
| 546 | rule = DOT |
| 547 | return self._add_rule(f"dot", rule) |
| 548 | |
| 549 | def join_seq(): |
| 550 | nonlocal seq |
| 551 | ret = [] |
| 552 | for is_literal, g in groupby(seq, lambda x: x[1]): |
| 553 | if is_literal: |
| 554 | ret.append(("".join(x[0] for x in g), True)) |
| 555 | else: |
| 556 | ret.extend(g) |
| 557 | if len(ret) == 1: |
| 558 | return ret[0] |
| 559 | return (" ".join(to_rule(x) for x in seq), False) |
| 560 | |
| 561 | while i < length: |
| 562 | c = pattern[i] |
| 563 | if c == ".": |
| 564 | seq.append((get_dot(), False)) |
| 565 | i += 1 |
| 566 | elif c == "(": |
| 567 | i += 1 |
| 568 | if i < length: |
| 569 | assert pattern[i] != "?", ( |
| 570 | f'Unsupported pattern syntax "{pattern[i]}" at index {i} of /{pattern}/' |
| 571 | ) |
| 572 | seq.append((f"({to_rule(transform())})", False)) |
| 573 | elif c == ")": |
| 574 | i += 1 |
| 575 | assert start > 0 and pattern[start - 1] == "(", ( |
| 576 | f"Unbalanced parentheses; start = {start}, i = {i}, pattern = {pattern}" |
| 577 | ) |
| 578 | return join_seq() |
| 579 | elif c == "[": |
| 580 | square_brackets = c |
| 581 | i += 1 |
| 582 | while i < length and pattern[i] != "]": |
| 583 | if pattern[i] == "\\": |
nothing calls this directly
no test coverage detected