diff --git a/regexp.py b/regexp.py --- a/regexp.py +++ b/regexp.py @@ -1,6 +1,10 @@ from abc import abstractmethod +class ParsingError(Exception): + pass + + class Token: is_skippable = False @@ -111,7 +115,7 @@ def find_closing_parenthesis(pattern, k) if counter == 0: return k+i - return None + raise ParsingError(f'A closing parenthesis not found. Pattern: "{pattern}", position: {k}') def parse(pattern, offset=0): @@ -126,13 +130,21 @@ def parse(pattern, offset=0): res.append(inner_content) i = j+1 elif c == "*": - token = res.pop() + try: + token = res.pop() + except IndexError as e: + raise ParsingError(f'The asterisk operator is missing an argument. Pattern: "{pattern}", position {i}') res.append(Asterisk(token)) i += 1 elif c == "+": - token = res.pop() + try: + token = res.pop() + except IndexError as e: + raise ParsingError(f'The plus operator is missing an argument. Pattern: "{pattern}", position {i}') res.append(Plus(token)) i += 1 + elif c == ")": + raise ParsingError(f'An opening parenthesis not found. Pattern: "{pattern}", position: {i}') else: res.append(Symbol(i+offset, c)) i += 1 @@ -228,9 +240,14 @@ class RegexpDFA: if __name__ == "__main__": tests = ["", "a", "ab", "aabb", "abab", "abcd", "abcbcdbcd"] - for pattern in ["a*b*", "a+b+", "(ab)*", "(ab)+", "a((bc)*d)*"]: + for pattern in ["*", "((a)", "a)"]: print("#", pattern) - r = RegexpDFA(pattern) + try: + r = RegexpDFA(pattern) + except ParsingError as e: + print("Failed to parse the regexp:") + print(e) + continue for t in tests: print(t, r.match(t)) print()