// Package filter ... // // Description : JSON 词法分析 // // Author : go_developer@163.com<白茶清欢> // // Date : 2022-07-04 17:52 package filter import ( "strings" "git.zhangdeman.cn/zhangdeman/util" "github.com/pkg/errors" ) // NewLexical 获取实例 // // Author : go_developer@163.com<白茶清欢> // // Date : 20:52 2022/7/4 func NewLexical(jsonData string) *lexical { return &lexical{jsonData: jsonData} } // lexical 词法解析 // // Author : go_developer@163.com<白茶清欢> // // Date : 20:42 2022/7/4 type lexical struct { jsonData string keyLeftRightTokenCnt int } // Parse 解析词法 // // Author : go_developer@163.com<白茶清欢> // // Date : 18:11 2022/7/4 func (l *lexical) Parse(jsonData string) ([]lexicalNode, error) { jsonData = strings.ReplaceAll(strings.ReplaceAll(jsonData, "\n", ""), "\t", "") // mt.Println(jsonData) if len(jsonData) < 2 { return nil, errors.New("input data is not json") } lexicalList := make([]lexicalNode, 0) tmpStr := "" for _, itemChar := range jsonData { currentChar := string(itemChar) preChar := "-1" if len(lexicalList) > 0 { preChar = lexicalList[len(lexicalList)-1].Val if len(tmpStr) == 0 && preChar == objectLeftToken && currentChar == " " { // 无意义的空格 continue } if len(tmpStr) == 0 && currentChar == " " && preChar == keyLeftRightToken && l.keyLeftRightTokenCnt%2 == 0 { // " : 之间的空格无意义 continue } } if l.inputCharIsToken(currentChar, preChar) { if currentChar == keyLeftRightToken { // 双引号计数 l.keyLeftRightTokenCnt++ } // 是关键词 if len(tmpStr) > 0 { lexicalList = append(lexicalList, lexicalNode{ Val: tmpStr, IsToken: false, }) } lexicalList = append(lexicalList, lexicalNode{ Val: currentChar, IsToken: true, }) tmpStr = "" } else { // 不是关键词, 继续向后走 tmpStr = tmpStr + currentChar } } util.JSON.ConsoleOutput(lexicalList) return nil, nil } // inputCharIsToken 输入字符是否为关键字 // // Author : go_developer@163.com<白茶清欢> // // Date : 18:15 2022/7/4 func (l *lexical) inputCharIsToken(inputChar string, preChar string) bool { if preChar == escapeCharacterToken { // 前一个是转义符, 当前不是关键字 return false } tokenCharList := []string{ listLeftToken, listRightToken, objectLeftToken, objectRightToken, keyLeftRightToken, kvPairSplitToken, escapeCharacterToken, } for _, itemChar := range tokenCharList { if itemChar == inputChar { return true } } return false }