增加kv语法分析处理
This commit is contained in:
parent
030828cab9
commit
f82ae6893c
120
syntax.go
120
syntax.go
@ -7,6 +7,10 @@
|
||||
// Date : 2022-07-04 17:53
|
||||
package filter
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NewSyntax 构建JSON语法树
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
@ -15,12 +19,17 @@ package filter
|
||||
func NewSyntax(jsonData string) *syntax {
|
||||
return &syntax{
|
||||
lexicalInstance: NewLexical(jsonData),
|
||||
syntaxResult: nil,
|
||||
}
|
||||
}
|
||||
|
||||
type syntax struct {
|
||||
// 词法分析实例
|
||||
lexicalInstance *lexical
|
||||
// 词法分析结果
|
||||
lexicalResult []*lexicalNode
|
||||
// 语法分析结果
|
||||
syntaxResult *jsonNode
|
||||
}
|
||||
|
||||
// Parse 构建语法树
|
||||
@ -29,5 +38,116 @@ type syntax struct {
|
||||
//
|
||||
// Date : 16:35 2022/7/5
|
||||
func (s *syntax) Parse() error {
|
||||
if err := s.lexicalInstance.Parse(); nil != err {
|
||||
// 词法解析失败
|
||||
return err
|
||||
}
|
||||
s.lexicalResult = s.lexicalInstance.Result()
|
||||
if len(s.lexicalResult) == 0 {
|
||||
return errors.New("词法解析无任何结果")
|
||||
}
|
||||
// TODO : 循环处理
|
||||
generateNode, lastIdx, err := s.generateJSONNode(0)
|
||||
if nil != err {
|
||||
return err
|
||||
}
|
||||
if lastIdx >= len(s.lexicalResult) {
|
||||
// 词法处理完成
|
||||
return nil
|
||||
}
|
||||
if nil == s.syntaxResult {
|
||||
s.syntaxResult = generateNode
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// generateJSONNode 构建 JSONNode, 参数 : 从那个索引开始处理 返回值 : 当前 json 节点, 下次从那个索引开始处理, 异常
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:58 2022/7/5
|
||||
func (s *syntax) generateJSONNode(currentLexicalIdx int) (*jsonNode, int, error) {
|
||||
generateJSONNode := &jsonNode{
|
||||
Name: "",
|
||||
Parent: nil,
|
||||
Son: nil,
|
||||
PreBrother: nil,
|
||||
NextBrother: nil,
|
||||
Val: nil,
|
||||
Type: "",
|
||||
}
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == objectLeftToken {
|
||||
// 对象的起始, 类型一定为对象
|
||||
generateJSONNode.Type = NodeTypeObject
|
||||
|
||||
// 下一个必定为 " (原因: 词法分析时, 已经过滤掉无用的空格换行符等, JSON数据已压缩成单行字符串)
|
||||
currentLexicalIdx++
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() != keyLeftRightToken {
|
||||
// 不是 " 号, 说明数据格式非法
|
||||
return nil, currentLexicalIdx, errors.New("JSON格式非法")
|
||||
}
|
||||
|
||||
// 在下一个必定是 json 的 key
|
||||
currentLexicalIdx++
|
||||
generateJSONNode.Name = s.lexicalResult[currentLexicalIdx].ValStr()
|
||||
|
||||
// 在下一个必定是 "
|
||||
currentLexicalIdx++
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() != keyLeftRightToken {
|
||||
// 不是 " 号, 说明数据格式非法
|
||||
return nil, currentLexicalIdx, errors.New("JSON格式非法")
|
||||
}
|
||||
|
||||
// 在下一个必定是 :
|
||||
currentLexicalIdx++
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() != colonToken {
|
||||
// 不是 : 号, 说明数据格式非法
|
||||
return nil, currentLexicalIdx, errors.New("JSON格式非法")
|
||||
}
|
||||
|
||||
// 到了取值部分, 具体分析是简单 k -> v or k -> object or k -> list
|
||||
currentLexicalIdx++
|
||||
if s.lexicalResult[currentLexicalIdx].IsToken &&
|
||||
s.lexicalResult[currentLexicalIdx].ValStr() != keyLeftRightToken {
|
||||
// 是关键字, 且不是 " 号 , 说明不是简单KV, 后续具体处理
|
||||
return generateJSONNode, currentLexicalIdx, nil
|
||||
}
|
||||
// 简单KV, 下一个必定是取值
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == keyLeftRightToken {
|
||||
// 双引号
|
||||
currentLexicalIdx++
|
||||
generateJSONNode.Val = s.lexicalResult[currentLexicalIdx].ValStr()
|
||||
// 跳过字符串闭合的 " 号
|
||||
currentLexicalIdx = currentLexicalIdx + 2
|
||||
// 判断 闭合 " 之后 是不是 , / ] / }
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == commaToken {
|
||||
// 跳过 分割的 ,
|
||||
currentLexicalIdx++
|
||||
} else {
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == objectRightToken ||
|
||||
s.lexicalResult[currentLexicalIdx].ValStr() == listRightToken {
|
||||
// 跳过整体对象的闭合标签
|
||||
currentLexicalIdx++
|
||||
}
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == commaToken {
|
||||
// 还是 ,
|
||||
currentLexicalIdx++
|
||||
}
|
||||
}
|
||||
} else {
|
||||
generateJSONNode.Val = s.lexicalResult[currentLexicalIdx].Val
|
||||
generateJSONNode.Type = s.lexicalResult[currentLexicalIdx].Type
|
||||
currentLexicalIdx++
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == objectRightToken ||
|
||||
s.lexicalResult[currentLexicalIdx].ValStr() == listRightToken {
|
||||
// 跳过整体对象的闭合标签
|
||||
currentLexicalIdx++
|
||||
}
|
||||
if s.lexicalResult[currentLexicalIdx].ValStr() == commaToken {
|
||||
// 还是 ,
|
||||
currentLexicalIdx++
|
||||
}
|
||||
}
|
||||
}
|
||||
return generateJSONNode, currentLexicalIdx, nil
|
||||
}
|
||||
|
38
syntax_test.go
Normal file
38
syntax_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Package filter ...
|
||||
//
|
||||
// Description : filter ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2022-07-05 17:43
|
||||
package filter
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_syntax_Parse(t *testing.T) {
|
||||
jsonData := `{
|
||||
"start" : 123456,
|
||||
"name" : "zhangsan",
|
||||
"age":"18",
|
||||
"extension":{
|
||||
"sex":"man",
|
||||
"height":"180"
|
||||
},
|
||||
"teacher_list":[
|
||||
{
|
||||
"name":"t1",
|
||||
"age":"11"
|
||||
},
|
||||
{
|
||||
"name":"t2",
|
||||
"age":"12"
|
||||
}
|
||||
]
|
||||
}`
|
||||
//jsonData = `{"name":"zhangsan","age":"18","extension":{"sex":"man","height":"180"},"teacher_list":[{"name":"t1","age":"11"},{"name":"t2","age":"12"}]}`
|
||||
|
||||
instance := NewSyntax(jsonData)
|
||||
_ = instance.Parse()
|
||||
}
|
Loading…
Reference in New Issue
Block a user