delph-in / pydelphin

Python libraries for DELPH-IN
https://pydelphin.readthedocs.io/
MIT License
79 stars 27 forks source link

REPP crashing on unmatched groups in the replacement #301

Closed goodmami closed 4 years ago

goodmami commented 4 years ago

The REPP code assumes that match.group(index) will return a string, but if the group specified by index was not matched at all, the expression will return None, leading to some kind of type error. For instance:

>>> from delphin import repp
>>> repp.REPP.from_string(r'!(a)(b)*    \1 \2').apply('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 573, in apply
    return self.group.apply(s, active=active)
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 123, in apply
    for step in self._trace(s, set(active or []), False):
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 143, in _trace
    for step in self._apply(s, active):
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 335, in _apply
    for step in operation._apply(o, active):
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 243, in _apply
    _copy_part(literal, shift, parts, smap, emap)
  File "/home/goodmami/delphin/pydelphin/delphin/repp.py", line 679, in _copy_part
    smap.extend([shift] * len(s))
TypeError: object of type 'NoneType' has no len()

Also I think that the REPP rules that result in this error are bad patterns and should be fixed (e.g., something like !(a)(b*) \1 \2 for the above).