parser: simplify parsing object key even more and fix unscan
This commit is contained in:
parent
17aa3f3c5a
commit
3c21f6b72b
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user