-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclasses.go
135 lines (112 loc) · 3.18 KB
/
classes.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package scan
import "unicode"
// Class returns true if the given rune is a member.
type Class func(rune) bool
// Not returns a Class function that returns true when given a rune that does
// not match class c.
func Not(c Class) Class {
return func(r0 rune) bool {
return !c(r0)
}
}
// Or returns a Class that returns true when given a rune that matches any
// class found in cs.
func Or(cs ...Class) Class {
return func(r0 rune) bool {
for _, c := range cs {
if c(r0) {
return true
}
}
return false
}
}
// Range returns a Class function that returns true when given a rune that is
// between from and to inclusive.
func Range(from rune, to rune) Class {
return func(r0 rune) bool {
return r0 >= from && r0 <= to
}
}
// Rune returns a Class function that returns true when given any rune found
// in rs.
func Rune(rs ...rune) Class {
switch len(rs) {
case 0:
return func(rune) bool { return false }
case 1:
return func(r0 rune) bool { return r0 == rs[0] }
}
return func(r0 rune) bool {
for _, r := range rs {
if r == r0 {
return true
}
}
return false
}
}
var (
// IsAny returns true as long as there is a rune available in the input
// stream.
IsAny Class = func(r rune) bool {
return r != EndOfText
}
// IsCurrency returns true when given a rune that is a currency symbol as
// defined by Unicode.
IsCurrency Class = func(r rune) bool {
return unicode.Is(unicode.Sc, r)
}
// IsDigit returns true when given a digit as defined by Unicode.
IsDigit Class = unicode.IsDigit
// IsDigit01 returns true when given a valid binary digit.
IsDigit01 Class = Rune('0', '1')
// IsDigit07 returns true when given a valid octal digit.
IsDigit07 Class = Range('0', '7')
// IsDigit09 returns true when given a valid decimal digit.
IsDigit09 Class = Range('0', '9')
// IsDigit0F returns true when given a valid hexadecimal digit.
IsDigit0F Class = Or(
IsDigit09,
Range('a', 'f'),
Range('A', 'F'),
)
// IsLetter returns true when given rune is a letter as defined by Unicode.
IsLetter Class = unicode.IsLetter
// IsLetterAZ returns true when given letters from the Latin alphabet.
IsLetterAZ Class = Or(
Range('a', 'z'),
Range('A', 'Z'),
)
// IsLetterUnder returns true when given letters as defined by Unicode
// or an underscore.
IsLetterUnder = Or(
IsLetter,
Rune('_'),
)
// IsLetterDigitUnder returns true when given letters as digits as defined
// by Unicode or an underscore.
IsLetterDigitUnder = Or(
IsLetterUnder,
IsDigit,
)
// IsNone always returns false.
IsNone Class = func(r rune) bool {
return false
}
// IsPrintable returns true when given a rune that is printable as defined
// by Unicode.
IsPrintable Class = unicode.IsPrint
// IsRune8 returns true when given a rune that can be represented by
// an 8-bit number.
IsRune8 Class = Range(0, 0xff)
// IsRune16 returns true when given a rune that can be represented by
// a 16-bit number.
IsRune16 Class = Range(0, 0xffff)
// IsSign returns true when the rune is a positive (+) or negative (-)
// numeric symbol.
IsSign Class = Rune('+', '-')
// IsSpace returns true when the given rune is whitespace as
// defined by Unicode.
IsSpace Class = unicode.IsSpace
)