Separate parsing status from actual errors

This commit is contained in:
2024-09-11 10:25:45 -06:00
parent c1eae9fa34
commit d0460e71e3
3 changed files with 140 additions and 109 deletions

View File

@ -46,18 +46,18 @@ func Regexp(str string) gigaparsec.Parser[byte, []byte] {
}
re := regexp.MustCompile(str)
expected := fmt.Sprintf("match `%s`", str)
return func(input gigaparsec.State[byte]) (consumed bool, result gigaparsec.Result[byte, []byte], err error) {
return func(input gigaparsec.State[byte]) (gigaparsec.Result[byte, []byte], error) {
r := NewRuneReader(input.Cursor())
idx := re.FindReaderIndex(r)
// TODO Check error from r; this requires an Error() method on cursor.RuneReader.
if idx == nil {
return false, gigaparsec.Result[byte, []byte]{}, gigaparsec.ParseError{
return gigaparsec.Fail[byte, []byte](false, gigaparsec.Message{
Pos: input.Pos(),
Expected: []string{expected},
// TODO Not having a Got is unsatisfactory, but how do I extract useful information?
// Maybe just read a fixed number of bytes or to the end, whichever comes first?
// I could add extra methods to cursor.RuneReader to figure out how much it had read.
}
}), nil
}
// Alas, this is a little wasteful because a Regexp can only return indices
// when searching a RuneReader.
@ -65,13 +65,9 @@ func Regexp(str string) gigaparsec.Parser[byte, []byte] {
n, _, err := input.Cursor().Read(dst)
if err != nil {
// If we can't access those same bytes again, something is wrong.
return false, gigaparsec.Result[byte, []byte]{}, fmt.Errorf("Regex: unexpected error: %w", err)
return gigaparsec.Result[byte, []byte]{}, fmt.Errorf("Regex: unexpected error: %w", err)
}
result = gigaparsec.Result[byte, []byte]{
State: input.At(input.Pos() + n),
Value: dst,
Message: gigaparsec.MessageOK(input.Pos()),
}
return true, result, nil
next := input.At(input.Pos() + n)
return gigaparsec.Succeed(true, dst, next, gigaparsec.MessageOK(input.Pos())), nil
}
}