-
Notifications
You must be signed in to change notification settings - Fork 11
/
matcher.go
executable file
·91 lines (81 loc) · 2.08 KB
/
matcher.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
package dsc
import "github.com/viant/toolbox"
type valueMatcher struct {
optionallyEnclosingChar string
terminatorChars string
}
func (m valueMatcher) Match(input string, offset int) (matched int) {
var i = 0
isValueEnclosed := false
if input[offset:offset+1] == m.optionallyEnclosingChar {
isValueEnclosed = true
i++
}
for ; i < len(input)-offset; i++ {
aChar := input[offset+i : offset+i+1]
if isValueEnclosed {
if aChar == m.optionallyEnclosingChar && input[offset+i-1:offset+i] != "\\" {
i++
break
}
} else {
for j := 0; j < len(m.terminatorChars); j++ {
if aChar == m.terminatorChars[j:j+1] {
return i
}
}
}
}
if isValueEnclosed {
if input[offset+i-1:offset+i] == m.optionallyEnclosingChar {
return i
}
return 0
}
return i
}
type valuesMatcher struct {
valuesGroupingBeginChar string
valuesGroupingEndChar string
valueSeparator string
valueOptionallyEnclosedWithChar string
valueTerminatorCharacters string
}
func (m valuesMatcher) Match(input string, offset int) (matched int) {
if input[offset:offset+len(m.valuesGroupingBeginChar)] != m.valuesGroupingBeginChar {
return 0
}
valueMatcher := valueMatcher{optionallyEnclosingChar: m.valueOptionallyEnclosedWithChar, terminatorChars: m.valueTerminatorCharacters}
whitespaceMatcher := toolbox.CharactersMatcher{Chars: " \n\t"}
i := len(m.valuesGroupingBeginChar)
var firstIteration = true
//"a(1, 2, 3)a"
var maxLoopCount = len(input) - (offset + 1)
for ; i < maxLoopCount; firstIteration = false {
aChar := input[offset+i : offset+i+1]
if aChar == m.valueSeparator {
if firstIteration {
return 0
}
i++
continue
}
whitespaceMatched := whitespaceMatcher.Match(input, offset+i)
if whitespaceMatched > 0 {
i += whitespaceMatched
continue
}
valueMatched := valueMatcher.Match(input, offset+i)
if valueMatched == 0 {
if firstIteration {
return 0
}
break
}
i += valueMatched
}
if offset+i < len(input) && input[offset+i:offset+i+1] != m.valuesGroupingEndChar {
return 0
}
return i + 1
}