added lazy to parser
This commit is contained in:
parent
4ca3d7d51a
commit
5abefd8dbe
2 changed files with 62 additions and 0 deletions
|
|
@ -114,6 +114,10 @@ class P(Generic[T]):
|
|||
def surround(self, other: P[Any]) -> P[T]:
|
||||
return P.map3(other, self, other, lambda _1, v, _2: v)
|
||||
|
||||
def some_lazy(self) -> P[list[T]]:
|
||||
return P._fix(lambda p: self.bind(
|
||||
lambda x: P.either(P.pure([]), p).fmap(lambda ys: [x] + ys)))
|
||||
|
||||
def some(self) -> P[list[T]]:
|
||||
return P._fix(lambda p: self.bind(
|
||||
lambda x: P.either(p, P.pure([])).fmap(lambda ys: [x] + ys)))
|
||||
|
|
@ -121,12 +125,18 @@ class P(Generic[T]):
|
|||
def many(self) -> P[list[T]]:
|
||||
return P.either(self.some(), P.pure([]))
|
||||
|
||||
def many_lazy(self) -> P[list[T]]:
|
||||
return P.either(P.pure([]), self.some_lazy())
|
||||
|
||||
def satisfies(self, pred: Callable[[T], bool]) -> P[T]:
|
||||
return self.bind(lambda v: P.pure(v) if pred(v) else P.fail())
|
||||
|
||||
def optional(self) -> P[T | None]:
|
||||
return P.either(self, P.pure(None))
|
||||
|
||||
def optional_lazy(self) -> P[T | None]:
|
||||
return P.either(P.pure(None), self)
|
||||
|
||||
def times(self, *, max: int | None = None, min: int | None = None,
|
||||
exact: int | None = None) -> P[list[T]]:
|
||||
match (exact, min, max):
|
||||
|
|
@ -139,6 +149,18 @@ class P(Generic[T]):
|
|||
case _:
|
||||
raise Exception("Choose exactly one of exact, min or max")
|
||||
|
||||
def times_lazy(self, *, max: int | None = None, min: int | None = None,
|
||||
exact: int | None = None) -> P[list[T]]:
|
||||
match (exact, min, max):
|
||||
case (int(e), None, None):
|
||||
return self.many_lazy().satisfies(lambda lst: len(lst) == e)
|
||||
case (None, int(mn), None):
|
||||
return self.many_lazy().satisfies(lambda lst: len(lst) >= mn)
|
||||
case (None, None, int(mx)):
|
||||
return self.many_lazy().satisfies(lambda lst: len(lst) <= mx)
|
||||
case _:
|
||||
raise Exception("Choose exactly one of exact, min or max")
|
||||
|
||||
def sep_by(self, sep: P[Any]) -> P[list[T]]:
|
||||
return P.map2(self, P.snd(sep, self).many(), lambda f, r: [f] + r)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue