增加kv语法分析处理
This commit is contained in:
		
							
								
								
									
										120
									
								
								syntax.go
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								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 | ||||
| } | ||||
|  | ||||
							
								
								
									
										38
									
								
								syntax_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								syntax_test.go
									
									
									
									
									
										Normal 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() | ||||
| } | ||||
		Reference in New Issue
	
	Block a user