2022-12-27 02:37:02 +03:00
|
|
|
package json
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2024-04-28 00:18:36 +03:00
|
|
|
"go.neonxp.ru/json/internal/lexer"
|
2022-12-27 02:37:02 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
func (j *JSON) parse(ch chan lexer.Lexem) (Node, error) {
|
|
|
|
prefix := <-ch
|
|
|
|
return j.createChild(nil, prefix, ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j *JSON) createChild(parent Node, l lexer.Lexem, ch chan lexer.Lexem) (Node, error) {
|
|
|
|
switch l.Type {
|
|
|
|
case lexer.LString:
|
|
|
|
c, err := j.Factory(StringType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
child := c.(StringNode)
|
|
|
|
child.SetString(strings.Trim(l.Value, `"`))
|
|
|
|
return child, nil
|
|
|
|
case lexer.LNumber:
|
|
|
|
num, err := strconv.ParseFloat(l.Value, 64)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
c, err := j.Factory(NumberType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
child := c.(NumberNode)
|
|
|
|
child.SetNumber(num)
|
|
|
|
return child, nil
|
|
|
|
case lexer.LBoolean:
|
|
|
|
b := strings.ToLower(l.Value) == "true"
|
|
|
|
c, err := j.Factory(BooleanType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
child := c.(BooleanNode)
|
|
|
|
child.SetBool(b)
|
|
|
|
return child, nil
|
|
|
|
case lexer.LObjectStart:
|
|
|
|
child, err := j.parseObject(parent, ch)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return child, nil
|
|
|
|
case lexer.LArrayStart:
|
|
|
|
child, err := j.parseArray(parent, ch)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return child, nil
|
|
|
|
case lexer.LNull:
|
|
|
|
c, err := j.Factory(NullType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
return c.(NullNode), nil
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("ivalid token: '%s' type=%s", l.Value, l.Type.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j *JSON) parseObject(parent Node, ch chan lexer.Lexem) (ObjectNode, error) {
|
|
|
|
c, err := j.Factory(ObjectType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
n := c.(ObjectNode)
|
|
|
|
nextKey := ""
|
|
|
|
for l := range ch {
|
|
|
|
switch l.Type {
|
|
|
|
case lexer.LObjectKey:
|
|
|
|
nextKey = strings.Trim(l.Value, `"`)
|
|
|
|
case lexer.LObjectEnd:
|
|
|
|
return n, nil
|
|
|
|
case lexer.LObjectValue:
|
|
|
|
continue
|
|
|
|
default:
|
|
|
|
child, err := j.createChild(n, l, ch)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
n.SetKeyValue(nextKey, child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("unexpected end of object")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j *JSON) parseArray(parent Node, ch chan lexer.Lexem) (ArrayNode, error) {
|
|
|
|
c, err := j.Factory(ArrayType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if c, ok := c.(AcceptParent); ok {
|
2022-12-27 04:14:41 +03:00
|
|
|
c.SetParent(parent)
|
2022-12-27 02:37:02 +03:00
|
|
|
}
|
|
|
|
n := c.(ArrayNode)
|
|
|
|
for l := range ch {
|
|
|
|
switch l.Type {
|
|
|
|
case lexer.LArrayEnd:
|
|
|
|
return n, nil
|
|
|
|
default:
|
|
|
|
child, err := j.createChild(n, l, ch)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
n.Append(child)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("unexpected end of object")
|
|
|
|
}
|