From f82ae6893cd0b1a9f6bdd6c5e0420b612f1f0971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Tue, 5 Jul 2022 17:48:40 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0kv=E8=AF=AD=E6=B3=95=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- syntax.go | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ syntax_test.go | 38 ++++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 syntax_test.go diff --git a/syntax.go b/syntax.go index a8655d9..9491e35 100644 --- a/syntax.go +++ b/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 +} diff --git a/syntax_test.go b/syntax_test.go new file mode 100644 index 0000000..2d25f30 --- /dev/null +++ b/syntax_test.go @@ -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() +}