diff --git a/src/pyalibert/parser.py b/src/pyalibert/parser.py index a54b741..5c7af9a 100644 --- a/src/pyalibert/parser.py +++ b/src/pyalibert/parser.py @@ -24,6 +24,15 @@ def regex(pattern: str): def just(word: str): + """ + ## Just word + Parses this word and stops. Producing a string containing that word. + ```py + parser = just("arbre") + parsed = parser.parse("arbre") + assert parsed == "arbre" + ``` + """ return Parser(JustTransform(word)) @@ -39,6 +48,9 @@ class Parser(Generic[P]): inner: "Transformer[P]" def parse(self, stream: str) -> P: + """ + Parses a string until the end into the produced type P. + """ parser = self.and_(end()).map(lambda value : value[0]) parsed = parser.inner.parse(stream, 0) if isinstance(parsed, Failure): @@ -46,48 +58,202 @@ class Parser(Generic[P]): return parsed.value def and_(self, other: "Parser[T]"): + """ + ## P and T + Parses this, and then other ; producing a tuple of both types. + ```py + parser = just("arbre").and_(just("mort")) + parsed = parser.parse("arbremort") + assert parsed == ("arbre", "mort") + ``` + Shorthand operator is `&` : + ```py + just("arbre") & just("mort") + ``` + """ return Parser(AndTransform(self.inner, other.inner)) def or_(self, other: "Parser[T]"): + """ + ## P Or T + Parses this, or else other ; producing a union of both types. + ```py + parser = just("arbre").or_(just("mort")) + parsed = parser.parse("mort") + assert parsed == "mort" + ``` + Shorthand operator is `|` : + ```py + just("arbre") | just("mort") + ``` + """ return Parser(OrTransform(self.inner, other.inner)) def or_not(self): + """ + ## P Or not + Parses this, or else `None` ; producing an optional of P. + ```py + parser = just("arbre").or_not() + parsed = parser.parse("mort") + assert parsed == None + ``` + """ return Parser(OptionTransform(self.inner)) def repeat(self): + """ + ## Repeat P + Parses P zero or more times ; producing a list of P. + ```py + parser = just("arbre").repeat() + parsed = parser.parse("arbrearbre") + assert parsed == ["arbre", "arbre"] + ``` + """ return Parser(ListTransform(self.inner)) def map(self, transform: Callable[[P], O]): + """ + ## Maps P into O + Parses P and then converts it into an O using the provided transform. + Produces an O. + ```py + parser = just("ar").repeat().map(lambda w: len(w)) + parsed = parser.parse("ararar") + assert parsed == 3 + ``` + """ return Parser(MapTransform(self.inner, transform)) def set(self, value: T) -> "Parser[T]": + """ + ## Sets P to T + Parses P and then sets its value to the passed T. + Produces a T. + ```py + parser = just("arbre").set("1") | just("mort").set("2") + parsed = parser.parse("arbre") + assert parsed == 1 + ``` + """ return Parser(ValueTransform(self.inner, value)) def sep_by(self, sep: "Parser[T]"): + """ + ## Separate Ps with Ts + Parses a list of `P` separated by one `T` between each two `P`. + Produces a list of P and discards the Ts. + ```py + parser = just("a").sep_by(",") + parsed = parser.parse("a,a,a") + assert parsed == ["a", "a", "a"] + ``` + """ return Parser(SepListTransform(self.inner, sep.inner)) def join(self: "Parser[list[str]]", join: str = ""): + """ + ## Joins a list of str + Parses a list of `str` and joins the elements of the list by filling gaps with a given join value (defaults to `""`). + Produces a single `str`. + ```py + parser = just("a").sep_by(",").join() + parsed = parser.parse("a,a,a") + assert parsed == "aaa" + ``` + """ return Parser(JoinTransform(self.inner, join)) def concat(self: "Parser[tuple[str,str]]", join: str = ""): + """ + ## Concatenates P[0] and P[1] + Parses a tuple of (`str`, `str`) and joins the left, and right `str` with a given join value (defaults to `""`). + Produces a single str. + ```py + parser = (just("a") & just("b")).concat("@") + parsed = parser.parse("ab") + assert parsed == "a@b" + ``` + Shorthand operator is `+` : + ```py + just("a") + just("b") + ``` + """ return Parser(ConcatTransform(self.inner, join)) - # | - def __or__(self, other: "Parser[T]"): - return self.or_(other) - # & def __and__(self, other: "Parser[T]"): + """ + ## P and T + Parses this, and then other ; producing a tuple of both types. + ```py + parser = just("arbre").and_(just("mort")) + parsed = parser.parse("arbremort") + assert parsed == ("arbre", "mort") + ``` + Shorthand operator is `&` : + ```py + just("arbre") & just("mort") + ``` + """ return self.and_(other) + # | + def __or__(self, other: "Parser[T]"): + """ + ## P Or T + Parses this, or else other ; producing a union of both types. + ```py + parser = just("arbre").or_(just("mort")) + parsed = parser.parse("mort") + assert parsed == "mort" + ``` + Shorthand operator is `|` : + ```py + just("arbre") | just("mort") + ``` + """ + return self.or_(other) + # >> def __rshift__(self, other: "Parser[T]"): + """ + ## P and T + Parses this, then other and discards the left value, producing a T. + ```py + parser = just("arbre") >> just("mort") + parsed = parser.parse("arbremort") + assert parsed == "mort" + """ return self.and_(other).map(lambda v: v[1]) # << def __lshift__(self, other: "Parser[T]"): + """ + ## P and T + Parses this, then other and discards the right value, producing a P. + ```py + parser = just("arbre") << just("mort") + parsed = parser.parse("arbremort") + assert parsed == "arbre" + """ return self.and_(other).map(lambda v: v[0]) # + def __add__(self: "Parser[str]", other: "Parser[str]"): + """ + ## Concatenates P[0] and P[1] + Parses a tuple of (`str`, `str`) and joins the left, and right `str` with a given join value (defaults to `""`). + Produces a single str. + ```py + parser = (just("a") & just("b")).concat("@") + parsed = parser.parse("ab") + assert parsed == "a@b" + ``` + Shorthand operator is `+` : + ```py + just("a") + just("b") + ``` + """ return self.and_(other).concat()