-
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
package chroma
import (
"fmt"
"strings"
)
// A Mutator modifies the behaviour of the lexer.
type Mutator interface {
// Mutate the lexer state machine as it is processing.
Mutate(state *LexerState) error
}
// A LexerMutator is an additional interface that a Mutator can implement
// to modify the lexer when it is compiled.
type LexerMutator interface {
// Rules are the lexer rules, state is the state key for the rule the mutator is associated with.
MutateLexer(rules CompiledRules, state string, rule int) error
}
// A MutatorFunc is a Mutator that mutates the lexer state machine as it is processing.
type MutatorFunc func(state *LexerState) error
func (m MutatorFunc) Mutate(state *LexerState) error { return m(state) } // nolint
// Mutators applies a set of Mutators in order.
func Mutators(modifiers ...Mutator) MutatorFunc {
return func(state *LexerState) error {
for _, modifier := range modifiers {
if err := modifier.Mutate(state); err != nil {
return err
}
}
return nil
}
}
type includeMutator struct {
state string
}
// Include the given state.
func Include(state string) Rule {
return Rule{Mutator: &includeMutator{state}}
}
func (i *includeMutator) Mutate(s *LexerState) error {
return fmt.Errorf("should never reach here Include(%q)", i.state)
}
func (i *includeMutator) MutateLexer(rules CompiledRules, state string, rule int) error {
includedRules, ok := rules[i.state]
if !ok {
return fmt.Errorf("invalid include state %q", i.state)
}
rules[state] = append(rules[state][:rule], append(includedRules, rules[state][rule+1:]...)...)
return nil
}
type combinedMutator struct {
states []string
}
// Combined creates a new anonymous state from the given states, and pushes that state.
func Combined(states ...string) Mutator {
return &combinedMutator{states}
}
func (c *combinedMutator) Mutate(s *LexerState) error {
return fmt.Errorf("should never reach here Combined(%v)", c.states)
}
func (c *combinedMutator) MutateLexer(rules CompiledRules, state string, rule int) error {
name := "__combined_" + strings.Join(c.states, "__")
if _, ok := rules[name]; !ok {
combined := []*CompiledRule{}
for _, state := range c.states {
rules, ok := rules[state]
if !ok {
return fmt.Errorf("invalid combine state %q", state)
}
combined = append(combined, rules...)
}
rules[name] = combined
}
rules[state][rule].Mutator = Push(name)
return nil
}
// Push states onto the stack.
func Push(states ...string) MutatorFunc {
return func(s *LexerState) error {
if len(states) == 0 {
s.Stack = append(s.Stack, s.State)
} else {
for _, state := range states {
if state == "#pop" {
s.Stack = s.Stack[:len(s.Stack)-1]
} else {
s.Stack = append(s.Stack, state)
}
}
}
return nil
}
}
// Pop state from the stack when rule matches.
func Pop(n int) MutatorFunc {
return func(state *LexerState) error {
if len(state.Stack) == 0 {
return fmt.Errorf("nothing to pop")
}
state.Stack = state.Stack[:len(state.Stack)-n]
return nil
}
}
// Default returns a Rule that applies a set of Mutators.
func Default(mutators ...Mutator) Rule {
return Rule{Mutator: Mutators(mutators...)}
}
// Stringify returns the raw string for a set of tokens.
func Stringify(tokens ...Token) string {
out := []string{}
for _, t := range tokens {
out = append(out, t.Value)
}
return strings.Join(out, "")
}