FINALLY looks like something thats is fast and simple
This commit is contained in:
parent
108e795378
commit
e87fb8209f
2
Makefile
2
Makefile
|
@ -34,7 +34,7 @@ examples:
|
|||
gomake -C _examples
|
||||
|
||||
# yes, hardcoded path, yes ugly, yes, deal with it
|
||||
zparse.go: zparse.rl
|
||||
zparse.go: zparse.rl types.rl
|
||||
/home/miekg/svn/ragel/ragel/ragel -Z -G2 -o $@ $<
|
||||
|
||||
kparse.go: kparse.rl
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
%%{
|
||||
|
||||
machine z;
|
||||
|
||||
action setA {
|
||||
rdf := fields(data[mark:p], 1)
|
||||
rr := new(RR_A)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeA
|
||||
rr.A = net.ParseIP(rdf[0])
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
action setAAAA {
|
||||
rdf := fields(data[mark:p], 1)
|
||||
rr := new(RR_AAAA)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeAAAA
|
||||
rr.AAAA = net.ParseIP(rdf[0])
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
action setNS {
|
||||
rdf := fields(data[mark:p], 1)
|
||||
rr := new(RR_NS)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeNS
|
||||
rr.Ns = rdf[0]
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
action setMX {
|
||||
rdf := fields(data[mark:p], 2)
|
||||
rr := new(RR_MX)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeMX
|
||||
rr.Pref = uint16(atoi(rdf[0]))
|
||||
rr.Mx = rdf[1]
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
|
||||
action setCNAME {
|
||||
rdf := fields(data[mark:p], 1)
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeCNAME
|
||||
rr.Cname = rdf[0]
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
action setSOA {
|
||||
println("SOA")
|
||||
rdf := fields(data[mark:p], 7)
|
||||
rr := new(RR_SOA)
|
||||
rr.Hdr = *hdr
|
||||
rr.Hdr.Rrtype = TypeSOA
|
||||
rr.Ns = rdf[0]
|
||||
rr.Mbox = rdf[1]
|
||||
rr.Serial = uint32(atoi(rdf[2]))
|
||||
rr.Refresh = uint32(atoi(rdf[3]))
|
||||
rr.Retry = uint32(atoi(rdf[4]))
|
||||
rr.Expire = uint32(atoi(rdf[5]))
|
||||
rr.Minttl = uint32(atoi(rdf[6]))
|
||||
z.Push(rr)
|
||||
}
|
||||
|
||||
}%%
|
3
zone.go
3
zone.go
|
@ -15,7 +15,6 @@ type Zone struct {
|
|||
}
|
||||
|
||||
func (z *Zone) Push(r RR) {
|
||||
println("Pushing", r.String())
|
||||
z.v.Push(r)
|
||||
}
|
||||
|
||||
|
@ -33,7 +32,7 @@ func (z *Zone) Len() int {
|
|||
|
||||
func (z *Zone) String() (s string) {
|
||||
for i:=0; i < z.Len(); i++ {
|
||||
s += z.At(i).String()
|
||||
s += z.At(i).String() + "\n"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
202
zparse.rl
202
zparse.rl
|
@ -8,110 +8,33 @@ import (
|
|||
"os"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const _RDATAMAX = 7
|
||||
const _IOBUF = 65365
|
||||
|
||||
// Save up tokens, after we've seen the entire rdata
|
||||
// we can use this.
|
||||
type token struct {
|
||||
T []string // text
|
||||
N []int // number
|
||||
ti int // text counter
|
||||
ni int // number counter
|
||||
// Return the rdata fields as a slice. All starting whitespace deleted
|
||||
func fields(s string, i int) (rdf []string) {
|
||||
rdf = strings.Split(strings.TrimSpace(s), " ", i)
|
||||
for i, _ := range rdf {
|
||||
rdf[i] = strings.TrimSpace(rdf[i])
|
||||
}
|
||||
if len(rdf) != i {
|
||||
panic("not enough rdata seen")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func newToken() *token {
|
||||
to := new(token)
|
||||
to.T = make([]string, _RDATAMAX)
|
||||
to.N = make([]int, _RDATAMAX)
|
||||
to.ni, to.ti = 0, 0
|
||||
return to
|
||||
}
|
||||
|
||||
// Only push functions are provided. Reading is done, by directly
|
||||
// accessing the members (T and N). See types.rl.
|
||||
func (to *token) pushInt(s string) {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
panic("Failure to parse to int: " + s)
|
||||
}
|
||||
to.N[to.ni] = i
|
||||
to.ni++
|
||||
if to.ni > _RDATAMAX {
|
||||
panic("Too much rdata (int)")
|
||||
}
|
||||
}
|
||||
|
||||
func (to *token) pushString(s string) {
|
||||
to.T[to.ti] = s
|
||||
to.ti++
|
||||
if to.ti > _RDATAMAX {
|
||||
panic("Too much rdata (string)")
|
||||
}
|
||||
}
|
||||
|
||||
func (to *token) reset() {
|
||||
to.ni, to.ti = 0, 0
|
||||
}
|
||||
|
||||
func rdata_aaaa(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_AAAA)
|
||||
rr.Hdr = hdr
|
||||
rr.Hdr.Rrtype = TypeAAAA
|
||||
rr.AAAA = net.ParseIP(tok.T[0])
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_a(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_A)
|
||||
rr.Hdr = hdr
|
||||
rr.Hdr.Rrtype = TypeA
|
||||
rr.A = net.ParseIP(tok.T[0])
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_ns(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_NS)
|
||||
rr.Hdr = hdr
|
||||
rr.Hdr.Rrtype = TypeNS
|
||||
rr.Ns = tok.T[0]
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_cname(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = hdr
|
||||
rr.Hdr.Rrtype = TypeCNAME
|
||||
rr.Cname = tok.T[0]
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_soa(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_SOA)
|
||||
rr.Hdr = hdr
|
||||
rr.Hdr.Rrtype = TypeSOA
|
||||
rr.Ns = tok.T[0]
|
||||
rr.Mbox = tok.T[1]
|
||||
rr.Serial = uint32(tok.N[0])
|
||||
rr.Refresh = uint32(tok.N[1])
|
||||
rr.Retry = uint32(tok.N[2])
|
||||
rr.Expire = uint32(tok.N[3])
|
||||
rr.Minttl = uint32(tok.N[4])
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_mx(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_MX)
|
||||
rr.Hdr = hdr;
|
||||
rr.Hdr.Rrtype = TypeMX
|
||||
rr.Pref = uint16(tok.N[0])
|
||||
rr.Mx = tok.T[0]
|
||||
return rr
|
||||
func atoi(s string) int {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
panic("not a number")
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
/*
|
||||
func rdata_ds(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_DS)
|
||||
rr.Hdr = hdr;
|
||||
|
@ -122,7 +45,6 @@ func rdata_ds(hdr RR_Header, tok *token) RR {
|
|||
rr.Digest = tok.T[0]
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_dnskey(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_DNSKEY)
|
||||
rr.Hdr = hdr;
|
||||
|
@ -133,7 +55,6 @@ func rdata_dnskey(hdr RR_Header, tok *token) RR {
|
|||
rr.PublicKey = tok.T[0]
|
||||
return rr
|
||||
}
|
||||
|
||||
func rdata_rrsig(hdr RR_Header, tok *token) RR {
|
||||
rr := new(RR_RRSIG)
|
||||
rr.Hdr = hdr;
|
||||
|
@ -149,12 +70,7 @@ func rdata_rrsig(hdr RR_Header, tok *token) RR {
|
|||
rr.Signature = tok.T[1]
|
||||
return rr
|
||||
}
|
||||
|
||||
func set(r RR, z *Zone, tok *token) {
|
||||
println("setting",r.String())
|
||||
z.Push(r)
|
||||
tok.reset()
|
||||
}
|
||||
*/
|
||||
|
||||
%%{
|
||||
machine z;
|
||||
|
@ -176,73 +92,59 @@ func Zparse(q io.Reader) (z *Zone, err os.Error) {
|
|||
|
||||
data := string(buf)
|
||||
cs, p, pe := 0, 0, len(data)
|
||||
ts, te, act := 0, 0, 0
|
||||
// top := 0
|
||||
// stack := make([]int, 100)
|
||||
eof := len(data)
|
||||
// keep Go happy - need to fix this ofcourse
|
||||
ts = ts; te = te; act = act
|
||||
|
||||
brace := false
|
||||
// brace := false
|
||||
lines := 0
|
||||
mark := 0
|
||||
hdr := new(RR_Header)
|
||||
tok := newToken()
|
||||
|
||||
%%{
|
||||
action mark { mark = p }
|
||||
action qname { hdr.Name = data[mark:p] }
|
||||
action qclass { hdr.Class = Str_class[data[mark:p]] }
|
||||
action setQname { hdr.Name = data[mark:p] }
|
||||
action setQclass { hdr.Class = Str_class[data[mark:p]] }
|
||||
action defTtl { /* ... */ }
|
||||
action setTtl { ttl, _ := strconv.Atoi(data[mark:p]); hdr.Ttl = uint32(ttl) }
|
||||
action number { tok.pushInt(data[mark:p]) }
|
||||
action text { tok.pushString(data[mark:p]) }
|
||||
action openBrace { if brace { println("Brace already open")} ; brace = true }
|
||||
action closeBrace { if !brace { println("Brace already closed")}; brace = false }
|
||||
action brace { brace }
|
||||
action linecount { lines++ }
|
||||
action lineCount { lines++ }
|
||||
|
||||
# Newlines
|
||||
nl = [\n]+ $linecount;
|
||||
# action openBrace { if brace { println("Brace already open")} ; brace = true }
|
||||
# action closeBrace { if !brace { println("Brace already closed")}; brace = false }
|
||||
# action brace { brace }
|
||||
|
||||
# Comments, entire line. Shorter comments are handled in the
|
||||
# 'bl' definition below. TODO
|
||||
include "types.rl";
|
||||
|
||||
nl = [\n]+ $lineCount;
|
||||
comment = ';' [^\n]*;
|
||||
ttl = digit+;
|
||||
# bl = ( [ \t]+
|
||||
# | '(' $openBrace
|
||||
# | ')' $closeBrace
|
||||
# | (comment? nl)+ when brace
|
||||
# )+ %mark;
|
||||
bl = [ \t]+;
|
||||
|
||||
bl = (
|
||||
[ \t]+
|
||||
| '(' $openBrace
|
||||
| ')' $closeBrace
|
||||
| (comment? nl)+ when brace
|
||||
)+ %mark;
|
||||
# rdata = [a-zA-Z0-9.]+ >mark;
|
||||
rdata = [^\n]+ >mark;
|
||||
qname = [a-zA-Z0-9.\-_]+ >mark %setQname;
|
||||
qclass = ('IN'i|'CH'i|'HS'i) >mark %setQclass;
|
||||
|
||||
# chars = [^; \t"\n\\)(];
|
||||
ws = [ \t]+;
|
||||
qclass = ('IN'i|'CS'i|'CH'i|'HS'i|'ANY'i|'NONE'i) %qclass;
|
||||
qname = [a-zA-Z0-9_\-.\+=/]+ %qname;
|
||||
t = [a-zA-Z0-9_\-.:\+=/]+ $1 %0 >mark %text;
|
||||
# now if I use this, I get an assertion failure in Ragel ... :-)
|
||||
tb = [a-zA-Z0-9_\-.: ]+ $1 %0 %text;
|
||||
n = [0-9]+ $1 %0 %number;
|
||||
ttl = digit+ >mark;
|
||||
|
||||
# Not even sure this works okay
|
||||
lhs = qname? bl %defTtl (
|
||||
(ttl %setTtl bl (qclass bl)?)
|
||||
| (qclass bl (ttl %setTtl bl)?)
|
||||
)?;
|
||||
|
||||
main := |*
|
||||
lhs 'A'i bl t nl => { r := rdata_a(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'NS'i bl t nl => { r := rdata_ns(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'CNAME'i bl t nl => { r := rdata_cname(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'AAAA'i bl t nl => { r := rdata_aaaa(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'MX'i bl n bl t nl => { r := rdata_mx(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'SOA'i bl t bl t bl n bl n bl n bl n bl n nl => { r := rdata_soa(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'DS'i bl n bl n bl n bl t nl => { r := rdata_ds(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'DNSKEY'i bl n bl n bl n bl t nl => { r := rdata_dnskey(*hdr, tok); set(r, z, tok); };
|
||||
lhs 'RRSIG'i bl n bl n bl n bl n bl n bl n bl n bl t bl t nl => { r := rdata_rrsig(*hdr, tok); set(r, z, tok); };
|
||||
*|;
|
||||
rhs = (
|
||||
( 'A'i rdata ) %setA
|
||||
| ( 'AAAA'i rdata ) %setAAAA
|
||||
| ( 'SOA'i rdata ) %setSOA
|
||||
| ( 'CNAME'i rdata ) %setCNAME
|
||||
| ( 'NS'i rdata ) %setNS
|
||||
| ( 'MX'i rdata ) %setMX
|
||||
);
|
||||
|
||||
rr = lhs rhs;
|
||||
# main := (rr? bl? ((comment? nl) when !brace))*;
|
||||
main := (rr? nl)*;
|
||||
|
||||
write init;
|
||||
write exec;
|
||||
|
|
Loading…
Reference in New Issue