-
Notifications
You must be signed in to change notification settings - Fork 1
/
mapper.go
105 lines (96 loc) · 1.96 KB
/
mapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package gomtch
import "unicode"
type Mapper interface {
Map() Tokens
Items() map[string][]int
AddIndex(v string, index int) Mapping
}
type Mapping map[string][]int
func NewMappingFromTokens(tokens []string) Mapping {
m := Mapping{}
var cntr int
var cntrRef int
for _, t := range tokens {
cntrRef = cntr
startSpecial := getStartSpecial([]rune(t))
if startSpecial != nil {
for _, s := range startSpecial {
m = m.AddIndex(string(s), cntr)
cntr++
}
t = t[len(startSpecial):]
cntrRef = cntr
}
endSpecial := getEndSpecial([]rune(t))
if endSpecial != nil {
cntrRef = cntr
for _, s := range endSpecial {
cntr++
m = m.AddIndex(string(s), cntr)
}
t = t[:len(t)-len(endSpecial)]
}
m = m.AddIndex(t, cntrRef)
cntr++
}
return m
}
func (m Mapping) Map() Tokens {
tokens := Tokens{
Values: map[int][]rune{},
}
reference := map[string]int{}
var next int
Outer:
for {
for word, indexes := range m.Items() {
for _, index := range indexes {
if index == next {
if id, ok := reference[word]; ok {
tokens.Ids = append(tokens.Ids, id)
next++
continue Outer
}
reference[word] = next
tokens.Values[next] = []rune(word)
tokens.Ids = append(tokens.Ids, next)
next++
continue Outer
}
}
}
break
}
return tokens
}
func (m Mapping) Items() map[string][]int {
return m
}
func (m Mapping) AddIndex(v string, index int) Mapping {
if _, ok := m[v]; ok {
m[v] = append(m[v], index)
} else {
m[v] = []int{index}
}
return m
}
func getStartSpecial(token []rune) []rune {
var special []rune
for _, r := range token {
if unicode.IsLetter(r) || unicode.IsNumber(r) {
return special
}
special = append(special, r)
}
return nil
}
func getEndSpecial(token []rune) []rune {
var special []rune
for i := len(token) - 1; i >= 0; i-- {
if unicode.IsLetter(token[i]) || unicode.IsNumber(token[i]) {
return special
}
special = append(special, token[i])
}
return nil
}