154 lines
4.4 KiB
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
|
|
}
|