diff --git a/core/expr.go b/core/expr.go index dc2a57f..b65d62b 100644 --- a/core/expr.go +++ b/core/expr.go @@ -10,9 +10,46 @@ const ( exprTokIdent exprTokOp exprTokStr + exprTokFloat + exprTokInt ) -func readToken(txt []rune) (tok int, end int) { +func isExprIdent(c rune) bool { + return unicode.IsDigit(c) || + ('a' <= c && c <= 'z') || + ('A' <= c && c <= 'Z') || + c == '.' || c == '_' +} + +// func isExprIdentFirst(c rune) bool { +// return unicode.IsDigit(c) || +// ('a' <= c && c <= 'z') || +// ('A' <= c && c <= 'Z') || +// c == '_' +// } + +func readExprString(txt []rune) int { + quote := txt[0] + isEscape := false + for i := 1; i < len(txt); i++ { + c := txt[i] + if c == '\\' { + isEscape = !isEscape + continue + } + if c == quote { + if isEscape { + isEscape = false + continue + } + return i + 1 + } + isEscape = false + } + return len(txt) +} + +func readExprToken(txt []rune) (tok int, end int) { c := txt[0] if unicode.IsSpace(c) { for i := 1; i < len(txt); i++ { @@ -24,20 +61,48 @@ func readToken(txt []rune) (tok int, end int) { return exprTokWS, len(txt) } - if unicode.IsDigit(c) || - ('a' <= c && c <= 'z') || - ('A' <= c && c <= 'Z') || - c == '.' || - c == '_' { + /////// begin + // 我们无需区分 number 和 ident, 所以下面删除了 + // if unicode.IsDigit(c) { + // i := 1 + // for ; ; i++ { + // if i >= len(txt) { + // return exprTokInt, len(txt) + // } + // if !unicode.IsDigit(txt[i]) { + // break + // } + // } + // if txt[i] == '.' { + // for ; ; i++ { + // if i >= len(txt) { + // return exprTokFloat, len(txt) + // } + // if !unicode.IsDigit(txt[i]) { + // break + // } + // } + // return exprTokFloat, len(txt) + // } + // return exprTokInt, len(txt) + // } + // if c == '.' { + // for i := 1; i < len(txt); i++ { + // if !unicode.IsDigit(txt[i]) { + // return exprTokIdent, i + // } + // } + // return exprTokFloat, len(txt) + // } + + // if isExprIdentFirst(c) { + /////// end + + if isExprIdent(c) { for i := 1; i < len(txt); i++ { c = txt[i] - if !unicode.IsDigit(c) && - !('a' <= c && c <= 'z') && - !('A' <= c && c <= 'Z') && - c != '.' && - c != '_' { - + if !isExprIdent(c) { return exprTokIdent, i } } @@ -45,24 +110,8 @@ func readToken(txt []rune) (tok int, end int) { } if c == '\'' || c == '"' { - quote := c - isEscape := false - for i := 1; i < len(txt); i++ { - c = txt[i] - if c == '\\' { - isEscape = !isEscape - continue - } - if c == quote { - if isEscape { - isEscape = false - continue - } - return exprTokStr, i + 1 - } - isEscape = false - } - return exprTokStr, len(txt) + end := readExprString(txt) + return exprTokStr, end } return exprTokOp, 1 @@ -73,7 +122,7 @@ func replaceAndOr(s string) string { var sb strings.Builder for len(runes) > 0 { - tok, next := readToken(runes) + tok, next := readExprToken(runes) // fmt.Println(tok, string(runes[:next])) if tok != exprTokIdent {