wip
This commit is contained in:
79
tagengine/node.go
Normal file
79
tagengine/node.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package tagengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type node struct {
|
||||
Token string
|
||||
Matches []*Rule // If a list of tokens reaches this node, it matches these.
|
||||
Children map[string]*node
|
||||
}
|
||||
|
||||
func (n *node) AddRule(r *Rule) {
|
||||
n.addRule(r, 0)
|
||||
}
|
||||
|
||||
func (n *node) addRule(r *Rule, idx int) {
|
||||
if len(r.Includes) == idx {
|
||||
n.Matches = append(n.Matches, r)
|
||||
return
|
||||
}
|
||||
|
||||
token := r.Includes[idx]
|
||||
|
||||
child, ok := n.Children[token]
|
||||
if !ok {
|
||||
child = &node{
|
||||
Token: token,
|
||||
Children: map[string]*node{},
|
||||
}
|
||||
n.Children[token] = child
|
||||
}
|
||||
|
||||
child.addRule(r, idx+1)
|
||||
}
|
||||
|
||||
// Note that tokens must be sorted. This is the case for tokens created from
|
||||
// the tokenize function.
|
||||
func (n *node) Match(tokens []string) (rules []*Rule) {
|
||||
return n.match(tokens, rules)
|
||||
}
|
||||
|
||||
func (n *node) match(tokens []string, rules []*Rule) []*Rule {
|
||||
// Check for a match.
|
||||
if n.Matches != nil {
|
||||
rules = append(rules, n.Matches...)
|
||||
}
|
||||
|
||||
if len(tokens) == 0 {
|
||||
return rules
|
||||
}
|
||||
|
||||
// Attempt to match children.
|
||||
for i := 0; i < len(tokens); i++ {
|
||||
token := tokens[i]
|
||||
if child, ok := n.Children[token]; ok {
|
||||
rules = child.match(tokens[i+1:], rules)
|
||||
}
|
||||
}
|
||||
|
||||
return rules
|
||||
}
|
||||
|
||||
func (n *node) Dump() {
|
||||
n.dump(0)
|
||||
}
|
||||
|
||||
func (n *node) dump(depth int) {
|
||||
indent := strings.Repeat(" ", 2*depth)
|
||||
tag := ""
|
||||
for _, m := range n.Matches {
|
||||
tag += " " + m.Tag
|
||||
}
|
||||
fmt.Printf("%s%s%s\n", indent, n.Token, tag)
|
||||
for _, child := range n.Children {
|
||||
child.dump(depth + 1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user