partially working code
This commit is contained in:
parent
c153bcfa22
commit
fa0d78db9e
171
zscan.go
171
zscan.go
|
@ -5,11 +5,10 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/scanner"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Only used when debugging the parser itself.
|
// Only used when debugging the parser itself.
|
||||||
var _DEBUG = false
|
var _DEBUG = true
|
||||||
|
|
||||||
// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
|
// Tokinize a RFC 1035 zone file. The tokenizer will normalize it:
|
||||||
// * Add ownernames if they are left blank;
|
// * Add ownernames if they are left blank;
|
||||||
|
@ -84,9 +83,9 @@ type Token struct {
|
||||||
func NewRR(s string) (RR, error) {
|
func NewRR(s string) (RR, error) {
|
||||||
t := make(chan Token)
|
t := make(chan Token)
|
||||||
if s[len(s)-1] != '\n' { // We need a closing newline
|
if s[len(s)-1] != '\n' { // We need a closing newline
|
||||||
t = ParseZone(strings.NewReader(s+"\n"))
|
t = ParseZone(strings.NewReader(s + "\n"))
|
||||||
} else {
|
} else {
|
||||||
t= ParseZone(strings.NewReader(s))
|
t = ParseZone(strings.NewReader(s))
|
||||||
}
|
}
|
||||||
r := <-t
|
r := <-t
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
|
@ -97,21 +96,17 @@ func NewRR(s string) (RR, error) {
|
||||||
|
|
||||||
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error
|
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error
|
||||||
// on the returned channel. The channel t is closed by ParseZone when the end of r is reached.
|
// on the returned channel. The channel t is closed by ParseZone when the end of r is reached.
|
||||||
func ParseZone(r io.Reader) (chan Token) {
|
func ParseZone(r io.Reader) chan Token {
|
||||||
t := make(chan Token)
|
t := make(chan Token)
|
||||||
go parseZone(r, t)
|
go parseZone(r, t)
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseZone(r io.Reader, t chan Token) {
|
func parseZone(r io.Reader, t chan Token) {
|
||||||
defer close(t)
|
defer close(t)
|
||||||
var s scanner.Scanner
|
|
||||||
c := make(chan lex)
|
c := make(chan lex)
|
||||||
s.Init(r)
|
|
||||||
s.Mode = 0
|
|
||||||
s.Whitespace = 0
|
|
||||||
// Start the lexer
|
// Start the lexer
|
||||||
go zlexer(s, c)
|
go zlexer(r, c)
|
||||||
// 5 possible beginnings of a line, _ is a space
|
// 5 possible beginnings of a line, _ is a space
|
||||||
// 1. _OWNER _ _RRTYPE -> class/ttl omitted
|
// 1. _OWNER _ _RRTYPE -> class/ttl omitted
|
||||||
// 2. _OWNER _ _STRING _ _RRTYPE -> class omitted
|
// 2. _OWNER _ _STRING _ _RRTYPE -> class omitted
|
||||||
|
@ -291,9 +286,9 @@ func (l lex) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// zlexer scans the sourcefile and returns tokens on the channel c.
|
// zlexer scans the sourcefile and returns tokens on the channel c.
|
||||||
func zlexer(s scanner.Scanner, c chan lex) {
|
func zlexer(r io.Reader, c chan lex) {
|
||||||
var l lex
|
var l lex
|
||||||
str := "" // Hold the current read text
|
defer close(c)
|
||||||
quote := false
|
quote := false
|
||||||
escape := false
|
escape := false
|
||||||
space := false
|
space := false
|
||||||
|
@ -301,35 +296,39 @@ func zlexer(s scanner.Scanner, c chan lex) {
|
||||||
rrtype := false
|
rrtype := false
|
||||||
owner := true
|
owner := true
|
||||||
brace := 0
|
brace := 0
|
||||||
tok := s.Scan()
|
p, q := 0, 0
|
||||||
defer close(c)
|
buf := make([]byte, 4096)
|
||||||
for tok != scanner.EOF {
|
n, err := r.Read(buf)
|
||||||
l.column = s.Position.Column
|
for err != io.EOF {
|
||||||
l.line = s.Position.Line
|
l.column = 0
|
||||||
switch x := s.TokenText(); x {
|
l.line = 0
|
||||||
case " ", "\t":
|
switch buf[q] {
|
||||||
escape = false
|
case ' ', '\t':
|
||||||
|
escape = false
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if str == "" {
|
if p == q {
|
||||||
//l.value = _BLANK
|
//l.value = _BLANK
|
||||||
//l.token = " "
|
//l.token = " "
|
||||||
} else if owner {
|
} else if owner {
|
||||||
// If we have a string and its the first, make it an owner
|
// If we have a string and its the first, make it an owner
|
||||||
l.value = _OWNER
|
l.value = _OWNER
|
||||||
l.token = str
|
println(p, q)
|
||||||
// escape $... start with a \ not a $, so this will work
|
l.token = string(buf[p:q])
|
||||||
if str == "$TTL" {
|
// escape $... start with a \ not a $, so this will work
|
||||||
|
if l.token == "$TTL" {
|
||||||
l.value = _DIRTTL
|
l.value = _DIRTTL
|
||||||
}
|
}
|
||||||
if str == "$ORIGIN" {
|
if l.token == "$ORIGIN" {
|
||||||
l.value = _DIRORIGIN
|
l.value = _DIRORIGIN
|
||||||
}
|
}
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
} else {
|
} else {
|
||||||
l.value = _STRING
|
l.value = _STRING
|
||||||
l.token = str
|
l.token = string(buf[p:q])
|
||||||
|
|
||||||
if !rrtype {
|
if !rrtype {
|
||||||
if _, ok := Str_rr[strings.ToUpper(l.token)]; ok {
|
if _, ok := Str_rr[strings.ToUpper(l.token)]; ok {
|
||||||
|
@ -341,47 +340,52 @@ func zlexer(s scanner.Scanner, c chan lex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
}
|
}
|
||||||
str = ""
|
|
||||||
if !space && !commt {
|
if !space && !commt {
|
||||||
l.value = _BLANK
|
l.value = _BLANK
|
||||||
l.token = " "
|
l.token = " "
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
|
}
|
||||||
|
if space || commt {
|
||||||
|
p++
|
||||||
}
|
}
|
||||||
owner = false
|
owner = false
|
||||||
space = true
|
space = true
|
||||||
case ";":
|
println("upping", p, q)
|
||||||
if escape {
|
case ';':
|
||||||
escape = false
|
if escape {
|
||||||
str += ";"
|
escape = false
|
||||||
break
|
|
||||||
}
|
|
||||||
if quote {
|
|
||||||
// Inside quoted text we allow ;
|
|
||||||
str += ";"
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if quote {
|
||||||
|
// Inside quoted text we allow ;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p++
|
||||||
commt = true
|
commt = true
|
||||||
case "\n":
|
case '\n':
|
||||||
// Hmmm, escape newline
|
// Hmmm, escape newline
|
||||||
escape = false
|
escape = false
|
||||||
if commt {
|
if commt {
|
||||||
// Reset a comment
|
// Reset a comment
|
||||||
commt = false
|
commt = false
|
||||||
rrtype = false
|
rrtype = false
|
||||||
str = ""
|
p++
|
||||||
// If not in a brace this ends the comment AND the RR
|
// If not in a brace this ends the comment AND the RR
|
||||||
if brace == 0 {
|
if brace == 0 {
|
||||||
owner = true
|
owner = true
|
||||||
l.value = _NEWLINE
|
l.value = _NEWLINE
|
||||||
l.token = "\n"
|
l.token = "\n"
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if str != "" {
|
if p != q {
|
||||||
l.value = _STRING
|
l.value = _STRING
|
||||||
l.token = str
|
l.token = string(buf[p:q])
|
||||||
if !rrtype {
|
if !rrtype {
|
||||||
if _, ok := Str_rr[strings.ToUpper(l.token)]; ok {
|
if _, ok := Str_rr[strings.ToUpper(l.token)]; ok {
|
||||||
l.value = _RRTYPE
|
l.value = _RRTYPE
|
||||||
|
@ -389,89 +393,100 @@ func zlexer(s scanner.Scanner, c chan lex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
}
|
}
|
||||||
if brace > 0 {
|
if brace > 0 {
|
||||||
l.value = _BLANK
|
l.value = _BLANK
|
||||||
l.token = " "
|
p++
|
||||||
if !space {
|
if !space {
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l.value = _NEWLINE
|
l.value = _NEWLINE
|
||||||
l.token = "\n"
|
l.token = "\n"
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
}
|
}
|
||||||
if l.value == _BLANK {
|
if l.value == _BLANK {
|
||||||
space = true
|
space = true
|
||||||
}
|
}
|
||||||
|
|
||||||
str = ""
|
p = q + 1
|
||||||
|
println("hallo")
|
||||||
commt = false
|
commt = false
|
||||||
rrtype = false
|
rrtype = false
|
||||||
owner = true
|
owner = true
|
||||||
case "\\":
|
case '\\':
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if escape {
|
||||||
|
escape = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if escape {
|
|
||||||
str += "\\"
|
|
||||||
escape = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
escape = true
|
escape = true
|
||||||
case "\"":
|
case '"':
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if escape {
|
||||||
|
escape = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if escape {
|
|
||||||
str += "\""
|
|
||||||
escape = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// str += "\"" don't add quoted quotes
|
|
||||||
quote = !quote
|
quote = !quote
|
||||||
case "(":
|
case '(':
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if escape {
|
||||||
|
escape = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if escape {
|
|
||||||
str += "("
|
|
||||||
escape = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
brace++
|
brace++
|
||||||
case ")":
|
case ')':
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if escape {
|
||||||
|
escape = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if escape {
|
|
||||||
str += ")"
|
|
||||||
escape = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
brace--
|
brace--
|
||||||
if brace < 0 {
|
if brace < 0 {
|
||||||
l.err = "Extra closing brace"
|
l.err = "Extra closing brace"
|
||||||
c <- l
|
c <- l
|
||||||
|
p = q + 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if commt {
|
if commt {
|
||||||
|
p++
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
escape = false
|
escape = false
|
||||||
str += x
|
|
||||||
space = false
|
space = false
|
||||||
}
|
}
|
||||||
tok = s.Scan()
|
// tok, err = r.ReadByte() read extra bytes
|
||||||
|
q++
|
||||||
|
if q > n {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Hmm.
|
println("We crashen gewoon hier", p, q)
|
||||||
if len(str) > 0 {
|
// It this need anymore???
|
||||||
|
/*
|
||||||
|
if p != q {
|
||||||
// Send remainder
|
// Send remainder
|
||||||
l.token = str
|
l.token = string(buf[p:q])
|
||||||
l.value = _STRING
|
l.value = _STRING
|
||||||
c <- l
|
c <- l
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringToTtl(l lex, t chan Token) (uint32, bool) {
|
func stringToTtl(l lex, t chan Token) (uint32, bool) {
|
||||||
|
|
Loading…
Reference in New Issue