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  }