refactoring done

This commit is contained in:
gobwas 2016-05-31 11:28:02 +03:00
parent 510a1756cf
commit 36eb5476d5
7 changed files with 468 additions and 460 deletions

View File

@ -350,23 +350,33 @@ func minimizeTreeAnyOf(tree *ast.Node) *ast.Node {
}
func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
if len(nodes) <= 1 {
return
}
// find node that has least number of children
idx := leastChildren(nodes)
if idx == -1 {
return nil, nil
return
}
tree := nodes[idx]
treeLength := len(tree.Children)
// allocate max able size for rightCommon slice
// to get ability insert elements in reverse order (from end to start)
// without sorting
commonRight = make([]*ast.Node, treeLength)
lastRight := treeLength // will use this to get results as commonRight[lastRight:]
var (
breakLeft bool
breakRight bool
breakLeft bool
breakRight bool
commonTotal int
)
for i, j := 0, len(tree.Children)-1; j >= 0 && !(breakLeft && breakLeft); i, j = i+1, j-1 {
for i, j := 0, treeLength-1; commonTotal < treeLength && j >= 0 && !(breakLeft && breakLeft); i, j = i+1, j-1 {
treeLeft := tree.Children[i]
treeRight := tree.Children[j]
fmt.Println(i, j)
for k := 0; k < len(nodes) && !(breakLeft && breakLeft); k++ {
// skip least children node
if k == idx {
@ -374,7 +384,7 @@ func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
}
restLeft := nodes[k].Children[i]
restRight := nodes[k].Children[j+len(nodes[k].Children)-len(tree.Children)]
restRight := nodes[k].Children[j+len(nodes[k].Children)-treeLength]
breakLeft = breakLeft || !treeLeft.Equal(restLeft)
@ -382,15 +392,20 @@ func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
breakRight = breakRight || (!breakLeft && j <= i)
breakRight = breakRight || !treeRight.Equal(restRight)
}
if !breakLeft {
fmt.Println("left app")
commonTotal++
commonLeft = append(commonLeft, treeLeft)
}
if !breakRight {
fmt.Println("right app")
commonRight = append(commonRight, treeRight)
commonTotal++
lastRight = j
commonRight[j] = treeRight
}
}
commonRight = commonRight[lastRight:]
return
}

View File

