import abc
import re
from typing import Any, Callable, Optional
import parse
[docs]
class Parser(object, metaclass=abc.ABCMeta):
[docs]
@abc.abstractmethod
def match(self, sentence: str) -> Any:
pass
[docs]
@abc.abstractmethod
def bind(self, func: Callable[..., Any], match: Any) -> Callable[..., Any]:
pass
[docs]
class RegExParser(Parser):
"""
Parser implementation, matching regex on step sentences
"""
def __init__(self, expression: str) -> None:
self.expression = re.compile(expression)
[docs]
def match(self, sentence: str) -> Optional[re.Match[str]]:
return self.expression.match(sentence)
[docs]
def bind(
self, func: Callable[..., Any], match: re.Match[str]
) -> Callable[..., Any]:
return lambda env, result, context, *args: func(
env, result, context, *args, **match.groupdict()
)
[docs]
class SimpleParser(Parser):
"""
Parser implementation, using parse library to simplify match strings
"""
def __init__(self, format_string: str) -> None:
self.parser = parse.compile(format_string, case_sensitive=True)
[docs]
def match(self, sentence: str) -> Any:
return self.parser.parse(sentence)
[docs]
def bind(self, func: Callable[..., Any], match: Any) -> Callable[..., Any]:
return lambda env, result, context, *args: func(
env, result, context, *args, **match.named
)