-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrdx.go
123 lines (110 loc) · 2.68 KB
/
rdx.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
package rdx
import (
"errors"
"github.com/drpcorg/chotki/protocol"
)
const (
None = byte(0)
Float = byte('F')
Integer = byte('I')
Reference = byte('R')
String = byte('S')
Term = byte('T')
Natural = byte('N')
NInc = byte('n')
ZCounter = byte('Z')
ZInc = byte('z')
Eulerian = byte('E')
Linear = byte('L')
Mapping = byte('M')
VVector = byte('V')
)
type RDX struct {
Nested []RDX
Text []byte
Parent *RDX
RdxType byte
}
const RdxMaxNesting = 64
var RdxSep = []byte("{}[],:.")
const (
RdxOOpen = iota
RdxOClose
RdxAOpen
RdxAClose
RdxComma
RdxColon
RdxDot
)
var ErrBadRdx = errors.New("bad RDX syntax")
var ErrBadValueForAType = errors.New("rdx: bad value for the type")
func (rdx *RDX) AddChild(rdxtype byte, text []byte) {
rdx.Nested = append(rdx.Nested, RDX{
RdxType: rdxtype,
Text: text,
})
}
func (rdx *RDX) FIRST() bool {
return rdx != nil && (rdx.RdxType == Float || rdx.RdxType == Integer ||
rdx.RdxType == Reference || rdx.RdxType == String || rdx.RdxType == Term)
}
func (rdx *RDX) String() string {
recs, _ := rdx.Feed()
var by []byte
for _, rec := range recs {
by = append(by, rec...)
}
return string(by)
}
func (rdx *RDX) Feed() (recs protocol.Records, err error) {
switch rdx.RdxType {
case None:
case Float:
recs = append(recs, rdx.Text)
case Integer:
recs = append(recs, rdx.Text)
case Reference:
recs = append(recs, rdx.Text)
case String:
recs = append(recs, rdx.Text)
case Term:
recs = append(recs, rdx.Text)
case Natural, NInc, ZCounter, ZInc:
recs = append(recs, rdx.Text)
case Mapping:
recs = append(recs, RdxSep[RdxOOpen:RdxOOpen+1])
for i := 0; i+1 < len(rdx.Nested); i += 2 {
key, _ := rdx.Nested[i].Feed()
val, _ := rdx.Nested[i+1].Feed()
recs = append(recs, key...)
recs = append(recs, RdxSep[RdxColon:RdxColon+1])
recs = append(recs, val...)
if i+2 < len(rdx.Nested) {
recs = append(recs, RdxSep[RdxComma:RdxComma+1])
}
}
recs = append(recs, RdxSep[RdxOClose:RdxOClose+1])
case Eulerian:
recs = append(recs, RdxSep[RdxOOpen:RdxOOpen+1])
for i := 0; i < len(rdx.Nested); i++ {
val, _ := rdx.Nested[i].Feed()
recs = append(recs, val...)
if i+1 < len(rdx.Nested) {
recs = append(recs, RdxSep[RdxComma:RdxComma+1])
}
}
recs = append(recs, RdxSep[RdxOClose:RdxOClose+1])
case Linear:
recs = append(recs, RdxSep[RdxAOpen:RdxAOpen+1])
for i := 0; i < len(rdx.Nested); i++ {
val, _ := rdx.Nested[i].Feed()
recs = append(recs, val...)
if i+1 < len(rdx.Nested) {
recs = append(recs, RdxSep[RdxComma:RdxComma+1])
}
}
recs = append(recs, RdxSep[RdxAClose:RdxAClose+1])
}
return
}
//go:generate ragel -Z -o rdx.ragel.go rdx.rl