json_filter/lexical.go

116 lines
2.6 KiB
Go

// 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
}