forked from mirror/glob
refactoring done
This commit is contained in:
parent
510a1756cf
commit
36eb5476d5
|
@ -350,23 +350,33 @@ func minimizeTreeAnyOf(tree *ast.Node) *ast.Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
|
func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
|
||||||
|
if len(nodes) <= 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// find node that has least number of children
|
// find node that has least number of children
|
||||||
idx := leastChildren(nodes)
|
idx := leastChildren(nodes)
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
return nil, nil
|
return
|
||||||
}
|
}
|
||||||
tree := nodes[idx]
|
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 (
|
var (
|
||||||
breakLeft bool
|
breakLeft bool
|
||||||
breakRight 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]
|
treeLeft := tree.Children[i]
|
||||||
treeRight := tree.Children[j]
|
treeRight := tree.Children[j]
|
||||||
|
|
||||||
fmt.Println(i, j)
|
|
||||||
|
|
||||||
for k := 0; k < len(nodes) && !(breakLeft && breakLeft); k++ {
|
for k := 0; k < len(nodes) && !(breakLeft && breakLeft); k++ {
|
||||||
// skip least children node
|
// skip least children node
|
||||||
if k == idx {
|
if k == idx {
|
||||||
|
@ -374,7 +384,7 @@ func commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
restLeft := nodes[k].Children[i]
|
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)
|
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 || (!breakLeft && j <= i)
|
||||||
breakRight = breakRight || !treeRight.Equal(restRight)
|
breakRight = breakRight || !treeRight.Equal(restRight)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !breakLeft {
|
if !breakLeft {
|
||||||
fmt.Println("left app")
|
commonTotal++
|
||||||
commonLeft = append(commonLeft, treeLeft)
|
commonLeft = append(commonLeft, treeLeft)
|
||||||
}
|
}
|
||||||
if !breakRight {
|
if !breakRight {
|
||||||
fmt.Println("right app")
|
commonTotal++
|
||||||
commonRight = append(commonRight, treeRight)
|
lastRight = j
|
||||||
|
commonRight[j] = treeRight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonRight = commonRight[lastRight:]
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,26 +16,35 @@ func TestCommonChildren(t *testing.T) {
|
||||||
left []*ast.Node
|
left []*ast.Node
|
||||||
right []*ast.Node
|
right []*ast.Node
|
||||||
}{
|
}{
|
||||||
// {
|
{
|
||||||
// nodes: []*ast.Node{
|
nodes: []*ast.Node{
|
||||||
// ast.NewNode(ast.KindNothing, nil,
|
ast.NewNode(ast.KindNothing, nil,
|
||||||
// ast.NewNode(ast.KindText, ast.Text{"a"}),
|
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||||
// ast.NewNode(ast.KindText, ast.Text{"z"}),
|
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||||
// ast.NewNode(ast.KindText, ast.Text{"c"}),
|
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"}),
|
nodes: []*ast.Node{
|
||||||
// ),
|
ast.NewNode(ast.KindNothing, nil,
|
||||||
// },
|
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
||||||
// left: []*ast.Node{
|
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||||
// ast.NewNode(ast.KindText, ast.Text{"a"}),
|
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||||
// },
|
),
|
||||||
// right: []*ast.Node{
|
ast.NewNode(ast.KindNothing, nil,
|
||||||
// ast.NewNode(ast.KindText, ast.Text{"c"}),
|
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{
|
nodes: []*ast.Node{
|
||||||
ast.NewNode(ast.KindNothing, nil,
|
ast.NewNode(ast.KindNothing, nil,
|
||||||
|
@ -55,12 +64,54 @@ func TestCommonChildren(t *testing.T) {
|
||||||
left: []*ast.Node{
|
left: []*ast.Node{
|
||||||
ast.NewNode(ast.KindText, ast.Text{"a"}),
|
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"}),
|
|
||||||
},
|
},
|
||||||
right: []*ast.Node{
|
right: []*ast.Node{
|
||||||
|
ast.NewNode(ast.KindText, ast.Text{"c"}),
|
||||||
ast.NewNode(ast.KindText, ast.Text{"d"}),
|
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)
|
left, right := commonChildren(test.nodes)
|
||||||
if !nodesEqual(left, test.left) {
|
if !nodesEqual(left, test.left) {
|
||||||
|
@ -268,238 +319,238 @@ func TestCompiler(t *testing.T) {
|
||||||
result match.Matcher
|
result match.Matcher
|
||||||
sep []rune
|
sep []rune
|
||||||
}{
|
}{
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewText("abc"),
|
result: match.NewText("abc"),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewAny(separators),
|
result: match.NewAny(separators),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewSuper(),
|
result: match.NewSuper(),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewSuper(),
|
result: match.NewSuper(),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewSingle(separators),
|
result: match.NewSingle(separators),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindRange, &ast.Range{
|
ast.NewNode(ast.KindRange, ast.Range{
|
||||||
// Lo: 'a',
|
Lo: 'a',
|
||||||
// Hi: 'z',
|
Hi: 'z',
|
||||||
// Not: true,
|
Not: true,
|
||||||
// }),
|
}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewRange('a', 'z', true),
|
result: match.NewRange('a', 'z', true),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindList, &ast.List{
|
ast.NewNode(ast.KindList, ast.List{
|
||||||
// Chars: "abc",
|
Chars: "abc",
|
||||||
// Not: true,
|
Not: true,
|
||||||
// }),
|
}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewList([]rune{'a', 'b', 'c'}, true),
|
result: match.NewList([]rune{'a', 'b', 'c'}, true),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.EveryOf{Matchers: match.Matchers{
|
result: match.EveryOf{Matchers: match.Matchers{
|
||||||
// match.NewMin(3),
|
match.NewMin(3),
|
||||||
// match.NewContains(string(separators), true),
|
match.NewContains(string(separators), true),
|
||||||
// }},
|
}},
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewMin(3),
|
result: match.NewMin(3),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewRow(
|
match.NewRow(
|
||||||
// 4,
|
4,
|
||||||
// match.Matchers{
|
match.Matchers{
|
||||||
// match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
// match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
// }...,
|
}...,
|
||||||
// ),
|
),
|
||||||
// match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
// nil,
|
nil,
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"/"}),
|
ast.NewNode(ast.KindText, ast.Text{"/"}),
|
||||||
// ast.NewNode(ast.KindAnyOf, nil,
|
ast.NewNode(ast.KindAnyOf, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"z"}),
|
ast.NewNode(ast.KindText, ast.Text{"z"}),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"ab"}),
|
ast.NewNode(ast.KindText, ast.Text{"ab"}),
|
||||||
// ),
|
),
|
||||||
// ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewText("/"),
|
match.NewText("/"),
|
||||||
// nil,
|
nil,
|
||||||
// match.NewBTree(
|
match.NewBTree(
|
||||||
// match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
|
match.NewAnyOf(match.NewText("z"), match.NewText("ab")),
|
||||||
// nil,
|
nil,
|
||||||
// match.NewSuper(),
|
match.NewSuper(),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewRow(
|
match.NewRow(
|
||||||
// 5,
|
5,
|
||||||
// match.Matchers{
|
match.Matchers{
|
||||||
// match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
// match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
// match.NewSingle(separators),
|
match.NewSingle(separators),
|
||||||
// }...,
|
}...,
|
||||||
// ),
|
),
|
||||||
// match.NewSuper(),
|
match.NewSuper(),
|
||||||
// nil,
|
nil,
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewSuffix("abc"),
|
result: match.NewSuffix("abc"),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewPrefix("abc"),
|
result: match.NewPrefix("abc"),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"def"}),
|
ast.NewNode(ast.KindText, ast.Text{"def"}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewPrefixSuffix("abc", "def"),
|
result: match.NewPrefixSuffix("abc", "def"),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindAny, 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.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewContains("abc", false),
|
result: match.NewContains("abc", false),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindAny, 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.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// sep: separators,
|
sep: separators,
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
// match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
// match.NewAny(separators),
|
match.NewAny(separators),
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindSuper, nil),
|
ast.NewNode(ast.KindSuper, nil),
|
||||||
// ast.NewNode(ast.KindSingle, nil),
|
ast.NewNode(ast.KindSingle, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
// match.NewMin(1),
|
match.NewMin(1),
|
||||||
// match.NewMin(1),
|
match.NewMin(1),
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ),
|
),
|
||||||
// result: match.NewText("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: ast.NewNode(ast.KindPattern, nil,
|
||||||
ast.NewNode(ast.KindAnyOf, nil,
|
ast.NewNode(ast.KindAnyOf, nil,
|
||||||
ast.NewNode(ast.KindPattern, 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.KindSingle, nil),
|
||||||
),
|
),
|
||||||
ast.NewNode(ast.KindPattern, nil,
|
ast.NewNode(ast.KindPattern, nil,
|
||||||
ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
ast.NewNode(ast.KindList, &ast.List{Chars: "def"}),
|
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
|
||||||
),
|
),
|
||||||
ast.NewNode(ast.KindPattern, nil,
|
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.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: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindRange, &ast.Range{Lo: 'a', Hi: 'z'}),
|
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.KindRange, ast.Range{Lo: 'a', Hi: 'x', Not: true}),
|
||||||
// ast.NewNode(ast.KindAny, nil),
|
ast.NewNode(ast.KindAny, nil),
|
||||||
// ),
|
),
|
||||||
// result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
// match.NewRow(
|
match.NewRow(
|
||||||
// 2,
|
2,
|
||||||
// match.Matchers{
|
match.Matchers{
|
||||||
// match.NewRange('a', 'z', false),
|
match.NewRange('a', 'z', false),
|
||||||
// match.NewRange('a', 'x', true),
|
match.NewRange('a', 'x', true),
|
||||||
// }...,
|
}...,
|
||||||
// ),
|
),
|
||||||
// nil,
|
nil,
|
||||||
// match.NewSuper(),
|
match.NewSuper(),
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// ast: ast.NewNode(ast.KindPattern, nil,
|
ast: ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindAnyOf, nil,
|
ast.NewNode(ast.KindAnyOf, nil,
|
||||||
// ast.NewNode(ast.KindPattern, nil,
|
ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindList, &ast.List{Chars: "abc"}),
|
ast.NewNode(ast.KindList, ast.List{Chars: "abc"}),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"ghi"}),
|
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
|
||||||
// ),
|
),
|
||||||
// ast.NewNode(ast.KindPattern, nil,
|
ast.NewNode(ast.KindPattern, nil,
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"abc"}),
|
ast.NewNode(ast.KindText, ast.Text{"abc"}),
|
||||||
// ast.NewNode(ast.KindList, &ast.List{Chars: "def"}),
|
ast.NewNode(ast.KindList, ast.List{Chars: "def"}),
|
||||||
// ast.NewNode(ast.KindText, &ast.Text{"ghi"}),
|
ast.NewNode(ast.KindText, ast.Text{"ghi"}),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// ),
|
),
|
||||||
// result: match.NewRow(
|
result: match.NewRow(
|
||||||
// 7,
|
7,
|
||||||
// match.Matchers{
|
match.Matchers{
|
||||||
// match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
// match.AnyOf{Matchers: match.Matchers{
|
match.AnyOf{Matchers: match.Matchers{
|
||||||
// match.NewList([]rune{'a', 'b', 'c'}, false),
|
match.NewList([]rune{'a', 'b', 'c'}, false),
|
||||||
// match.NewList([]rune{'d', 'e', 'f'}, false),
|
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||||
// }},
|
}},
|
||||||
// match.NewText("ghi"),
|
match.NewText("ghi"),
|
||||||
// }...,
|
}...,
|
||||||
// ),
|
),
|
||||||
// },
|
},
|
||||||
} {
|
} {
|
||||||
m, err := Compile(test.ast, test.sep)
|
m, err := Compile(test.ast, test.sep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
4
glob.go
4
glob.go
|
@ -1,7 +1,7 @@
|
||||||
package glob
|
package glob
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gobwas/glob/parser"
|
"github.com/gobwas/glob/compiler"
|
||||||
"github.com/gobwas/glob/syntax"
|
"github.com/gobwas/glob/syntax"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func Compile(pattern string, separators ...rune) (Glob, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
matcher, err := compile(ast, separators)
|
matcher, err := compiler.Compile(ast, separators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
14
glob_test.go
14
glob_test.go
|
@ -159,12 +159,6 @@ func TestGlob(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQuoteMeta(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 {
|
for id, test := range []struct {
|
||||||
in, out string
|
in, out string
|
||||||
}{
|
}{
|
||||||
|
@ -177,12 +171,12 @@ func TestQuoteMeta(t *testing.T) {
|
||||||
out: `\{foo\*\}`,
|
out: `\{foo\*\}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: string(specials),
|
in: `*?\[]{}`,
|
||||||
out: string(specialsQuoted),
|
out: `\*\?\\\[\]\{\}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
in: string(append([]byte("some text and"), specials...)),
|
in: `some text and *?\[]{}`,
|
||||||
out: string(append([]byte("some text and"), specialsQuoted...)),
|
out: `some text and \*\?\\\[\]\{\}`,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
act := QuoteMeta(test.in)
|
act := QuoteMeta(test.in)
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
package ast
|
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 {
|
type Node struct {
|
||||||
Parent *Node
|
Parent *Node
|
||||||
Children []*Node
|
Children []*Node
|
||||||
|
|
|
@ -43,7 +43,7 @@ func parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) {
|
||||||
return nil, tree, errors.New(token.Raw)
|
return nil, tree, errors.New(token.Raw)
|
||||||
|
|
||||||
case lexer.Text:
|
case lexer.Text:
|
||||||
Insert(tree, NewNode(KindText, &Text{token.Raw}))
|
Insert(tree, NewNode(KindText, Text{token.Raw}))
|
||||||
return parserMain, tree, nil
|
return parserMain, tree, nil
|
||||||
|
|
||||||
case lexer.Any:
|
case lexer.Any:
|
||||||
|
@ -139,13 +139,13 @@ func parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if isRange {
|
if isRange {
|
||||||
Insert(tree, NewNode(KindRange, &Range{
|
Insert(tree, NewNode(KindRange, Range{
|
||||||
Lo: lo,
|
Lo: lo,
|
||||||
Hi: hi,
|
Hi: hi,
|
||||||
Not: not,
|
Not: not,
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
Insert(tree, NewNode(KindList, &List{
|
Insert(tree, NewNode(KindList, List{
|
||||||
Chars: chars,
|
Chars: chars,
|
||||||
Not: not,
|
Not: not,
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gobwas/glob/syntax"
|
"github.com/gobwas/glob/syntax/lexer"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stubLexer struct {
|
type stubLexer struct {
|
||||||
tokens []syntax.Token
|
tokens []lexer.Token
|
||||||
pos int
|
pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stubLexer) Next() (ret syntax.Token) {
|
func (s *stubLexer) Next() (ret lexer.Token) {
|
||||||
if s.pos == len(s.tokens) {
|
if s.pos == len(s.tokens) {
|
||||||
return syntax.Token{syntax.EOF, ""}
|
return lexer.Token{lexer.EOF, ""}
|
||||||
}
|
}
|
||||||
ret = s.tokens[s.pos]
|
ret = s.tokens[s.pos]
|
||||||
s.pos++
|
s.pos++
|
||||||
|
@ -22,129 +22,129 @@ func (s *stubLexer) Next() (ret syntax.Token) {
|
||||||
|
|
||||||
func TestParseString(t *testing.T) {
|
func TestParseString(t *testing.T) {
|
||||||
for id, test := range []struct {
|
for id, test := range []struct {
|
||||||
tokens []syntax.Token
|
tokens []lexer.Token
|
||||||
tree Node
|
tree *Node
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
//pattern: "abc",
|
//pattern: "abc",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.Text, "abc"},
|
lexer.Token{lexer.Text, "abc"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "abc"}),
|
NewNode(KindText, Text{Text: "abc"}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "a*c",
|
//pattern: "a*c",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.Text, "a"},
|
lexer.Token{lexer.Text, "a"},
|
||||||
syntax.Token{syntax.Any, "*"},
|
lexer.Token{lexer.Any, "*"},
|
||||||
syntax.Token{syntax.Text, "c"},
|
lexer.Token{lexer.Text, "c"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "a"}),
|
NewNode(KindText, Text{Text: "a"}),
|
||||||
NewNode(KindAny, nil),
|
NewNode(KindAny, nil),
|
||||||
NewNode(KindText, &Text{Text: "c"}),
|
NewNode(KindText, Text{Text: "c"}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "a**c",
|
//pattern: "a**c",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.Text, "a"},
|
lexer.Token{lexer.Text, "a"},
|
||||||
syntax.Token{syntax.Super, "**"},
|
lexer.Token{lexer.Super, "**"},
|
||||||
syntax.Token{syntax.Text, "c"},
|
lexer.Token{lexer.Text, "c"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "a"}),
|
NewNode(KindText, Text{Text: "a"}),
|
||||||
NewNode(KindSuper, nil),
|
NewNode(KindSuper, nil),
|
||||||
NewNode(KindText, &Text{Text: "c"}),
|
NewNode(KindText, Text{Text: "c"}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "a?c",
|
//pattern: "a?c",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.Text, "a"},
|
lexer.Token{lexer.Text, "a"},
|
||||||
syntax.Token{syntax.Single, "?"},
|
lexer.Token{lexer.Single, "?"},
|
||||||
syntax.Token{syntax.Text, "c"},
|
lexer.Token{lexer.Text, "c"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "a"}),
|
NewNode(KindText, Text{Text: "a"}),
|
||||||
NewNode(KindSingle, nil),
|
NewNode(KindSingle, nil),
|
||||||
NewNode(KindText, &Text{Text: "c"}),
|
NewNode(KindText, Text{Text: "c"}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "[!a-z]",
|
//pattern: "[!a-z]",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.RangeOpen, "["},
|
lexer.Token{lexer.RangeOpen, "["},
|
||||||
syntax.Token{syntax.Not, "!"},
|
lexer.Token{lexer.Not, "!"},
|
||||||
syntax.Token{syntax.RangeLo, "a"},
|
lexer.Token{lexer.RangeLo, "a"},
|
||||||
syntax.Token{syntax.RangeBetween, "-"},
|
lexer.Token{lexer.RangeBetween, "-"},
|
||||||
syntax.Token{syntax.RangeHi, "z"},
|
lexer.Token{lexer.RangeHi, "z"},
|
||||||
syntax.Token{syntax.RangeClose, "]"},
|
lexer.Token{lexer.RangeClose, "]"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindRange, &Range{Lo: 'a', Hi: 'z', Not: true}),
|
NewNode(KindRange, Range{Lo: 'a', Hi: 'z', Not: true}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "[az]",
|
//pattern: "[az]",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.RangeOpen, "["},
|
lexer.Token{lexer.RangeOpen, "["},
|
||||||
syntax.Token{syntax.Text, "az"},
|
lexer.Token{lexer.Text, "az"},
|
||||||
syntax.Token{syntax.RangeClose, "]"},
|
lexer.Token{lexer.RangeClose, "]"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindList, &List{Chars: "az"}),
|
NewNode(KindList, List{Chars: "az"}),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "{a,z}",
|
//pattern: "{a,z}",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.TermsOpen, "{"},
|
lexer.Token{lexer.TermsOpen, "{"},
|
||||||
syntax.Token{syntax.Text, "a"},
|
lexer.Token{lexer.Text, "a"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.Text, "z"},
|
lexer.Token{lexer.Text, "z"},
|
||||||
syntax.Token{syntax.TermsClose, "}"},
|
lexer.Token{lexer.TermsClose, "}"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindAnyOf, nil,
|
NewNode(KindAnyOf, nil,
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "a"}),
|
NewNode(KindText, Text{Text: "a"}),
|
||||||
),
|
),
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "z"}),
|
NewNode(KindText, Text{Text: "z"}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "/{z,ab}*",
|
//pattern: "/{z,ab}*",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.Text, "/"},
|
lexer.Token{lexer.Text, "/"},
|
||||||
syntax.Token{syntax.TermsOpen, "{"},
|
lexer.Token{lexer.TermsOpen, "{"},
|
||||||
syntax.Token{syntax.Text, "z"},
|
lexer.Token{lexer.Text, "z"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.Text, "ab"},
|
lexer.Token{lexer.Text, "ab"},
|
||||||
syntax.Token{syntax.TermsClose, "}"},
|
lexer.Token{lexer.TermsClose, "}"},
|
||||||
syntax.Token{syntax.Any, "*"},
|
lexer.Token{lexer.Any, "*"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "/"}),
|
NewNode(KindText, Text{Text: "/"}),
|
||||||
NewNode(KindAnyOf, nil,
|
NewNode(KindAnyOf, nil,
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "z"}),
|
NewNode(KindText, Text{Text: "z"}),
|
||||||
),
|
),
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "ab"}),
|
NewNode(KindText, Text{Text: "ab"}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
NewNode(KindAny, nil),
|
NewNode(KindAny, nil),
|
||||||
|
@ -152,43 +152,43 @@ func TestParseString(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
//pattern: "{a,{x,y},?,[a-z],[!qwe]}",
|
//pattern: "{a,{x,y},?,[a-z],[!qwe]}",
|
||||||
tokens: []syntax.Token{
|
tokens: []lexer.Token{
|
||||||
syntax.Token{syntax.TermsOpen, "{"},
|
lexer.Token{lexer.TermsOpen, "{"},
|
||||||
syntax.Token{syntax.Text, "a"},
|
lexer.Token{lexer.Text, "a"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.TermsOpen, "{"},
|
lexer.Token{lexer.TermsOpen, "{"},
|
||||||
syntax.Token{syntax.Text, "x"},
|
lexer.Token{lexer.Text, "x"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.Text, "y"},
|
lexer.Token{lexer.Text, "y"},
|
||||||
syntax.Token{syntax.TermsClose, "}"},
|
lexer.Token{lexer.TermsClose, "}"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.Single, "?"},
|
lexer.Token{lexer.Single, "?"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.RangeOpen, "["},
|
lexer.Token{lexer.RangeOpen, "["},
|
||||||
syntax.Token{syntax.RangeLo, "a"},
|
lexer.Token{lexer.RangeLo, "a"},
|
||||||
syntax.Token{syntax.RangeBetween, "-"},
|
lexer.Token{lexer.RangeBetween, "-"},
|
||||||
syntax.Token{syntax.RangeHi, "z"},
|
lexer.Token{lexer.RangeHi, "z"},
|
||||||
syntax.Token{syntax.RangeClose, "]"},
|
lexer.Token{lexer.RangeClose, "]"},
|
||||||
syntax.Token{syntax.Separator, ","},
|
lexer.Token{lexer.Separator, ","},
|
||||||
syntax.Token{syntax.RangeOpen, "["},
|
lexer.Token{lexer.RangeOpen, "["},
|
||||||
syntax.Token{syntax.Not, "!"},
|
lexer.Token{lexer.Not, "!"},
|
||||||
syntax.Token{syntax.Text, "qwe"},
|
lexer.Token{lexer.Text, "qwe"},
|
||||||
syntax.Token{syntax.RangeClose, "]"},
|
lexer.Token{lexer.RangeClose, "]"},
|
||||||
syntax.Token{syntax.TermsClose, "}"},
|
lexer.Token{lexer.TermsClose, "}"},
|
||||||
syntax.Token{syntax.EOF, ""},
|
lexer.Token{lexer.EOF, ""},
|
||||||
},
|
},
|
||||||
tree: NewNode(KindPattern, nil,
|
tree: NewNode(KindPattern, nil,
|
||||||
NewNode(KindAnyOf, nil,
|
NewNode(KindAnyOf, nil,
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "a"}),
|
NewNode(KindText, Text{Text: "a"}),
|
||||||
),
|
),
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindAnyOf, nil,
|
NewNode(KindAnyOf, nil,
|
||||||
NewNode(KindPattern, nil,
|
NewNode(KindPattern, nil,
|
||||||
NewNode(KindText, &Text{Text: "x"}),
|
NewNode(KindText, Text{Text: "x"}),
|
||||||
),
|
),
|
||||||
NewNode(KindPattern, nil,
|
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(KindSingle, nil),
|
||||||
),
|
),
|
||||||
NewNode(KindPattern, 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(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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue