diff --git a/regexp.py b/regexp.py --- a/regexp.py +++ b/regexp.py @@ -66,6 +66,44 @@ class Asterisk(Plus): return str(self.content) + "*" +class Alternative(Token): + def __init__(self, content: list): + self.variants = [] + subsequence = [] + + for token in content: + if isinstance(token, AlternativeSeparator): + if not subsequence: + raise ParsingError("Found an empty Alternative variant.") + self.variants.append(Chain(subsequence)) + subsequence = [] + else: + subsequence.append(token) + + if not subsequence: + raise ParsingError("Found an empty Alternative variant.") + self.variants.append(Chain(subsequence)) + + + def list_first(self): + for x in self.variants: + yield from x.list_first() + + def list_last(self): + for x in self.variants: + yield from x.list_last() + + def list_neighbours(self): + for x in self.variants: + yield from x.list_neighbours() + + @property + def is_skippable(self): + return any(x.is_skippable for x in self.variants) + +class AlternativeSeparator: + pass + class Chain(Token): def __init__(self, content: list): self.content = content @@ -120,6 +158,7 @@ def find_closing_parenthesis(pattern, k) def parse(pattern, offset=0): res = [] + is_alternative = False i = 0 while i < len(pattern): @@ -145,11 +184,18 @@ def parse(pattern, offset=0): i += 1 elif c == ")": raise ParsingError(f'An opening parenthesis not found. Pattern: "{pattern}", position: {i}') + elif c == "|": + is_alternative = True + res.append(AlternativeSeparator()) + i += 1 else: res.append(Symbol(i+offset, c)) i += 1 - return Chain(res) + if is_alternative: + return Alternative(res) + else: + return Chain(res) class Regexp: