parser: simplify parsing object key even more and fix unscan

This commit is contained in:
Fatih Arslan 2015-10-19 02:01:33 +03:00
parent 17aa3f3c5a
commit 3c21f6b72b

View File

@ -12,8 +12,7 @@ import (
type Parser struct { type Parser struct {
sc *scanner.Scanner sc *scanner.Scanner
tok token.Token // last read token tok token.Token // last read token
prevTok token.Token // previous read token
enableTrace bool enableTrace bool
indent int indent int
@ -90,6 +89,7 @@ func (p *Parser) next() (ast.Node, error) {
switch tok.Type { switch tok.Type {
case token.IDENT, token.STRING: case token.IDENT, token.STRING:
p.unscan()
return p.parseObjectItem() return p.parseObjectItem()
case token.COMMENT: case token.COMMENT:
return &ast.Comment{ return &ast.Comment{
@ -141,16 +141,9 @@ func (p *Parser) parseObjectItem() (*ast.ObjectItem, error) {
// parseObjectKey parses an object key and returns a ObjectKey AST // parseObjectKey parses an object key and returns a ObjectKey AST
func (p *Parser) parseObjectKey() ([]*ast.ObjectKey, error) { func (p *Parser) parseObjectKey() ([]*ast.ObjectKey, error) {
firstKey := false keyCount := 0
nestedObj := false
keys := make([]*ast.ObjectKey, 0) keys := make([]*ast.ObjectKey, 0)
// we have three casses
// 1. assignment: KEY = NODE
// 2. object: KEY { }
// 3. nested object: KEY KEY2 ... KEYN {}
// Invalid cases:
// 1. foo bar = {}
for { for {
tok := p.scan() tok := p.scan()
switch tok.Type { switch tok.Type {
@ -159,26 +152,23 @@ func (p *Parser) parseObjectKey() ([]*ast.ObjectKey, error) {
case token.ASSIGN: case token.ASSIGN:
// assignment or object only, but not nested objects. this is not // assignment or object only, but not nested objects. this is not
// allowed: `foo bar = {}` // allowed: `foo bar = {}`
if nestedObj { if keyCount > 1 {
return nil, fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type) return nil, fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type)
} }
if keyCount == 0 {
return nil, errors.New("no keys found!!!")
}
return keys, nil return keys, nil
case token.LBRACE: case token.LBRACE:
// object // object
return keys, nil return keys, nil
case token.IDENT, token.STRING: case token.IDENT, token.STRING:
// nested object keyCount++
if !firstKey {
firstKey = true
} else {
nestedObj = true
}
keys = append(keys, &ast.ObjectKey{Token: p.tok}) keys = append(keys, &ast.ObjectKey{Token: p.tok})
case token.ILLEGAL: case token.ILLEGAL:
fmt.Println("illegal") fmt.Println("illegal")
// break // scan next
default: default:
return nil, fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type) return nil, fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type)
} }
@ -285,9 +275,6 @@ func (p *Parser) scan() token.Token {
return p.tok return p.tok
} }
// store previous token
p.prevTok = p.tok
// Otherwise read the next token from the scanner and Save it to the buffer // Otherwise read the next token from the scanner and Save it to the buffer
// in case we unscan later. // in case we unscan later.
p.tok = p.sc.Scan() p.tok = p.sc.Scan()
@ -297,7 +284,6 @@ func (p *Parser) scan() token.Token {
// unscan pushes the previously read token back onto the buffer. // unscan pushes the previously read token back onto the buffer.
func (p *Parser) unscan() { func (p *Parser) unscan() {
p.n = 1 p.n = 1
p.tok = p.prevTok
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------