diff options
Diffstat (limited to 'conf/parser.go')
-rw-r--r-- | conf/parser.go | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/conf/parser.go b/conf/parser.go index 4f58713..3d584f6 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,6 +48,13 @@ 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 @@ -56,8 +67,82 @@ func (p *parser) startparsing() { fmt.Fprintf(os.Stderr, "Error: tokentype: %v, 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 != ObjectOpen { + 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 != Name { + 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) + } + + tok, err := p.s.Peek() + if err != nil { + fmt.Fprintf(os.Stderr, "error when parsing keyvalue. Got an error when checking if there are more keyvalues: %v.\n", err) + return false + } + + fmt.Fprintf(os.Stderr, "peeked %q (type %d) at line %d offset %d.\n", tok.Lit, tok.Type, tok.LineNr, tok.Offset) + if tok.Type == ObjectClose { + p.advanceOneToken("keyvaluelast") + return false + } + + return true } |