Transform pattern into an equivalent, with only top-level Either.
(self)
| 70 | |
| 71 | @property |
| 72 | def either(self): |
| 73 | """Transform pattern into an equivalent, with only top-level Either.""" |
| 74 | # Currently the pattern will not be equivalent, but more "narrow", |
| 75 | # although good enough to reason about list arguments. |
| 76 | ret = [] |
| 77 | groups = [[self]] |
| 78 | while groups: |
| 79 | children = groups.pop(0) |
| 80 | types = [type(c) for c in children] |
| 81 | if Either in types: |
| 82 | either = [c for c in children if type(c) is Either][0] |
| 83 | children.pop(children.index(either)) |
| 84 | for c in either.children: |
| 85 | groups.append([c] + children) |
| 86 | elif Required in types: |
| 87 | required = [c for c in children if type(c) is Required][0] |
| 88 | children.pop(children.index(required)) |
| 89 | groups.append(list(required.children) + children) |
| 90 | elif Optional in types: |
| 91 | optional = [c for c in children if type(c) is Optional][0] |
| 92 | children.pop(children.index(optional)) |
| 93 | groups.append(list(optional.children) + children) |
| 94 | elif AnyOptions in types: |
| 95 | optional = [c for c in children if type(c) is AnyOptions][0] |
| 96 | children.pop(children.index(optional)) |
| 97 | groups.append(list(optional.children) + children) |
| 98 | elif OneOrMore in types: |
| 99 | oneormore = [c for c in children if type(c) is OneOrMore][0] |
| 100 | children.pop(children.index(oneormore)) |
| 101 | groups.append(list(oneormore.children) * 2 + children) |
| 102 | else: |
| 103 | ret.append(children) |
| 104 | return Either(*[Required(*e) for e in ret]) |
| 105 | |
| 106 | |
| 107 | class ChildPattern(Pattern): |