From be245b258c8b608c75e57124c40a4136c9daafa1 Mon Sep 17 00:00:00 2001 From: Brandon Dyck Date: Wed, 18 Sep 2024 13:01:44 -0600 Subject: [PATCH] Added Run convenience function --- TODO.txt | 2 +- gigaparsec.go | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index d36a81f..7e001b8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,7 @@ -Add a convenient way to run parsers Add repetition parsers to avoid some recursion Think about not requiring so much Pos() when making messages Rename Seq2 to Seq Document Seq +Should MakeState be private now that there's Run? Add SPDX tags What's Megaparsec got that we ain't got? diff --git a/gigaparsec.go b/gigaparsec.go index 67a53b1..3fb5f5b 100644 --- a/gigaparsec.go +++ b/gigaparsec.go @@ -165,6 +165,27 @@ func (p Parser[In, Out]) Label(label string) Parser[In, Out] { } } +type ParseError Message + +func (pe ParseError) Error() string { + return Message(pe).String() +} + +func Run[In, Out any](p Parser[In, Out], c cursor.Cursor[In]) (out Out, err error) { + start := MakeState(c) + result, err := p(start) + if err != nil { + err = fmt.Errorf("Run: %w", err) + return + } + if failed, _, msg := result.Failed(); failed { + err = ParseError(msg) + return + } + _, _, out, _, _ = result.Succeeded() + return +} + // Return creates a parser that always succeeds and returns value without consuming any input. func Return[In, Out any](value Out) Parser[In, Out] { return func(state State[In]) (Result[In, Out], error) {