-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsemantics.go
127 lines (116 loc) · 2.56 KB
/
semantics.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// RoutingA:
// https://github.com/v2rayA/RoutingA
// Use of this source code is governed by MIT license that can be found in the LICENSE file.
package RoutingA
import "strings"
func mergeMap(m1 *map[string][]string, m2 map[string][]string) {
for k, v := range m2 {
(*m1)[k] = append((*m1)[k], v...)
}
}
func symMatch(a []symbol, b []rune) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i].sym != b[i] {
return false
}
}
return true
}
func parseN(s symbol) (m map[string][]string) {
if s.sym != 'N' {
return nil
}
m = make(map[string][]string)
if !symMatch(s.children, []rune(",H:HN")) {
return
}
return parseHHN(s.Slice(1, s.Len()))
}
//H:HN
func parseHHN(s symbol) (m map[string][]string) {
if !symMatch(s.children, []rune("H:HN")) {
return
}
m = make(map[string][]string)
m[s.children[0].val] = append(m[s.children[0].val], parseH(s.children[2]))
N := s.children[3]
if len(N.children) > 0 {
mm := parseN(N)
mergeMap(&m, mm)
}
return
}
func parseH(s symbol) string {
if s.sym != 'H' {
return ""
}
switch {
case (strings.HasPrefix(s.val, `'`) && strings.HasSuffix(s.val, `'`)) ||
(strings.HasPrefix(s.val, `"`) && strings.HasSuffix(s.val, `"`)):
return s.val[1 : len(s.val)-1]
default:
return s.val
}
}
func parseM(s symbol) (params []string) {
if s.sym != 'M' {
return
}
if len(s.children) == 0 {
return
}
params = append(params, parseH(s.children[1]))
params = append(params, parseM(s.children[2])...)
return
}
func parseG(s symbol) (params []string, namedParams map[string][]string) {
if s.sym != 'G' {
return
}
params = make([]string, 0)
namedParams = make(map[string][]string)
switch {
case symMatch(s.children, []rune("HMN")):
params = append(params, parseH(s.children[0]))
params = append(params, parseM(s.children[1])...)
namedParams = parseN(s.children[2])
case symMatch(s.children, []rune("H:HN")):
namedParams = parseHHN(s)
}
return
}
func parseQ(s symbol) (and []Function) {
if s.sym != 'Q' {
return
}
and = make([]Function, 0)
if symMatch(s.children, []rune("&&FQ")) {
and = append(and, *newFunction(s.children[2]))
and = append(and, parseQ(s.children[3])...)
}
return
}
func parseR(s symbol) (As symbols) {
if s.sym != 'R' {
return
}
As = make(symbols, 0)
switch {
case symMatch(s.children, []rune("rAR")):
As = append(As, s.children[1])
As = append(As, parseR(s.children[2])...)
}
return
}
func parseS(s symbol) (As symbols) {
if s.sym != 'S' {
return
}
As = make(symbols, 0)
As = append(As, s.children[0])
As = append(As, parseR(s.children[1])...)
return
}