github.com/team-ide/go-dialect@v1.9.20/dialect/statement_parser_text.go (about) 1 package dialect 2 3 import ( 4 "errors" 5 "strings" 6 ) 7 8 func parseTextStatement(content string, parent Statement) (statements []Statement, err error) { 9 list, err := parseStringStatement(content, parent, 10 func(thisChar string, parent Statement) (statement Statement) { 11 if thisChar == "[" { 12 statement = &IgnorableStatement{ 13 AbstractStatement: &AbstractStatement{ 14 Parent: parent, 15 }, 16 } 17 } 18 return 19 }, 20 func(thisChar string) (isEnd bool) { 21 if thisChar == "]" { 22 isEnd = true 23 } 24 return 25 }, 26 ) 27 if err != nil { 28 return 29 } 30 31 var list_ []Statement 32 for _, one := range list { 33 list_, err = parseTextExpressionStatement(*one.GetContent(), one.GetParent()) 34 if err != nil { 35 return 36 } 37 switch one.(type) { 38 case *IgnorableStatement: 39 *one.GetContent() = "" 40 *one.GetChildren() = list_ 41 statements = append(statements, one) 42 default: 43 statements = append(statements, list_...) 44 } 45 } 46 //fmt.Println(this_.Sql) 47 return 48 } 49 50 func parseTextExpressionStatement(content string, parent Statement) (statements []Statement, err error) { 51 52 list, err := parseStringStatement(content, parent, 53 func(thisChar string, parent Statement) (statement Statement) { 54 if thisChar == "{" { 55 statement = &ExpressionStatement{ 56 AbstractStatement: &AbstractStatement{ 57 Parent: parent, 58 }, 59 } 60 } 61 return 62 }, 63 func(thisChar string) (matchStart bool) { 64 matchStart = thisChar == "}" 65 return 66 }, 67 ) 68 if err != nil { 69 return 70 } 71 var expressionStatement *ExpressionStatement 72 for _, one := range list { 73 switch one.(type) { 74 case *ExpressionStatement: 75 expressionStatement, err = parseExpressionStatement(*one.GetContent(), one.GetParent()) 76 if err != nil { 77 return 78 } 79 statements = append(statements, expressionStatement) 80 default: 81 statements = append(statements, one) 82 } 83 } 84 return 85 } 86 87 func parseStringStatement(content string, parent Statement, 88 matchStart func(thisChar string, parent Statement) (statement Statement), 89 matchEnd func(thisChar string) (matchStart bool), 90 ) (statements []Statement, err error) { 91 92 var level int 93 var levelStatement = make(map[int]Statement) 94 var str string 95 96 var inStringPack string 97 var inStringLevel int 98 var stringPackChars = []string{"\"", "'"} 99 var lastChar string 100 var thisChar string 101 102 strList := strings.Split(content, "") 103 var matchStatement Statement 104 for i := 0; i < len(strList); i++ { 105 thisChar = strList[i] 106 107 if i > 0 { 108 lastChar = strList[i-1] 109 } 110 packCharIndex := StringsIndex(stringPackChars, thisChar) 111 if packCharIndex >= 0 { 112 // inStringLevel == 0 表示 不在 字符串 包装 中 113 if inStringLevel == 0 { 114 inStringPack = stringPackChars[packCharIndex] 115 // 字符串包装层级 +1 116 inStringLevel++ 117 } else { 118 // 如果有转义符号 类似 “\'”,“\"” 119 if lastChar == "\\" { 120 } else if lastChar == inStringPack { 121 // 如果 前一个字符 与字符串包装字符一致 122 inStringLevel-- 123 } else { 124 // 字符串包装层级 -1 125 inStringLevel-- 126 } 127 } 128 } 129 var thisParentChildren *[]Statement 130 var thisParent = parent 131 if levelStatement[level] == nil { 132 thisParentChildren = &statements 133 } else { 134 thisParent = levelStatement[level].GetParent() 135 if thisParent == parent { 136 thisParentChildren = &statements 137 } else { 138 thisParentChildren = levelStatement[level].GetParent().GetChildren() 139 } 140 } 141 142 if inStringLevel == 0 { 143 if matchStatement = matchStart(thisChar, thisParent); matchStatement != nil { 144 if thisParent == nil { 145 err = errors.New("sql template [" + content + "] parse match start error") 146 return 147 } 148 149 if str != "" { 150 if levelStatement[level] != nil { 151 *levelStatement[level].GetContent() += str 152 } else { 153 textStatement := &TextStatement{ 154 AbstractStatement: &AbstractStatement{ 155 Parent: thisParent, 156 Content: str, 157 }, 158 } 159 *thisParentChildren = append(*thisParentChildren, textStatement) 160 } 161 } 162 *thisParentChildren = append(*thisParentChildren, matchStatement) 163 level++ 164 levelStatement[level] = matchStatement 165 str = "" 166 167 } else if matchEnd(thisChar) { 168 if thisParent == nil || levelStatement[level] == nil { 169 err = errors.New("sql template [" + content + "] parse match end error") 170 return 171 } 172 *levelStatement[level].GetContent() = str 173 levelStatement[level] = nil 174 level-- 175 str = "" 176 } else { 177 str += thisChar 178 } 179 } else { 180 str += thisChar 181 } 182 } 183 if str != "" { 184 textStatement := &TextStatement{ 185 AbstractStatement: &AbstractStatement{ 186 Parent: parent, 187 Content: str, 188 }, 189 } 190 statements = append(statements, textStatement) 191 } 192 return 193 }