@@ -25,10 +25,6 @@ def _first(self) -> list[str]:
2525 if self ._max_len is not None and self ._max_len == self ._min_len :
2626 self .done = True
2727
28- if self ._min_len == 0 :
29- self ._last = ['' ]
30- return ['' ]
31-
3228 result = ['' ]
3329 for _ in range (self ._min_len ):
3430 result = [pfx + sfx for pfx in self ._chars for sfx in result ]
@@ -98,11 +94,16 @@ class Alternative:
9894 def __init__ (self , elements : list [CharClass | RegexTree | BackReference ]):
9995 self ._index = 0
10096 self ._elements = [e for e in elements if not e .done or len (e .current )]
97+ self ._noBackreference = not any (isinstance (
98+ e , BackReference ) for e in self ._elements )
10199 self ._base = len (self ._elements )
102100 self .done = self ._base == 0
103101 self .current = self ._first ()
104102
105103 def next (self ) -> set [str ]:
104+ if self ._noBackreference :
105+ return self ._next_no_backreference ()
106+
106107 assert not self .done
107108 assert not isinstance (self ._elements [0 ], BackReference )
108109
@@ -153,10 +154,52 @@ def next(self) -> set[str]:
153154 self .current .update (new_strings )
154155 return new_strings
155156
157+ def _first_no_backreference (self ) -> set [str ]:
158+ result : set [str ] = {'' }
159+ done = True
160+
161+ for element in self ._elements :
162+ done = done and element .done
163+ result = {pfx + sfx for pfx in result for sfx in element .current }
164+
165+ self .done = done
166+ return result
167+
168+ def _next_no_backreference (self ) -> set [str ]:
169+ assert not self .done
170+
171+ index = self ._index + 1
172+ if index >= self ._base :
173+ index = 0
174+ while self ._elements [index ].done :
175+ index += 1
176+ if index >= self ._base :
177+ index = 0
178+
179+ self ._index = index
180+ result : set [str ] = {'' }
181+ done = True
182+
183+ for i , element in enumerate (self ._elements ):
184+ if i == index :
185+ strings = element .next ()
186+ else :
187+ strings = element .current
188+ done = done and element .done
189+ result = {pfx + sfx for pfx in result for sfx in strings }
190+
191+ self .done = done
192+ result -= self .current
193+ self .current .update (result )
194+ return result
195+
156196 def _first (self ) -> set [str ]:
157197 if self .done :
158198 return {'' }
159199
200+ if self ._noBackreference :
201+ return self ._first_no_backreference ()
202+
160203 assert not isinstance (self ._elements [0 ], BackReference )
161204
162205 result : list [tuple [str , dict [RegexTree , str ]]] = []
0 commit comments