simplified parser

This commit is contained in:
Ruediger Ludwig 2022-12-12 05:49:41 +01:00
parent 4034c08cd9
commit 28fb30d493
3 changed files with 19 additions and 16 deletions

View file

@ -53,7 +53,7 @@ class Parser:
worry_inc, test, worry_inc, test,
lambda number, items, worry_inc, test: lambda number, items, worry_inc, test:
Monkey(number, items, worry_inc, *test)) Monkey(number, items, worry_inc, *test))
monkey_list: P[list[Monkey]] = P.first(monkey, P.eol().optional()).many() monkey_list: P[list[Monkey]] = P.second(P.eol().optional(), monkey).many()
WorryIncreaser = Callable[[int], int] WorryIncreaser = Callable[[int], int]
@ -111,7 +111,7 @@ class Troop_While_Worried(Troop):
""" The """ """ The """
@classmethod @classmethod
def parse(cls, lines: Iterator[str]) -> Self: def parse(cls, lines: Iterator[str]) -> Self:
monkeys = Parser.monkey_list.parse_iterator(lines).get() monkeys = Parser.monkey_list.parse(lines).get()
return Troop_While_Worried(monkeys) return Troop_While_Worried(monkeys)
def single_round(self): def single_round(self):
@ -126,7 +126,7 @@ class Troop_While_Kinda_Relieved(Troop):
@classmethod @classmethod
def parse(cls, lines: Iterator[str]) -> Self: def parse(cls, lines: Iterator[str]) -> Self:
monkeys = Parser.monkey_list.parse_iterator(lines).get() monkeys = Parser.monkey_list.parse(lines).get()
return Troop_While_Kinda_Relieved(monkeys, prod(monkey.modulator for monkey in monkeys)) return Troop_While_Kinda_Relieved(monkeys, prod(monkey.modulator for monkey in monkeys))
def single_round(self): def single_round(self):

View file

@ -112,24 +112,27 @@ class P(Generic[T]):
def __init__(self, func: ParserFunc[T]): def __init__(self, func: ParserFunc[T]):
self.func = func self.func = func
def parse(self, s: str) -> Result[T]: def parse(self, input: str | Iterator[str]) -> Result[T]:
all_results = self.func(SimpleParserInput(s, 0)) if isinstance(input, str):
parser_input = SimpleParserInput(input, 0)
else:
parser_input = IteratorParserInput(StringDispenser(input), 0)
all_results = self.func(parser_input)
try: try:
_, result = next(all_results) _, result = next(all_results)
return Result.of(result) return Result.of(result)
except StopIteration: except StopIteration:
return Result.fail("No result") return Result.fail("No result")
def parse_iterator(self, it: Iterator[str]) -> Result[T]: def parse_multi(self, input: str | Iterator[str]) -> Iterator[T]:
all_results = self.func(IteratorParserInput(StringDispenser(it), 0)) if isinstance(input, str):
try: parser_input = SimpleParserInput(input, 0)
_, result = next(all_results) else:
return Result.of(result) parser_input = IteratorParserInput(StringDispenser(input), 0)
except StopIteration:
return Result.fail("No result")
def parse_multi(self, s: str, i: int = 0) -> Iterator[T]: all_results = self.func(parser_input)
return (v for _, v in self.func(SimpleParserInput(s, i))) return (v for _, v in all_results)
@classmethod @classmethod
def pure(cls, value: T) -> P[T]: def pure(cls, value: T) -> P[T]:

View file

@ -275,7 +275,7 @@ def test_iterator_input():
input = iter(['1', '2']) input = iter(['1', '2'])
parser = P.unsigned().line().many() parser = P.unsigned().line().many()
expected = [1, 2] expected = [1, 2]
result = parser.parse_iterator(input).get() result = parser.parse(input).get()
assert result == expected assert result == expected
@ -283,5 +283,5 @@ def test_iterator_trim_input():
input = iter(['1 ', '2 ']) input = iter(['1 ', '2 '])
parser = P.unsigned().trim().line().many() parser = P.unsigned().trim().line().many()
expected = [1, 2] expected = [1, 2]
result = parser.parse_iterator(input).get() result = parser.parse(input).get()
assert result == expected assert result == expected