// 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 { // TODO : 是关键字, 且不是 " 号 , 说明不是简单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 }