-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.go
75 lines (63 loc) · 1.66 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
package parser
// ------------------------------------------------------------
// TOKEN-T
// tokenT stores a single token type, and associated behaviour.
type tokenT struct {
Symbol symbol
Text string
BindingPower int
nud nudFn
led ledFn
}
// any answers true if my symbol is any of the supplied symbols.
func (t tokenT) any(symbols ...symbol) bool {
for _, s := range symbols {
if t.Symbol == s {
return true
}
}
return false
}
// inside answers true if my symbol is after start and before end.
func (t tokenT) inside(start, end symbol) bool {
return t.Symbol > start && t.Symbol < end
}
// ------------------------------------------------------------
// FUNC
type nudFn func(*nodeT, *parserT) (*nodeT, error)
type ledFn func(*nodeT, *parserT, *nodeT) (*nodeT, error)
// ------------------------------------------------------------
// TOKEN FUNCS
func emptyNud(n *nodeT, p *parserT) (*nodeT, error) {
return n, nil
}
func emptyLed(n *nodeT, p *parserT, left *nodeT) (*nodeT, error) {
return n, nil
}
func binaryLed(n *nodeT, p *parserT, left *nodeT) (*nodeT, error) {
n.addChild(left)
right, err := p.Expression(n.Token.BindingPower)
if err != nil {
return nil, err
}
n.addChild(right)
return n, nil
}
func enclosedNud(n *nodeT, p *parserT) (*nodeT, error) {
enclosed, err := p.Expression(n.Token.BindingPower)
if err != nil {
return nil, err
}
next, err := p.Next()
if err != nil {
return nil, err
}
if next == nil {
return nil, newParseError("missing next for " + n.Text)
}
if next.Token.Symbol != closeToken {
return nil, newParseError("missing close for " + n.Text)
}
n.addChild(enclosed)
return n, nil
}