-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.go
116 lines (98 loc) · 2.59 KB
/
token.go
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package tok
import "fmt"
//------------------------------------------------------------------------------
// Token marks a sub string in a Scanner.
type Token struct {
from Marker
to Marker
}
// Generates a Token from two Marker.
func MakeToken(a, b Marker) Token {
t := Token{a, b}
if t.from > t.to {
t.from, t.to = t.to, t.from
}
return t
}
// After reports whether t is after oth.
func (t Token) After(oth Token) bool {
return t.from >= oth.to
}
// Before reports whether t is before oth.
func (t Token) Before(oth Token) bool {
return t.to <= oth.from
}
func (t Token) Len() int {
return int(t.to - t.from)
}
// Merge creates a Token that convers both Tokens t and oth.
func (t Token) Merge(oth Token) Token {
if t.from > oth.from {
t.from = oth.from
}
if t.to < oth.to {
t.to = oth.to
}
return t
}
// Clash returns true if both tokens overlap, but no one covers the other.
func (t Token) Clashes(oth Token) bool {
return !t.Before(oth) && !t.After(oth) && !t.Covers(oth) && !oth.Covers(t)
}
// Covers returns true if sub is a sub Token of t.
func (t Token) Covers(sub Token) bool {
return t.from <= sub.from && t.to >= sub.to
}
// Split splits a Token into two parts via sep.
func (t Token) Split(sep Token) (Token, Token) {
return MakeToken(t.from, sep.from), MakeToken(sep.to, t.to)
}
// String returns a readable representation of a Token.
func (t Token) String() string {
return fmt.Sprintf("[%d-%d)", t.from, t.to)
}
// Returns the sub string that t represents.
func (s *Scanner) Get(t Token) string {
return s.full[t.from:t.to]
}
//------------------------------------------------------------------------------
// Tokenize marks the sub string that was scanned by f.
func (s *Scanner) Tokenize(f ScopeFunc) (Token, bool) {
a := s.Mark()
res := f()
b := s.Mark()
if !res {
s.ToMarker(a)
}
return MakeToken(a, b), res
}
// TokenizeUse marks the sub string that was read by r.
func (s *Scanner) TokenizeUse(r Reader) (Token, error) {
a := s.Mark()
err := r.Read(s)
if err != nil {
s.ToMarker(a)
}
b := s.Mark()
return MakeToken(a, b), err
}
// Returns a sub string from the text that will be scanned.
func (s *Scanner) Since(m Marker) string {
return s.Get(MakeToken(m, s.Mark()))
}
// Capture returns the sub string that was scanned by f.
func (s *Scanner) Capture(f ScopeFunc) (string, bool) {
t, ok := s.Tokenize(f)
if ok {
return s.Get(t), true
}
return "", false
}
// CaptureUse returns the sub string that was scanned by r.
func (s *Scanner) CaptureUse(r Reader) (string, error) {
t, err := s.TokenizeUse(r)
if err == nil {
return s.Get(t), nil
}
return "", err
}