-
Notifications
You must be signed in to change notification settings - Fork 0
/
nodes.go
76 lines (61 loc) · 2.14 KB
/
nodes.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
package regexp
////////////////////////////////////////////////////////////////////////////////
// NFA nodes interfaces
////////////////////////////////////////////////////////////////////////////////
// node is an NFA node used to evaluate a regexp
type node interface {
epsilons() []node
}
// matchNode is a node which might match a rune moving the automaton to next.
type matchNode interface {
node
matches(rune) bool
next() node
}
// nodeBuilder is a parser-exposed interface for building nodes.
type nodeBuilder interface {
node
addEpsilon(node)
}
// matchBuilder is a parser-exposed interface for building matchNodes.
type matchBuilder interface {
matchNode
setNext(node)
}
////////////////////////////////////////////////////////////////////////////////
// base implementations
////////////////////////////////////////////////////////////////////////////////
// nodeBase is the base implementation of nodeBuilder
type nodeBase []node
func (n *nodeBase) epsilons() []node { return []node(*n) }
func (n *nodeBase) addEpsilon(e node) { *n = append(*n, e) }
// matchBase is the base implementation of matchBuilder
type matchBase struct {
nodeBase
n node
}
func (n *matchBase) next() node { return n.n }
func (n *matchBase) setNext(next node) { n.n = next }
////////////////////////////////////////////////////////////////////////////////
// concrete node types
////////////////////////////////////////////////////////////////////////////////
type (
starNode struct{ nodeBase }
qmarkNode struct{ nodeBase }
plusNode struct{ nodeBase }
terminalNode struct{ nodeBase }
leftParenNode struct{ nodeBase }
rightParenNode struct{ nodeBase }
pipeNode struct{ nodeBase }
dotNode struct{ matchBase }
literalNode struct {
matchBase
r rune
}
)
////////////////////////////////////////////////////////////////////////////////
// match node implementations
////////////////////////////////////////////////////////////////////////////////
var _, _ matchBuilder = (*dotNode)(nil), (*literalNode)(nil)
func (n dotNode) matches(_ rune) bool { return true }
func (n literalNode) matches(r rune) bool { return r == n.r }