parser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,992 行 · 第 1/3 页
JAVA
1,992 行
switch (token) { case EQ: return new EqExpr(left, parseConcatExpr()); case LT: case LE: case GT: case GE: case NE: return new CmpExpr(left, parseConcatExpr(), token); case BETWEEN: { Expr min = parseConcatExpr(); token = scanToken(); if (token != AND) throw error(L.l("expected AND at '{0}'", tokenName(token))); Expr max = parseConcatExpr(); return new BetweenExpr(left, min, max, isNot); } case IS: { token = scanToken(); isNot = false; if (token == NOT) { token = scanToken(); isNot = true; } if (token == NULL) return new IsNullExpr(left, isNot); else throw error(L.l("expected NULL at '{0}'", tokenName(token))); } case LIKE: { token = scanToken(); if (token == STRING) return new LikeExpr(left, _lexeme, isNot); else throw error(L.l("expected string at '{0}'", tokenName(token))); } case IN: { HashSet<String> values = parseInValues(); return new InExpr(left, values, isNot); } default: _token = token; return left; } } /** * Parses the IN values. */ private HashSet<String> parseInValues() throws SQLException { int token = scanToken(); if (token != '(') throw error(L.l("Expected '('")); HashSet<String> values = new HashSet<String>(); while ((token = scanToken()) != ')') { if (token == STRING) { values.add(_lexeme); } else throw error(L.l("expected STRING at {0}", tokenName(token))); if ((token = scanToken()) != ',') break; } if (token != ')') throw error(L.l("expected ')' at {0}", tokenName(token))); return values; } /** * Parses a concat expression. */ private Expr parseConcatExpr() throws SQLException { Expr left = parseAddExpr(); while (true) { int token = scanToken(); switch (token) { case CONCAT: left = new ConcatExpr(left, parseAddExpr()); break; default: _token = token; return left; } } } /** * Parses a +/- expression. */ private Expr parseAddExpr() throws SQLException { Expr left = parseMulExpr(); while (true) { int token = scanToken(); switch (token) { case '+': case '-': left = new BinaryExpr(left, parseMulExpr(), token); break; default: _token = token; return left; } } } /** * Parses a mul/div expression */ private Expr parseMulExpr() throws SQLException { Expr left = parseTerm(); while (true) { int token = scanToken(); switch (token) { case '*': case '/': case '%': left = new BinaryExpr(left, parseTerm(), token); break; default: _token = token; return left; } } } /** * Parses a term. */ private Expr parseTerm() throws SQLException { int token = scanToken(); switch (token) { case '+': return parseTerm(); case '-': return new UnaryExpr(parseTerm(), token); case '(': Expr expr = parseExpr(); int peekToken; if ((peekToken = scanToken()) != ')') throw error(L.l("expected ')' at {0}", tokenName(peekToken))); return expr; default: _token = token; return parseSimpleTerm(); } } /** * Parses a simple term. */ private Expr parseSimpleTerm() throws SQLException { int token = scanToken(); switch (token) { case IDENTIFIER: { String name = _lexeme; token = scanToken(); if (token == '.') { token = scanToken(); if (token == IDENTIFIER) { String column = _lexeme; return _query.bind(name, column); } else if (token == '*') { return new UnboundStarExpr(name); } else throw error("expected IDENTIFIER"); } else if (token == '(') { FunExpr fun = null; if (name.equalsIgnoreCase("max")) fun = new MaxExpr(); else if (name.equalsIgnoreCase("min")) fun = new MinExpr(); else if (name.equalsIgnoreCase("sum")) fun = new SumExpr(); else if (name.equalsIgnoreCase("avg")) fun = new AvgExpr(); else if (name.equalsIgnoreCase("count")) { fun = new CountExpr(); token = scanToken(); if (token == '*') { fun.addArg(new UnboundStarExpr()); } else _token = token; } else if (name.equalsIgnoreCase("exists")) { token = scanToken(); if (token != SELECT) throw error(L.l("exists requires SELECT at '{0}'", tokenName(token))); ExistsQuery query = new ExistsQuery(_database, _sql); parseSelect(query); ExistsExpr expr = new ExistsExpr(query); query.setSubSelect(expr); _andExpr.add(new ExistsEvalExpr(expr)); token = scanToken(); if (token != ')') throw error(L.l("exists requires ')' at '{0}'", tokenName(token))); return expr; } else { String funName = (Character.toUpperCase(name.charAt(0)) + name.substring(1).toLowerCase()); funName = "com.caucho.db.fun." + funName + "Expr"; try { Class cl = Class.forName(funName); fun = (FunExpr) cl.newInstance(); } catch (ClassNotFoundException e) { log.finer(e.toString()); } catch (Throwable e) { log.log(Level.FINER, e.toString(), e); } if (fun == null) throw error(L.l("`{0}' is an unknown function.", name)); } token = scanToken(); while (token > 0 && token != ')') { _token = token; Expr arg = parseExpr(); fun.addArg(arg); token = scanToken(); if (token == ',') token = scanToken(); } return fun; } else { _token = token; return _query.bind(null, name); } } case STRING: return new StringExpr(_lexeme); case DOUBLE: case INTEGER: case LONG: return NumberExpr.create(_lexeme); case NULL: return new NullExpr(); case TRUE: return BooleanLiteralExpr.create(true); case FALSE: return BooleanLiteralExpr.create(false); case '?': ParamExpr param = new ParamExpr(_params.size()); _params.add(param); return param; default: throw error(L.l("unexpected term {0}", tokenName(token))); } } /** * Parses an identifier. */ private String parseIdentifier() throws SQLException { int token = scanToken(); if (token != IDENTIFIER) throw error(L.l("expected identifier at {0}", tokenName(token))); return _lexeme; } /** * Scan the next token. If the lexeme is a string, its string * representation is in "lexeme". * * @return integer code for the token */ private int scanToken() throws SQLException { if (_token > 0) { int value = _token; _token = -1; return value; } int sign = 1; int ch; for (ch = read(); Character.isWhitespace((char) ch); ch = read()) { } switch (ch) { case -1: case '(': case ')': case '.': case '*': case '/': case '%': case ',': case '?': return ch; case '+': if ((ch = read()) >= '0' && ch <= '9') break; else { unread(ch); return '+'; } case '-': if ((ch = read()) >= '0' && ch <= '9') { sign = -1; break; } else { unread(ch); return '-'; } case '=': return EQ; case '<': if ((ch = read()) == '=') return LE; else if (ch == '>') return NE; else { unread(ch); return LT; } case '>': if ((ch = read()) == '=') return GE; else { unread(ch); return GT; } case '|': if ((ch = read()) == '|') return CONCAT; else { throw error(L.l("'|' expected at {0}", charName(ch))); } // @@ is useless? case '@': if ((ch = read()) != '@') throw error(L.l("`@' expected at {0}", charName(ch))); return scanToken(); } if (Character.isJavaIdentifierStart((char) ch)) { CharBuffer cb = _cb; cb.clear(); for (; ch > 0 && Character.isJavaIdentifierPart((char) ch); ch = read()) cb.append((char) ch); unread(ch); _lexeme = cb.toString(); String lower = _lexeme.toLowerCase(); int token = _reserved.get(lower); if (token > 0) return token; else return IDENTIFIER; } else if (ch >= '0' && ch <= '9') { CharBuffer cb = _cb; cb.clear(); int type = INTEGER; if (sign < 0) cb.append('-'); for (; ch >= '0' && ch <= '9'; ch = read()) cb.append((char) ch); if (ch == '.') { type = DOUBLE; cb.append('.'); for (ch = read(); ch >= '0' && ch <= '9'; ch = read()) cb.append((char) ch); } if (ch == 'e' || ch == 'E') { type = DOUBLE; cb.append('e'); if ((ch = read()) == '+' || ch == '-') { cb.append((char) ch); ch = read(); } if (! (ch >= '0' && ch <= '9')) throw error(L.l("exponent needs digits at {0}", charName(ch))); for (; ch >= '0' && ch <= '9'; ch = read()) cb.append((char) ch); } if (ch == 'F' || ch == 'D') type = DOUBLE; else if (ch == 'L') { type = LONG; } else unread(ch); _lexeme = cb.toString(); return type; } else if (ch == '\'') { CharBuffer cb = _cb; cb.clear(); for (ch = read(); ch >= 0; ch = read()) { if (ch == '\'') { if ((ch = read()) == '\'') cb.append('\''); else { unread(ch); break; } } else if (ch == '\\') { ch = read(); if (ch >= 0) cb.append(ch); } else cb.append((char) ch); } _lexeme = cb.toString(); return STRING; } else if (ch == '#') { // skip comment while ((ch = read()) >= 0 && ch != '\n' && ch != '\r') { } // XXX: cleanup to avoid recursion return scanToken(); } throw error(L.l("unexpected char at {0} ({1})", "" + (char) ch, String.valueOf(ch))); } /** * Returns the next character. */ private int read() { if (_parseIndex < _sqlLength) return _sqlChars[_parseIndex++]; else return -1; } /** * Unread the last character. */ private void unread(int ch) { if (ch >= 0) _parseIndex--; } /** * Returns the name for a character */ private String charName(int ch) { if (ch < 0) return L.l("end of query"); else return String.valueOf((char) ch); } /** * Returns the name of a token */ private String tokenName(int token) { switch (token) { case AS: return "AS"; case ARG: return "?"; case FROM: return "FROM"; case IN: return "IN"; case SELECT: return "SELECT"; case WHERE: return "WHERE"; case OR: return "OR"; case AND: return "AND"; case NOT: return "NOT"; case BETWEEN: return "BETWEEN"; case TRUE: return "TRUE"; case FALSE: return "FALSE"; case NULL: return "NULL"; case GROUP: return "GROUP"; case ORDER: return "ORDER"; case BY: return "BY"; case ASC: return "ASC"; case DESC: return "DESC"; case LIMIT: return "LIMIT"; case -1: return L.l("end of query"); default: if (token < 128) return "'" + String.valueOf((char) token) + "'"; else return "'" + _lexeme + "'"; } } private SQLException error(String msg) { return new SQLParseException(msg + "\n" + _sql); } static { _reserved = new IntMap(); _reserved.put("as", AS); _reserved.put("from", FROM); _reserved.put("in", IN); _reserved.put("select", SELECT); _reserved.put("distinct", DISTINCT); _reserved.put("where", WHERE); _reserved.put("order", ORDER); _reserved.put("group", GROUP); _reserved.put("by", BY); _reserved.put("asc", ASC); _reserved.put("desc", DESC); _reserved.put("limit", LIMIT); _reserved.put("offset", OFFSET); _reserved.put("or", OR); _reserved.put("and", AND); _reserved.put("not", NOT); _reserved.put("between", BETWEEN); _reserved.put("like", LIKE); _reserved.put("escape", ESCAPE); _reserved.put("is", IS); _reserved.put("true", TRUE); _reserved.put("false", FALSE); _reserved.put("unknown", UNKNOWN); _reserved.put("null", NULL); _reserved.put("create", CREATE); _reserved.put("table", TABLE); _reserved.put("insert", INSERT); _reserved.put("into", INTO); _reserved.put("values", VALUES); _reserved.put("drop", DROP); _reserved.put("update", UPDATE); _reserved.put("set", SET); _reserved.put("delete", DELETE); _reserved.put("constraint", CONSTRAINT); _reserved.put("unique", UNIQUE); _reserved.put("check", CHECK); _reserved.put("primary", PRIMARY); _reserved.put("key", KEY); _reserved.put("foreign", FOREIGN); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?