json_filter/syntax.go

154 lines
4.4 KiB
Go

// Package filter ...
//
// Description : 语法分析
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2022-07-04 17:53
package filter
import (
"github.com/pkg/errors"
)
// NewSyntax 构建JSON语法树
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:33 2022/7/5
func NewSyntax(jsonData string) *syntax {
return &syntax{
lexicalInstance: NewLexical(jsonData),
syntaxResult: nil,
}
}
type syntax struct {
// 词法分析实例
lexicalInstance *lexical
// 词法分析结果
lexicalResult []*lexicalNode
// 语法分析结果
syntaxResult *jsonNode
}
// Parse 构建语法树
//
// Author : go_developer@163.com<白茶清欢>
//
// 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
}