glob/compiler/compiler.go

116 lines
2.4 KiB
Go
Raw Normal View History

2016-05-30 19:35:53 +03:00
package compiler
2016-01-08 20:14:31 +03:00
2016-02-23 14:46:32 +03:00
// TODO use constructor with all matchers, and to their structs private
2016-02-25 00:41:52 +03:00
// TODO glue multiple Text nodes (like after QuoteMeta)
2016-02-23 14:46:32 +03:00
2016-01-08 20:14:31 +03:00
import (
"fmt"
2016-12-07 10:55:55 +03:00
2018-10-02 22:52:57 +03:00
"github.com/gobwas/glob/internal/debug"
2016-01-08 20:14:31 +03:00
"github.com/gobwas/glob/match"
2016-05-30 19:35:53 +03:00
"github.com/gobwas/glob/syntax/ast"
2016-01-08 20:14:31 +03:00
)
2018-02-16 17:36:02 +03:00
func Compile(tree *ast.Node, sep []rune) (match.Matcher, error) {
m, err := compile(tree, sep)
if err != nil {
return nil, err
2016-01-08 20:14:31 +03:00
}
2018-02-16 17:36:02 +03:00
return m, nil
2016-01-08 20:14:31 +03:00
}
2018-02-16 17:36:02 +03:00
func compileNodes(ns []*ast.Node, sep []rune) ([]match.Matcher, error) {
var matchers []match.Matcher
for _, n := range ns {
m, err := compile(n, sep)
2016-05-30 19:35:53 +03:00
if err != nil {
return nil, err
2016-01-09 02:34:41 +03:00
}
2018-02-16 17:36:02 +03:00
matchers = append(matchers, m)
2016-01-09 02:34:41 +03:00
}
2018-02-16 17:36:02 +03:00
return matchers, nil
2016-05-30 19:35:53 +03:00
}
2016-01-08 20:14:31 +03:00
2019-02-06 23:43:38 +03:00
func compile(node *ast.Node, sep []rune) (m match.Matcher, err error) {
2018-10-02 22:52:57 +03:00
if debug.Enabled {
2019-02-06 23:43:38 +03:00
debug.EnterPrefix("compiler: compiling %s", node)
2018-10-02 22:52:57 +03:00
defer func() {
2019-02-06 23:43:38 +03:00
if err != nil {
debug.Logf("->! %v", err)
} else {
debug.Logf("-> %s", m)
}
debug.LeavePrefix()
2018-10-02 22:52:57 +03:00
}()
}
2016-01-08 20:14:31 +03:00
2018-02-16 17:36:02 +03:00
// todo this could be faster on pattern_alternatives_combine_lite (see glob_test.go)
2019-02-06 23:43:38 +03:00
if n := ast.Minimize(node); n != nil {
debug.Logf("minimized tree -> %s", node, n)
2018-02-16 17:36:02 +03:00
r, err := compile(n, sep)
2018-10-02 22:52:57 +03:00
if debug.Enabled {
if err != nil {
debug.Logf("compiler: compile minimized tree failed: %v", err)
} else {
debug.Logf("compiler: minimized tree")
2019-02-06 23:43:38 +03:00
debug.Logf("compiler: \t%s", node)
2018-10-02 22:52:57 +03:00
debug.Logf("compiler: \t%s", n)
}
}
2018-02-16 17:36:02 +03:00
if err == nil {
return r, nil
2016-01-08 20:14:31 +03:00
}
}
2019-02-06 23:43:38 +03:00
switch node.Kind {
2016-05-30 19:35:53 +03:00
case ast.KindAnyOf:
2019-02-06 23:43:38 +03:00
matchers, err := compileNodes(node.Children, sep)
2016-05-30 19:35:53 +03:00
if err != nil {
return nil, err
2016-01-08 20:14:31 +03:00
}
return match.NewAnyOf(matchers...), nil
2016-01-15 19:50:12 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindPattern:
2019-02-06 23:43:38 +03:00
if len(node.Children) == 0 {
return match.NewNothing(), nil
2016-01-15 19:50:12 +03:00
}
2019-02-06 23:43:38 +03:00
matchers, err := compileNodes(node.Children, sep)
2016-05-30 19:35:53 +03:00
if err != nil {
return nil, err
2016-01-15 19:50:12 +03:00
}
2018-02-16 17:36:02 +03:00
m, err = match.Compile(match.Minimize(matchers))
2016-01-15 19:50:12 +03:00
if err != nil {
return nil, err
2016-01-08 20:14:31 +03:00
}
2016-05-30 19:35:53 +03:00
case ast.KindAny:
m = match.NewAny(sep)
2016-01-08 20:14:31 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindSuper:
m = match.NewSuper()
2016-01-08 20:14:31 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindSingle:
m = match.NewSingle(sep)
2016-01-08 20:14:31 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindNothing:
m = match.NewNothing()
case ast.KindList:
2019-02-06 23:43:38 +03:00
l := node.Value.(ast.List)
2016-05-30 19:35:53 +03:00
m = match.NewList([]rune(l.Chars), l.Not)
2016-01-08 20:14:31 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindRange:
2019-02-06 23:43:38 +03:00
r := node.Value.(ast.Range)
2016-05-30 19:35:53 +03:00
m = match.NewRange(r.Lo, r.Hi, r.Not)
2016-01-08 20:14:31 +03:00
2016-05-30 19:35:53 +03:00
case ast.KindText:
2019-02-06 23:43:38 +03:00
t := node.Value.(ast.Text)
2016-05-30 19:35:53 +03:00
m = match.NewText(t.Text)
2016-01-08 20:14:31 +03:00
default:
return nil, fmt.Errorf("could not compile tree: unknown node type")
}
2018-02-16 17:36:02 +03:00
return match.Optimize(m), nil
2016-01-08 20:14:31 +03:00
}