}
}
func tag(t string) parser[string] {
b := []byte(t)
return func(input []byte) (rest []byte, value string, err error) {
if bytes.HasPrefix(input, b) {
return input[len(b):], t, nil
} else {
return input, "", fmt.Errorf("not found: %q", t)
}
}
}
func value[T, U any](val T, p parser[U]) parser[T] {
return func(input []byte) (rest []byte, value T, err error) {
rest, _, err = p(input)
if err != nil {
return input, value, err
}
return rest, val, nil
}
}
// takeAny returns the longest input slice (if any) that contains only
// characters found in set.
func takeAny(set string) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest = bytes.TrimLeft(input, set)
return rest, input[:len(input)-len(rest)], nil
}
}
// takeAny1 returns the longest input slice that contains only
// characters found in set. If it doesn't find at least one byte that matches,
// it returns an error.
func takeAny1(set string) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest = bytes.TrimLeft(input, set)
if len(rest) == len(input) {
return input, nil, fmt.Errorf("nothing matching %q was found", set)
}
return rest, input[:len(input)-len(rest)], nil
}
}
func positiveInt(input []byte) (rest []byte, value int, err error) {
return mapWithError(
takeAny1("0123456789"),
func(b []byte) (int, error) {
return strconv.Atoi(string(b))
},
)(input)
}
func delimited[T, U, V any](left parser[T], inner parser[U], right parser[V]) parser[U] {
return func(input []byte) (rest []byte, value U, err error) {
rest, _, err = left(input)
if err != nil {
return
}
rest, value, err = inner(rest)
if err != nil {
return
}
rest, _, err = right(rest)
return
}
}
func terminated[T, U any](first parser[T], second parser[U]) parser[T] {
return func(input []byte) (rest []byte, value T, err error) {
rest, value, err = first(input)
if err != nil {
return
}
rest, _, err = second(rest)
return
}
}
func preceded[T, U any](first parser[T], second parser[U]) parser[U] {
return func(input []byte) (rest []byte, value U, err error) {
rest, _, err = first(input)
if err != nil {
return
}
rest, value, err = second(rest)
return
}
}
func space0(input []byte) (rest []byte, value []byte, err error) {
return takeAny(" \t")(input)
}
func multispace0(input []byte) (rest []byte, value []byte, err error) {
return takeAny(" \t\r\n")(input)
}
func lineEnding(input []byte) (rest []byte, value string, err error) {
return alt(tag("\n"), tag("\r\n"))(input)
}
func takeWhile(f func(byte) bool) parser[[]byte] {
return func(input []byte) ([]byte, []byte, error) {
i := 0
for i < len(input) && f(input[i]) {
i++
}
return input[i:], input[:i], nil
}
}
func recognize[T any](p parser[T]) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest, _, err = p(input)
if err != nil {
return
}
return rest, input[:len(input)-len(rest)], nil
}
}
func recognize2[T, U any](p1 parser[T], p2 parser[U]) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest, _, err = p1(input)
if err != nil {
return
}
rest, _, err = p2(rest)
if err != nil {
return
}
return rest, input[:len(input)-len(rest)], nil
}
}
func recognize3[T, U, V any](p1 parser[T], p2 parser[U], p3 parser[V]) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest, _, err = p1(input)
if err != nil {
return
}
rest, _, err = p2(rest)
if err != nil {
return
}
rest, _, err = p3(rest)
if err != nil {
return
}
return rest, input[:len(input)-len(rest)], nil
}
}
func recognize4[T, U, V, W any](p1 parser[T], p2 parser[U], p3 parser[V], p4 parser[W]) parser[[]byte] {
return func(input []byte) (rest []byte, value []byte, err error) {
rest, _, err = p1(input)
if err != nil {
return
}
rest, _, err = p2(rest)
if err != nil {
return
}
rest, _, err = p3(rest)
if err != nil {
return
}
rest, _, err = p4(rest)
if err != nil {
return
}
return rest, input[:len(input)-len(rest)], nil