|
14 | 14 | from abc import abstractmethod, abstractstaticmethod
|
15 | 15 | from collections import defaultdict
|
16 | 16 | from copy import deepcopy
|
| 17 | +from functools import partial |
17 | 18 | from hashlib import sha256
|
18 | 19 | from typing import (
|
19 | 20 | Any,
|
@@ -133,6 +134,10 @@ def substitute(
|
133 | 134 | if end is None:
|
134 | 135 | end = start + len(content)
|
135 | 136 | if loc_type == 'index':
|
| 137 | + if (start > 0 and self.index[start] == self.index[start - 1]) or ( |
| 138 | + end < len(self) - 1 and self.index[end - 1] == self.index[end] |
| 139 | + ): |
| 140 | + return self |
136 | 141 | start = self.index[start]
|
137 | 142 | end = self.index[end]
|
138 | 143 | if start == end:
|
@@ -798,23 +803,31 @@ def parse(
|
798 | 803 | def verify_level(
|
799 | 804 | self,
|
800 | 805 | tree: SyntacticTree,
|
| 806 | + correct: bool = False, |
801 | 807 | ) -> SyntacticTree:
|
802 | 808 | if len(tree.children) != 0:
|
803 |
| - raise UnparsedTreeError( |
804 |
| - f'Unparsed non-transform node {tree} ' |
805 |
| - f'(full version: {tree.materialise(recursive=True)}) ' |
806 |
| - f'has children: {[v for v in tree.children.values()]}. ' |
807 |
| - 'All nodes must be either transforms or terminal (leaves).' |
808 |
| - ) |
| 809 | + if correct: |
| 810 | + tree.content = IndexedNestedString( |
| 811 | + IndexedNestedString(tree.materialise(recursive=True)), |
| 812 | + ) |
| 813 | + tree.children = {} |
| 814 | + else: |
| 815 | + raise UnparsedTreeError( |
| 816 | + f'Unparsed non-transform node {tree} ' |
| 817 | + f'(full version: {tree.materialise(recursive=True)}) ' |
| 818 | + f'has children: {[v for v in tree.children.values()]}. ' |
| 819 | + 'All nodes must be either transforms or terminal (leaves).' |
| 820 | + ) |
809 | 821 | return tree
|
810 | 822 |
|
811 | 823 | def verify_parse(
|
812 | 824 | self,
|
813 | 825 | tree: SyntacticTree,
|
| 826 | + correct: bool = False, |
814 | 827 | ) -> None:
|
815 | 828 | Grammar.recur_depth_first(
|
816 | 829 | tree=tree,
|
817 |
| - f=self.verify_level, |
| 830 | + f=partial(self.verify_level, correct=correct), |
818 | 831 | skip_transform_roots=True,
|
819 | 832 | )
|
820 | 833 |
|
@@ -927,7 +940,7 @@ def transform(
|
927 | 940 | self,
|
928 | 941 | tree: SyntacticTree,
|
929 | 942 | ) -> TransformTree:
|
930 |
| - self.verify_parse(tree) |
| 943 | + self.verify_parse(tree, correct=True) |
931 | 944 | tree = self.transform_impl(tree)
|
932 | 945 | return Grammar.annotate_leaf_count(tree)
|
933 | 946 |
|
|
0 commit comments