Move Map and Run onto Parser, and document stuff
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@ import (
|
|||||||
// Token wraps a parser to discard all whitespace after the parsed input.
|
// Token wraps a parser to discard all whitespace after the parsed input.
|
||||||
// whitespace is a parser that will consume non-empty whitespace.
|
// whitespace is a parser that will consume non-empty whitespace.
|
||||||
func Token[Out any](whitespace gigaparsec.Parser[byte, struct{}]) func(p gigaparsec.Parser[byte, Out]) gigaparsec.Parser[byte, Out] {
|
func Token[Out any](whitespace gigaparsec.Parser[byte, struct{}]) func(p gigaparsec.Parser[byte, Out]) gigaparsec.Parser[byte, Out] {
|
||||||
mappedWS := gigaparsec.Map(whitespace, func(struct{}) struct{} { return struct{}{} })
|
mappedWS := whitespace.Map(func(struct{}) struct{} { return struct{}{} })
|
||||||
var ignoreWS gigaparsec.Parser[byte, struct{}] = func(s gigaparsec.State[byte]) (gigaparsec.Result[byte, struct{}], error) {
|
var ignoreWS gigaparsec.Parser[byte, struct{}] = func(s gigaparsec.State[byte]) (gigaparsec.Result[byte, struct{}], error) {
|
||||||
result, err := mappedWS(s)
|
result, err := mappedWS(s)
|
||||||
return result.Consume(false), err
|
return result.Consume(false), err
|
||||||
@@ -25,5 +25,5 @@ func isWhitespaceASCII(b byte) bool {
|
|||||||
|
|
||||||
// WhitespaceASCII consumes one ASCII whitespace character: space, tab, LF, CR, vertical tab, or form feed.
|
// WhitespaceASCII consumes one ASCII whitespace character: space, tab, LF, CR, vertical tab, or form feed.
|
||||||
func WhitespaceASCII() gigaparsec.Parser[byte, struct{}] {
|
func WhitespaceASCII() gigaparsec.Parser[byte, struct{}] {
|
||||||
return gigaparsec.Map(gigaparsec.Satisfy(isWhitespaceASCII), func(byte) struct{} { return struct{}{} })
|
return gigaparsec.Satisfy(isWhitespaceASCII).Map(func(byte) struct{} { return struct{}{} })
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ func ExampleToken() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
tokenize := gigaparsec.Repeat(0, bytes.Token[string](bytes.WhitespaceASCII())(ptokens))
|
tokenize := gigaparsec.Repeat(0, bytes.Token[string](bytes.WhitespaceASCII())(ptokens))
|
||||||
tokens, _ := gigaparsec.Run(tokenize, strings.NewReader("(alpha + 42) -5 "))
|
tokens, _ := tokenize.Run(strings.NewReader("(alpha + 42) -5 "))
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
fmt.Println(token)
|
fmt.Println(token)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-12
@@ -194,6 +194,7 @@ func (p Parser[In, Out]) Label(label string) Parser[In, Out] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Where creates a parser that fails if pred does not hold.
|
||||||
func (p Parser[In, Out]) Where(pred func(Out) bool) Parser[In, Out] {
|
func (p Parser[In, Out]) Where(pred func(Out) bool) Parser[In, Out] {
|
||||||
return func(s State[In]) (Result[In, Out], error) {
|
return func(s State[In]) (Result[In, Out], error) {
|
||||||
result, err := p(s)
|
result, err := p(s)
|
||||||
@@ -205,13 +206,15 @@ func (p Parser[In, Out]) Where(pred func(Out) bool) Parser[In, Out] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ParseError Message
|
// Map creates a parser that converts the output of p from Out1 to Out2.
|
||||||
|
func (p Parser[In, Out]) Map[Out2 any](f func(Out) Out2) Parser[In, Out2] {
|
||||||
func (pe ParseError) Error() string {
|
return Bind(p, func(out Out) Parser[In, Out2] {
|
||||||
return Message(pe).String()
|
return Return[In](f(out))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Run[In, Out any](p Parser[In, Out], r ReaderAt[In]) (out Out, err error) {
|
// Run executes a parser on r and returns the result.
|
||||||
|
func (p Parser[In, Out]) Run(r ReaderAt[In]) (out Out, err error) {
|
||||||
start := MakeState(r)
|
start := MakeState(r)
|
||||||
result, err := p(start)
|
result, err := p(start)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -226,6 +229,12 @@ func Run[In, Out any](p Parser[In, Out], r ReaderAt[In]) (out Out, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ParseError Message
|
||||||
|
|
||||||
|
func (pe ParseError) Error() string {
|
||||||
|
return Message(pe).String()
|
||||||
|
}
|
||||||
|
|
||||||
// Return creates a parser that always succeeds and returns value without consuming any input.
|
// Return creates a parser that always succeeds and returns value without consuming any input.
|
||||||
func Return[In, Out any](value Out) Parser[In, Out] {
|
func Return[In, Out any](value Out) Parser[In, Out] {
|
||||||
return func(state State[In]) (Result[In, Out], error) {
|
return func(state State[In]) (Result[In, Out], error) {
|
||||||
@@ -355,13 +364,6 @@ func Try[In, Out any](p Parser[In, Out]) Parser[In, Out] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map creates a parser that converts the output of p from Out1 to Out2.
|
|
||||||
func Map[In, Out1, Out2 any](p Parser[In, Out1], f func(Out1) Out2) Parser[In, Out2] {
|
|
||||||
return Bind(p, func(out Out1) Parser[In, Out2] {
|
|
||||||
return Return[In](f(out))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func end[In any](s State[In]) (Result[In, struct{}], error) {
|
func end[In any](s State[In]) (Result[In, struct{}], error) {
|
||||||
_, _, err := s.Read([]In{})
|
_, _, err := s.Read([]In{})
|
||||||
if errors.Is(err, io.EOF) {
|
if errors.Is(err, io.EOF) {
|
||||||
@@ -424,6 +426,7 @@ func Lazy[In, Out any](p func() Parser[In, Out]) Parser[In, Out] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bracket parses p, flanked by left and right.
|
||||||
func Bracket[In, Out, LOut, ROut any](left Parser[In, LOut], p Parser[In, Out], right Parser[In, ROut]) Parser[In, Out] {
|
func Bracket[In, Out, LOut, ROut any](left Parser[In, LOut], p Parser[In, Out], right Parser[In, ROut]) Parser[In, Out] {
|
||||||
return Seq3(left, p, right, func(_ LOut, val Out, _ ROut) Out { return val })
|
return Seq3(left, p, right, func(_ LOut, val Out, _ ROut) Out { return val })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module git.codemonkeysoftware.net/b/gigaparsec
|
module git.codemonkeysoftware.net/b/gigaparsec
|
||||||
|
|
||||||
go 1.23
|
go 1.27
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/shoenig/test v1.11.0
|
github.com/shoenig/test v1.11.0
|
||||||
|
|||||||
+8
-8
@@ -22,13 +22,13 @@ func BenchmarkBind5(b *testing.B) {
|
|||||||
input := gigaparsec.SliceReaderAt[byte]{0}
|
input := gigaparsec.SliceReaderAt[byte]{0}
|
||||||
b.Run("gigaparsec.Bind5", func(b *testing.B) {
|
b.Run("gigaparsec.Bind5", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(gigaparsec.Bind5), input)
|
p(gigaparsec.Bind5).Run(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
b.Run("naïve.Bind5", func(b *testing.B) {
|
b.Run("naïve.Bind5", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(naive.Bind5), input)
|
p(naive.Bind5).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -46,13 +46,13 @@ func BenchmarkBind9(b *testing.B) {
|
|||||||
input := gigaparsec.SliceReaderAt[byte]{0}
|
input := gigaparsec.SliceReaderAt[byte]{0}
|
||||||
b.Run("gigaparsec.Bind9", func(b *testing.B) {
|
b.Run("gigaparsec.Bind9", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(gigaparsec.Bind9), input)
|
p(gigaparsec.Bind9).Run(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
b.Run("naive.Bind9", func(b *testing.B) {
|
b.Run("naive.Bind9", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(naive.Bind9), input)
|
p(naive.Bind9).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -72,12 +72,12 @@ func BenchmarkSeq5(b *testing.B) {
|
|||||||
input := gigaparsec.SliceReaderAt[byte]{0}
|
input := gigaparsec.SliceReaderAt[byte]{0}
|
||||||
b.Run("gigaparsec.Seq5", func(b *testing.B) {
|
b.Run("gigaparsec.Seq5", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(gigaparsec.Seq5), input)
|
p(gigaparsec.Seq5).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
b.Run("naive.Seq5", func(b *testing.B) {
|
b.Run("naive.Seq5", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(naive.Seq5), input)
|
p(naive.Seq5).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -97,12 +97,12 @@ func BenchmarkSeq9(b *testing.B) {
|
|||||||
input := gigaparsec.SliceReaderAt[byte]{0}
|
input := gigaparsec.SliceReaderAt[byte]{0}
|
||||||
b.Run("gigaparsec.Seq9", func(b *testing.B) {
|
b.Run("gigaparsec.Seq9", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(gigaparsec.Seq9), input)
|
p(gigaparsec.Seq9).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
b.Run("naive.Seq9", func(b *testing.B) {
|
b.Run("naive.Seq9", func(b *testing.B) {
|
||||||
for range b.N {
|
for range b.N {
|
||||||
gigaparsec.Run(p(naive.Seq9), input)
|
p(naive.Seq9).Run(input)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user