1
0
mirror of https://github.com/alecthomas/chroma.git synced 2025-01-12 01:22:30 +02:00

Reprocess all rules after a LexerMutator is applied.

This commit is contained in:
Alec Thomas 2017-09-22 23:14:32 +10:00
parent 8170d52c25
commit a5a3b67010
2 changed files with 11 additions and 3 deletions

View File

@ -45,7 +45,7 @@ func Include(state string) Rule {
}
func (i *includeMutator) Mutate(s *LexerState) error {
panic(fmt.Errorf("should never reach here Include(%q)", i.state))
return fmt.Errorf("should never reach here Include(%q)", i.state)
}
func (i *includeMutator) MutateLexer(rules CompiledRules, state string, rule int) error {
@ -67,7 +67,7 @@ func Combined(states ...string) Mutator {
}
func (c *combinedMutator) Mutate(s *LexerState) error {
panic(fmt.Errorf("should never reach here Combined(%v)", c.states))
return fmt.Errorf("should never reach here Combined(%v)", c.states)
}
func (c *combinedMutator) MutateLexer(rules CompiledRules, state string, rule int) error {

View File

@ -272,15 +272,23 @@ func (r *RegexLexer) maybeCompile() (err error) {
}
}
}
restart:
seen := map[LexerMutator]bool{}
for state := range r.rules {
for i := 0; i < len(r.rules[state]); i++ {
rule := r.rules[state][i]
if compile, ok := rule.Mutator.(LexerMutator); ok {
if seen[compile] {
return fmt.Errorf("saw mutator %T twice; this should not happen", compile)
}
seen[compile] = true
if err := compile.MutateLexer(r.rules, state, i); err != nil {
return err
}
// Process the rules again in case the mutator added/removed rules.
i = -1
//
// This sounds bad, but shouldn't be significant in practice.
goto restart
}
}
}