@ -16,26 +16,35 @@ func TestCommonChildren(t *testing.T) {
left []*ast.Node
right []*ast.Node
}{
// {
// nodes: []*ast.Node{
// ast.NewNode(ast.KindNothing, nil,
// ast.NewNode(ast.KindText, ast.Text{"a"}),
// ast.NewNode(ast.KindText, ast.Text{"z"}),
// ast.NewNode(ast.KindText, ast.Text{"c"}),
// ),
// ast.NewNode(ast.KindNothing, nil,
// ast.NewNode(ast.KindText, ast.Text{"a"}),
// ast.NewNode(ast.KindText, ast.Text{"b"}),
// ast.NewNode(ast.KindText, ast.Text{"c"}),
// ),
// },
// left: []*ast.Node{
// ast.NewNode(ast.KindText, ast.Text{"a"}),
// },
// right: []*ast.Node{
// ast.NewNode(ast.KindText, ast.Text{"c"}),
// },
// },
{
nodes: []*ast.Node{
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"z"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
),
},
},
{
nodes: []*ast.Node{
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"z"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
),
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
),
},
left: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"a"}),
},
right: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"c"}),
},
},
{
nodes: []*ast.Node{
ast.NewNode(ast.KindNothing, nil,
@ -55,12 +64,54 @@ func TestCommonChildren(t *testing.T) {
left: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
},
right: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"c"}),
ast.NewNode(ast.KindText, ast.Text{"d"}),
},
},
{
nodes: []*ast.Node{
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
),
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
ast.NewNode(ast.KindText, ast.Text{"c"}),
),
},
left: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"b"}),
},
right: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"c"}),
},
},
{
nodes: []*ast.Node{
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"d"}),
),
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"d"}),
),
ast.NewNode(ast.KindNothing, nil,
ast.NewNode(ast.KindText, ast.Text{"a"}),
ast.NewNode(ast.KindText, ast.Text{"e"}),
),
},
left: []*ast.Node{
ast.NewNode(ast.KindText, ast.Text{"a"}),
},
right: []*ast.Node{},
},
} {
left, right := commonChildren(test.nodes)
if !nodesEqual(left, test.left) {
@ -268,238 +319,238 @@ func TestCompiler(t *testing.T) {
result match.Matcher
sep []rune
}{
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ),
// result: match.NewText("abc"),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ),
// sep: separators,
// result: match.NewAny(separators),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ),
// result: match.NewSuper(),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindSuper, nil),
// ),
// result: match.NewSuper(),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindSingle, nil),
// ),
// sep: separators,
// result: match.NewSingle(separators),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindRange, &ast.Range{
// Lo: 'a',
// Hi: 'z',
// Not: true,
// }),
// ),
// result: match.NewRange('a', 'z', true),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindList, &ast.List{
// Chars: "abc",
// Not: true,
// }),
// ),
// result: match.NewList([]rune{'a', 'b', 'c'}, true),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindSingle, nil),
// ),
// sep: separators,
// result: match.EveryOf{Matchers: match.Matchers{
// match.NewMin(3),
// match.NewContains(string(separators), true),
// }},
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindSingle, nil),
// ),
// result: match.NewMin(3),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindSingle, nil),
// ),
// sep: separators,
// result: match.NewBTree(
// match.NewRow(
// 4,
// match.Matchers{
// match.NewText("abc"),
// match.NewSingle(separators),
// }...,
// ),
// match.NewAny(separators),
// nil,
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"/"}),
// ast.NewNode(ast.KindAnyOf, nil,
// ast.NewNode(ast.KindText, &ast.Text{"z"}),
// ast.NewNode(ast.KindText, &ast.Text{"ab"}),
// ),
// ast.NewNode(ast.KindSuper, nil),
// ),
// sep: separators,
// result: match.NewBTree(
// match.NewText("/"),
// nil,
// match.NewBTree(
// match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
// nil,
// match.NewSuper(),
// ),
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindSuper, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindSingle, nil),
// ),
// sep: separators,
// result: match.NewBTree(
// match.NewRow(
// 5,
// match.Matchers{
// match.NewSingle(separators),
// match.NewText("abc"),
// match.NewSingle(separators),
// }...,
// ),
// match.NewSuper(),
// nil,
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ),
// result: match.NewSuffix("abc"),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindAny, nil),
// ),
// result: match.NewPrefix("abc"),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindText, &ast.Text{"def"}),
// ),
// result: match.NewPrefixSuffix("abc", "def"),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ),
// result: match.NewContains("abc", false),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindAny, nil),
// ast.NewNode(ast.KindAny, nil),
// ),
// sep: separators,
// result: match.NewBTree(
// match.NewText("abc"),
// match.NewAny(separators),
// match.NewAny(separators),
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindSuper, nil),
// ast.NewNode(ast.KindSingle, nil),
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindSuper, nil),
// ast.NewNode(ast.KindSingle, nil),
// ),
// result: match.NewBTree(
// match.NewText("abc"),
// match.NewMin(1),
// match.NewMin(1),
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ),
// result: match.NewText("abc"),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAnyOf, nil,
// ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAnyOf, nil,
// ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ),
// ),
// ),
// ),
// ),
// result: match.NewText("abc"),
// },
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
result: match.NewText("abc"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
),
sep: separators,
result: match.NewAny(separators),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
),
result: match.NewSuper(),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindSuper, nil),
),
result: match.NewSuper(),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindSingle, nil),
),
sep: separators,
result: match.NewSingle(separators),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindRange, ast.Range{
Lo: 'a',
Hi: 'z',
Not: true,
}),
),
result: match.NewRange('a', 'z', true),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindList, ast.List{
Chars: "abc",
Not: true,
}),
),
result: match.NewList([]rune{'a', 'b', 'c'}, true),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindSingle, nil),
),
sep: separators,
result: match.EveryOf{Matchers: match.Matchers{
match.NewMin(3),
match.NewContains(string(separators), true),
}},
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindSingle, nil),
),
result: match.NewMin(3),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindSingle, nil),
),
sep: separators,
result: match.NewBTree(
match.NewRow(
4,
match.Matchers{
match.NewText("abc"),
match.NewSingle(separators),
}...,
),
match.NewAny(separators),
nil,
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"/"}),
ast.NewNode(ast.KindAnyOf, nil,
ast.NewNode(ast.KindText, ast.Text{"z"}),
ast.NewNode(ast.KindText, ast.Text{"ab"}),
),
ast.NewNode(ast.KindSuper, nil),
),
sep: separators,
result: match.NewBTree(
match.NewText("/"),
nil,
match.NewBTree(
match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
nil,
match.NewSuper(),
),
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindSuper, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindSingle, nil),
),
sep: separators,
result: match.NewBTree(
match.NewRow(
5,
match.Matchers{
match.NewSingle(separators),
match.NewText("abc"),
match.NewSingle(separators),
}...,
),
match.NewSuper(),
nil,
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
result: match.NewSuffix("abc"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindAny, nil),
),
result: match.NewPrefix("abc"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindText, ast.Text{"def"}),
),
result: match.NewPrefixSuffix("abc", "def"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
),
result: match.NewContains("abc", false),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindAny, nil),
ast.NewNode(ast.KindAny, nil),
),
sep: separators,
result: match.NewBTree(
match.NewText("abc"),
match.NewAny(separators),
match.NewAny(separators),
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindSuper, nil),
ast.NewNode(ast.KindSingle, nil),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindSuper, nil),
ast.NewNode(ast.KindSingle, nil),
),
result: match.NewBTree(
match.NewText("abc"),
match.NewMin(1),
match.NewMin(1),
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
result: match.NewText("abc"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAnyOf, nil,
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, &ast.Text{"abc"}),
ast.NewNode(ast.KindAnyOf, nil,
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
),
),
),
),
result: match.NewText("abc"),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAnyOf, nil,
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindSingle, nil),
),
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, &ast.Text{"abc"}),
ast.NewNode(ast.KindList, &ast.List{Chars: "def"}),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
),
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, &ast.Text{"abc"}),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, &ast.Text{"abc"}),
ast.NewNode(ast.KindText, ast.Text{"abc"}),
),
),
),
@ -513,51 +564,51 @@ func TestCompiler(t *testing.T) {
}},
),
},
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindRange, &ast.Range{Lo: 'a', Hi: 'z'}),
// ast.NewNode(ast.KindRange, &ast.Range{Lo: 'a', Hi: 'x', Not: true}),
// ast.NewNode(ast.KindAny, nil),
// ),
// result: match.NewBTree(
// match.NewRow(
// 2,
// match.Matchers{
// match.NewRange('a', 'z', false),
// match.NewRange('a', 'x', true),
// }...,
// ),
// nil,
// match.NewSuper(),
// ),
// },
// {
// ast: ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindAnyOf, nil,
// ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindList, &ast.List{Chars: "abc"}),
// ast.NewNode(ast.KindText, &ast.Text{"ghi"}),
// ),
// ast.NewNode(ast.KindPattern, nil,
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
// ast.NewNode(ast.KindList, &ast.List{Chars: "def"}),
// ast.NewNode(ast.KindText, &ast.Text{"ghi"}),
// ),
// ),
// ),
// result: match.NewRow(
// 7,
// match.Matchers{
// match.NewText("abc"),
// match.AnyOf{Matchers: match.Matchers{
// match.NewList([]rune{'a', 'b', 'c'}, false),
// match.NewList([]rune{'d', 'e', 'f'}, false),
// }},
// match.NewText("ghi"),
// }...,
// ),
// },
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'z'}),
ast.NewNode(ast.KindRange, ast.Range{Lo: 'a', Hi: 'x', Not: true}),
ast.NewNode(ast.KindAny, nil),
),
result: match.NewBTree(
match.NewRow(
2,
match.Matchers{
match.NewRange('a', 'z', false),
match.NewRange('a', 'x', true),
}...,
),
nil,
match.NewSuper(),
),
},
{
ast: ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindAnyOf, nil,
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindList, ast.List{Chars: "abc"}),
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
),
ast.NewNode(ast.KindPattern, nil,
ast.NewNode(ast.KindText, ast.Text{"abc"}),
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
),
),
),
result: match.NewRow(
7,
match.Matchers{
match.NewText("abc"),
match.AnyOf{Matchers: match.Matchers{
match.NewList([]rune{'a', 'b', 'c'}, false),
match.NewList([]rune{'d', 'e', 'f'}, false),
}},
match.NewText("ghi"),
}...,
),
},
} {
m, err := Compile(test.ast, test.sep)
if err != nil {

View File

@ -1,7 +1,7 @@
package glob
import (
"github.com/gobwas/glob/parser"
"github.com/gobwas/glob/compiler"
"github.com/gobwas/glob/syntax"
)
@ -42,7 +42,7 @@ func Compile(pattern string, separators ...rune) (Glob, error) {
return nil, err
}
matcher, err := compile(ast, separators)
matcher, err := compiler.Compile(ast, separators)
if err != nil {
return nil, err
}

View File

@ -159,12 +159,6 @@ func TestGlob(t *testing.T) {
}
func TestQuoteMeta(t *testing.T) {
specialsQuoted := make([]byte, len(specials)*2)
for i, j := 0, 0; i < len(specials); i, j = i+1, j+2 {
specialsQuoted[j] = '\\'
specialsQuoted[j+1] = specials[i]
}
for id, test := range []struct {
in, out string
}{
@ -177,12 +171,12 @@ func TestQuoteMeta(t *testing.T) {
out: `\{foo\*\}`,
},
{
in: string(specials),
out: string(specialsQuoted),
in: `*?\[]{}`,
out: `\*\?\\\[\]\{\}`,
},
{
in: string(append([]byte("some text and"), specials...)),
out: string(append([]byte("some text and"), specialsQuoted...)),
in: `some text and *?\[]{}`,
out: `some text and \*\?\\\[\]\{\}`,
},
} {
act := QuoteMeta(test.in)

View File

@ -1,18 +1,5 @@
package ast
type Visitor interface {
Visit(*Node) Visitor
}
func Walk(v Visitor, n *Node) {
if v = v.Visit(n); v == nil {
return
}
for _, c := range n.Children {
Walk(v, c)
}
}
type Node struct {
Parent *Node
Children []*Node

View File

@ -43,7 +43,7 @@ func parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) {
return nil, tree, errors.New(token.Raw)
case lexer.Text:
Insert(tree, NewNode(KindText, &Text{token.Raw}))
Insert(tree, NewNode(KindText, Text{token.Raw}))
return parserMain, tree, nil
case lexer.Any:
@ -139,13 +139,13 @@ func parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) {
}
if isRange {
Insert(tree, NewNode(KindRange, &Range{
Insert(tree, NewNode(KindRange, Range{
Lo: lo,
Hi: hi,
Not: not,
}))
} else {
Insert(tree, NewNode(KindList, &List{
Insert(tree, NewNode(KindList, List{
Chars: chars,
Not: not,
}))

View File

@ -1,19 +1,19 @@
package ast
import (
"github.com/gobwas/glob/syntax"
"github.com/gobwas/glob/syntax/lexer"
"reflect"
"testing"
)
type stubLexer struct {
tokens []syntax.Token
tokens []lexer.Token
pos int
}
func (s *stubLexer) Next() (ret syntax.Token) {
func (s *stubLexer) Next() (ret lexer.Token) {
if s.pos == len(s.tokens) {
return syntax.Token{syntax.EOF, ""}
return lexer.Token{lexer.EOF, ""}
}
ret = s.tokens[s.pos]
s.pos++
@ -22,129 +22,129 @@ func (s *stubLexer) Next() (ret syntax.Token) {
func TestParseString(t *testing.T) {
for id, test := range []struct {
tokens []syntax.Token
tree Node
tokens []lexer.Token
tree *Node
}{
{
//pattern: "abc",
tokens: []syntax.Token{
syntax.Token{syntax.Text, "abc"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.Text, "abc"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "abc"}),
NewNode(KindText, Text{Text: "abc"}),
),
},
{
//pattern: "a*c",
tokens: []syntax.Token{
syntax.Token{syntax.Text, "a"},
syntax.Token{syntax.Any, "*"},
syntax.Token{syntax.Text, "c"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.Text, "a"},
lexer.Token{lexer.Any, "*"},
lexer.Token{lexer.Text, "c"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "a"}),
NewNode(KindText, Text{Text: "a"}),
NewNode(KindAny, nil),
NewNode(KindText, &Text{Text: "c"}),
NewNode(KindText, Text{Text: "c"}),
),
},
{
//pattern: "a**c",
tokens: []syntax.Token{
syntax.Token{syntax.Text, "a"},
syntax.Token{syntax.Super, "**"},
syntax.Token{syntax.Text, "c"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.Text, "a"},
lexer.Token{lexer.Super, "**"},
lexer.Token{lexer.Text, "c"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "a"}),
NewNode(KindText, Text{Text: "a"}),
NewNode(KindSuper, nil),
NewNode(KindText, &Text{Text: "c"}),
NewNode(KindText, Text{Text: "c"}),
),
},
{
//pattern: "a?c",
tokens: []syntax.Token{
syntax.Token{syntax.Text, "a"},
syntax.Token{syntax.Single, "?"},
syntax.Token{syntax.Text, "c"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.Text, "a"},
lexer.Token{lexer.Single, "?"},
lexer.Token{lexer.Text, "c"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "a"}),
NewNode(KindText, Text{Text: "a"}),
NewNode(KindSingle, nil),
NewNode(KindText, &Text{Text: "c"}),
NewNode(KindText, Text{Text: "c"}),
),
},
{
//pattern: "[!a-z]",
tokens: []syntax.Token{
syntax.Token{syntax.RangeOpen, "["},
syntax.Token{syntax.Not, "!"},
syntax.Token{syntax.RangeLo, "a"},
syntax.Token{syntax.RangeBetween, "-"},
syntax.Token{syntax.RangeHi, "z"},
syntax.Token{syntax.RangeClose, "]"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.RangeOpen, "["},
lexer.Token{lexer.Not, "!"},
lexer.Token{lexer.RangeLo, "a"},
lexer.Token{lexer.RangeBetween, "-"},
lexer.Token{lexer.RangeHi, "z"},
lexer.Token{lexer.RangeClose, "]"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindRange, &Range{Lo: 'a', Hi: 'z', Not: true}),
NewNode(KindRange, Range{Lo: 'a', Hi: 'z', Not: true}),
),
},
{
//pattern: "[az]",
tokens: []syntax.Token{
syntax.Token{syntax.RangeOpen, "["},
syntax.Token{syntax.Text, "az"},
syntax.Token{syntax.RangeClose, "]"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.RangeOpen, "["},
lexer.Token{lexer.Text, "az"},
lexer.Token{lexer.RangeClose, "]"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindList, &List{Chars: "az"}),
NewNode(KindList, List{Chars: "az"}),
),
},
{
//pattern: "{a,z}",
tokens: []syntax.Token{
syntax.Token{syntax.TermsOpen, "{"},
syntax.Token{syntax.Text, "a"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.Text, "z"},
syntax.Token{syntax.TermsClose, "}"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.TermsOpen, "{"},
lexer.Token{lexer.Text, "a"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.Text, "z"},
lexer.Token{lexer.TermsClose, "}"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindAnyOf, nil,
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "a"}),
NewNode(KindText, Text{Text: "a"}),
),
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "z"}),
NewNode(KindText, Text{Text: "z"}),
),
),
),
},
{
//pattern: "/{z,ab}*",
tokens: []syntax.Token{
syntax.Token{syntax.Text, "/"},
syntax.Token{syntax.TermsOpen, "{"},
syntax.Token{syntax.Text, "z"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.Text, "ab"},
syntax.Token{syntax.TermsClose, "}"},
syntax.Token{syntax.Any, "*"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.Text, "/"},
lexer.Token{lexer.TermsOpen, "{"},
lexer.Token{lexer.Text, "z"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.Text, "ab"},
lexer.Token{lexer.TermsClose, "}"},
lexer.Token{lexer.Any, "*"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "/"}),
NewNode(KindText, Text{Text: "/"}),
NewNode(KindAnyOf, nil,
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "z"}),
NewNode(KindText, Text{Text: "z"}),
),
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "ab"}),
NewNode(KindText, Text{Text: "ab"}),
),
),
NewNode(KindAny, nil),
@ -152,43 +152,43 @@ func TestParseString(t *testing.T) {
},
{
//pattern: "{a,{x,y},?,[a-z],[!qwe]}",
tokens: []syntax.Token{
syntax.Token{syntax.TermsOpen, "{"},
syntax.Token{syntax.Text, "a"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.TermsOpen, "{"},
syntax.Token{syntax.Text, "x"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.Text, "y"},
syntax.Token{syntax.TermsClose, "}"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.Single, "?"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.RangeOpen, "["},
syntax.Token{syntax.RangeLo, "a"},
syntax.Token{syntax.RangeBetween, "-"},
syntax.Token{syntax.RangeHi, "z"},
syntax.Token{syntax.RangeClose, "]"},
syntax.Token{syntax.Separator, ","},
syntax.Token{syntax.RangeOpen, "["},
syntax.Token{syntax.Not, "!"},
syntax.Token{syntax.Text, "qwe"},
syntax.Token{syntax.RangeClose, "]"},
syntax.Token{syntax.TermsClose, "}"},
syntax.Token{syntax.EOF, ""},
tokens: []lexer.Token{
lexer.Token{lexer.TermsOpen, "{"},
lexer.Token{lexer.Text, "a"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.TermsOpen, "{"},
lexer.Token{lexer.Text, "x"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.Text, "y"},
lexer.Token{lexer.TermsClose, "}"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.Single, "?"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.RangeOpen, "["},
lexer.Token{lexer.RangeLo, "a"},
lexer.Token{lexer.RangeBetween, "-"},
lexer.Token{lexer.RangeHi, "z"},
lexer.Token{lexer.RangeClose, "]"},
lexer.Token{lexer.Separator, ","},
lexer.Token{lexer.RangeOpen, "["},
lexer.Token{lexer.Not, "!"},
lexer.Token{lexer.Text, "qwe"},
lexer.Token{lexer.RangeClose, "]"},
lexer.Token{lexer.TermsClose, "}"},
lexer.Token{lexer.EOF, ""},
},
tree: NewNode(KindPattern, nil,
NewNode(KindAnyOf, nil,
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "a"}),
NewNode(KindText, Text{Text: "a"}),
),
NewNode(KindPattern, nil,
NewNode(KindAnyOf, nil,
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "x"}),
NewNode(KindText, Text{Text: "x"}),
),
NewNode(KindPattern, nil,
NewNode(KindText, &Text{Text: "y"}),
NewNode(KindText, Text{Text: "y"}),
),
),
),
@ -196,10 +196,10 @@ func TestParseString(t *testing.T) {
NewNode(KindSingle, nil),
),
NewNode(KindPattern, nil,
NewNode(KindRange, &Range{Lo: 'a', Hi: 'z', Not: false}),
NewNode(KindRange, Range{Lo: 'a', Hi: 'z', Not: false}),
),
NewNode(KindPattern, nil,
NewNode(KindList, &List{Chars: "qwe", Not: true}),
NewNode(KindList, List{Chars: "qwe", Not: true}),
),
),
),
@ -215,42 +215,3 @@ func TestParseString(t *testing.T) {
}
}
}
type kv struct {
kind Kind
value interface{}
}
type visitor struct {
visited []kv
}
func (v *visitor) Visit(n Node) Visitor {
v.visited = append(v.visited, kv{n.Kind(), n.Value()})
return v
}
func TestWalkTree(t *testing.T) {
for i, test := range []struct {
tree *Node
visited []kv
}{
{
tree: NewNode(KindPattern, nil,
NewNode(KindSingle, nil),
),
visited: []kv{
kv{KindPattern, nil},
kv{KindSingle, nil},
},
},
} {
v := &visitor{}
Walk(v, test.tree)
if !reflect.DeepEqual(test.visited, v.visited) {
t.Errorf("[%d] unexpected result of Walk():\nvisited:\t%v\nwant:\t\t%v", i, v.visited, test.visited)
}
}
}