summaryrefslogtreecommitdiff
path: root/conf
diff options
context:
space:
mode:
Diffstat (limited to 'conf')
-rw-r--r--conf/parser.go92
-rw-r--r--conf/scanner.go17
2 files changed, 96 insertions, 13 deletions
diff --git a/conf/parser.go b/conf/parser.go
index 75f610c..26784f4 100644
--- a/conf/parser.go
+++ b/conf/parser.go
@@ -1,8 +1,12 @@
// grammar of the config file
//
+// Notes: We parse exactly three modules ("input", "filter", "output")
+// in our configuration. Each module consists of two name-object pairs
+// that are nested. We don't want to allow limitless recursion here.
+//
// config = module module module
-// module = name object
-// name = 'input' | 'filter' | 'etc.'
+// module = name object name object
+// name = 'input' | 'filter' | 'output' | etc.
// object = '{' keyvalue | keyvalue | ... '}'
// keyvalue = statement '=>' value
// statement = name | if
@@ -17,8 +21,8 @@ import (
"os"
)
-// Having a Config to Manager function could be nice?
-// Or we could just return a Manager from here.
+// Having a Config to Manager function could be nice? Or we could just
+// return a Manager from here which may be even better...
type Config struct {
}
@@ -44,20 +48,88 @@ func NewConfig(r io.Reader) *Config {
}
func (p *parser) startparsing() {
+ p.module("input")
+
+ p.module("filter")
+
+}
+
+func (p *parser) advanceOneToken(place string) {
var err error
p.last = p.cur
p.cur, err = p.s.Scan()
- for err == nil {
- fmt.Fprintf(os.Stderr, "tokentype: %d, token: %q offset: %d, line: %d\n", p.cur.Type, p.cur.Lit, p.cur.Offset, p.cur.LineNr)
- p.last = p.cur
- p.cur, err = p.s.Scan()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error when parsing %s. Scanner returned an error %v.\n", place, err)
+ os.Exit(1)
}
- fmt.Fprintf(os.Stderr, "Error: tokentype: %d, token: %q, err: %v\n", p.cur.Type, p.cur.Lit, err)
}
-func (p *parser) module(name string) {
+func (p *parser) module(firstname string) {
+ p.advanceOneToken("module")
+
+ fmt.Fprintf(os.Stderr, "tokentype: %d, token: %q\n", p.cur.Type, p.cur.Lit)
+
+ if p.cur.Lit != firstname {
+ fmt.Fprintf(os.Stderr, "error when parsing module. We were expecting name %q but got %q at line %d offset %d.\n", firstname, p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
+ p.advanceOneToken("module")
+ if p.cur.Type != ObjectDelimiter {
+ fmt.Fprintf(os.Stderr, "error when parsing module. We were expecting an opening bracket but got %q at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
+ p.advanceOneToken("module")
+ if p.cur.Type != Name {
+ fmt.Fprintf(os.Stderr, "error when parsing module. We were expecting another name but got %q at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+ p.object()
+
+ p.advanceOneToken("module")
+ if p.cur.Lit[0] != '}' {
+ fmt.Fprintf(os.Stderr, "error when parsing module. Was expecting a closing bracket but got %s at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
}
func (p *parser) object() {
+ p.advanceOneToken("object")
+
+ if p.cur.Lit[0] != '{' {
+ fmt.Fprintf(os.Stderr, "error when parsing object. Was expecting an opening bracket but got %s at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+ // hack to deal with case where there is no white space between
+ // the delimiters.
+ if p.cur.Lit == "{}" {
+ return
+ }
+
+ for {
+ more := p.keyvalue()
+ if !more {
+ break
+ }
+ }
+
+}
+
+func (p *parser) keyvalue() bool {
+ p.advanceOneToken("keyvalue")
+
+ fmt.Fprintf(os.Stderr, "keyvalue: tokentype: %d, token: %q\n", p.cur.Type, p.cur.Lit)
+ if p.cur.Type != Literal {
+ fmt.Fprintf(os.Stderr, "error when parsing keyvalue. Was expecting a name but got %q at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
+ p.advanceOneToken("keyvalue")
+ if p.cur.Lit != "=>" {
+ fmt.Fprintf(os.Stderr, "error when parsing keyvalue. Was expecting a '=>' but got %q at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
+ p.advanceOneToken("keyvalue")
+ if p.cur.Type != Literal || p.cur.Type != Literal {
+ fmt.Fprintf(os.Stderr, "error when parsing keyvalue. Was expecting a literal or a name but got %q at line %d offset %d.\n", p.cur.Lit, p.cur.LineNr, p.cur.Offset)
+ }
+
+ return false
}
diff --git a/conf/scanner.go b/conf/scanner.go
index fd9868a..44301fe 100644
--- a/conf/scanner.go
+++ b/conf/scanner.go
@@ -14,8 +14,10 @@ type tokentype int
const (
Name tokentype = iota
Literal
- DeliOpen
- DeliClose
+ ListDelimiter
+ ObjectDelimiter
+ EmptyList
+ EmptyObject
Nothing
IfStatement
)
@@ -50,7 +52,16 @@ func newScanner(r io.Reader) *scanner {
}
func getTokenType(s []byte) tokentype {
- return Nothing
+ switch s[0] {
+ case '"', '\'':
+ return Literal
+ case '[':
+ return ListDelimiter
+ case '{':
+ return ObjectDelimiter
+ }
+
+ return Name
}
func (s *scanner) Scan() (token, error) {