Check-in [893c36d683]
Overview
Comment:Added a string matching parser.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 893c36d683930cc81427ab01abf66b828947606d
User & Date: spaskalev on 2015-03-19 20:36:20.531
Other Links: manifest | tags
Context
2015-03-19
20:40
Added a test for parse.Defer check-in: b37c997693 user: spaskalev tags: trunk
20:36
Added a string matching parser. check-in: 893c36d683 user: spaskalev tags: trunk
20:17
A simple parser combinator library check-in: 061baeefcb user: spaskalev tags: trunk
Changes
75
76
77
78
79
80
81















75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
	return func(s string) (N, string) {
		if len(s) < count {
			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
	}
}
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16


17
18
19


20
21
22
23
24
25
26
27


28
29
30


31
32
33
34
35
36
37
38


39
40
41


42
43
44


45
46
47
48
49
50
51
52


53




54
55








56
57
1
2
3
4
5
6
7
8
9


10
11
12
13
14


15
16
17


18
19
20
21
22
23
24
25


26
27
28


29
30
31
32
33
34
35
36


37
38
39


40
41
42


43
44
45
46
47
48
49
50


51
52
53
54
55
56
57


58
59
60
61
62
63
64
65
66
67









-
-
+
+



-
-
+
+

-
-
+
+






-
-
+
+

-
-
+
+






-
-
+
+

-
-
+
+

-
-
+
+






-
-
+
+

+
+
+
+
-
-
+
+
+
+
+
+
+
+


package parse

import (
	"testing"
)

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 n, r := s("aa"); !n.Matched || n.Content != "aa" || n.Nodes == nil || r != "" {
		t.Error("Invalid result for Seq positive test", n)
	}
	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 n, r := s("a"); n.Matched || n.Content != "a" || n.Nodes == nil || r != "" {
		t.Error("Invalid result for Seq partial match test", n)
	}
	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(""); 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)
	}
}
	if r, s := a("aa"); !r.Matched || r.Content != "a" || r.Nodes != nil || s != "a" {
		t.Error("Invalid result for Any match test", r)

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 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))
	}
}