增加kv语法分析处理

This commit is contained in:
白茶清欢 2022-07-05 17:48:40 +08:00
parent 030828cab9
commit f82ae6893c
2 changed files with 158 additions and 0 deletions

120
syntax.go
View File

@ -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
View 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()
}