Index: src/0dev.org/parse/parse.go ================================================================== --- src/0dev.org/parse/parse.go +++ src/0dev.org/parse/parse.go @@ -77,5 +77,20 @@ return N{Matched: false, Content: "", Nodes: nil}, s } return N{Matched: true, Content: s[:count], Nodes: nil}, s[count:] } } + +// Returns a parser that accepts the specified string +func String(value string) P { + accept := Accept(len(value)) + return func(s string) (N, string) { + n, r := accept(s) + if !n.Matched { + return n, s + } + if n.Content == value { + return n, r + } + return N{Matched: false, Content: "", Nodes: []N{n}}, s + } +} Index: src/0dev.org/parse/parse_test.go ================================================================== --- src/0dev.org/parse/parse_test.go +++ src/0dev.org/parse/parse_test.go @@ -5,53 +5,63 @@ ) func TestAccept(t *testing.T) { // Accept(0) will always match :) p0 := Accept(0) - if r, s := p0(""); !r.Matched || r.Content != "" || r.Nodes != nil || s != "" { - t.Error("Invalid result for Accept's negative test", r) + if n, r := p0(""); !n.Matched || n.Content != "" || n.Nodes != nil || r != "" { + t.Error("Invalid result for Accept's negative test", n) } // Test with a non-zero amount of bytes p := Accept(1) - if r, s := p(""); r.Matched || r.Content != "" || r.Nodes != nil || s != "" { - t.Error("Invalid result for Accept's negative test", r) + if n, r := p(""); n.Matched || n.Content != "" || n.Nodes != nil || r != "" { + t.Error("Invalid result for Accept's negative test", n) } - if r, s := p("a"); !r.Matched || r.Content != "a" || r.Nodes != nil || s != "" { - t.Error("Invalid result for Accept's positive test", r) + if n, r := p("a"); !n.Matched || n.Content != "a" || n.Nodes != nil || r != "" { + t.Error("Invalid result for Accept's positive test", n) } } func TestK(t *testing.T) { p := Accept(1) k := K(p) - if r, s := k("aaa"); !r.Matched || r.Content != "aaa" || r.Nodes == nil || s != "" { - t.Error("Invalid result for K* match test", r) + if n, r := k("aaa"); !n.Matched || n.Content != "aaa" || n.Nodes == nil || r != "" { + t.Error("Invalid result for K* match test", n) } - if r, s := k(""); !r.Matched || r.Content != "" || r.Nodes != nil || s != "" { - t.Error("Invalid result for K* no-match test", r) + if n, r := k(""); !n.Matched || n.Content != "" || n.Nodes != nil || r != "" { + t.Error("Invalid result for K* no-match test", n) } } func TestSeq(t *testing.T) { p1, p2 := Accept(1), Accept(1) s := Seq(p1, p2) - if r, s := s("aa"); !r.Matched || r.Content != "aa" || r.Nodes == nil || s != "" { - t.Error("Invalid result for Seq positive test", r) - } - if r, s := s("a"); r.Matched || r.Content != "a" || r.Nodes == nil || s != "" { - t.Error("Invalid result for Seq partial match test", r) - } - if r, s := s(""); r.Matched || r.Content != "" || r.Nodes == nil || s != "" { - t.Error("Invalid result for Seq no-match test", r) + if n, r := s("aa"); !n.Matched || n.Content != "aa" || n.Nodes == nil || r != "" { + t.Error("Invalid result for Seq positive test", n) + } + if n, r := s("a"); n.Matched || n.Content != "a" || n.Nodes == nil || r != "" { + t.Error("Invalid result for Seq partial match test", n) + } + if n, r := s(""); n.Matched || n.Content != "" || n.Nodes == nil || r != "" { + t.Error("Invalid result for Seq no-match test", n) } } func TestAny(t *testing.T) { p, p0 := Accept(1), Accept(0) a := Any(p, p0) - if r, s := a(""); !r.Matched || r.Content != "" || r.Nodes != nil || s != "" { - t.Error("Invalid result for Any match test", r) + if n, r := a(""); !n.Matched || n.Content != "" || n.Nodes != nil || r != "" { + t.Error("Invalid result for Any match test", n) + } + if n, r := a("aa"); !n.Matched || n.Content != "a" || n.Nodes != nil || r != "a" { + t.Error("Invalid result for Any match test", n) + } +} + +func TestString(t *testing.T) { + s := String("aa") + if n, r := s("aa"); !n.Matched || n.Content != "aa" || n.Nodes != nil || r != "" { + t.Error("Invalid result for String match test", n) } - if r, s := a("aa"); !r.Matched || r.Content != "a" || r.Nodes != nil || s != "a" { - t.Error("Invalid result for Any match test", r) + if n, r := s("ab"); n.Matched || n.Content != "" || n.Nodes == nil || r != "ab" { + t.Error("Invalid result for String no-match test", n, r, len(r)) } }