parser.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,992 行 · 第 1/3 页
JAVA
1,992 行
if ((token = scanToken()) != '(') throw error(L.l("expected '(' at `{0}'", tokenName(token))); do { token = scanToken(); switch (token) { case IDENTIFIER: parseCreateColumn(factory, _lexeme); break; case UNIQUE: factory.addUnique(parseColumnNames()); break; case PRIMARY: token = scanToken(); if (token != KEY) throw error(L.l("expected 'key' at {0}", tokenName(token))); factory.addPrimaryKey(parseColumnNames()); break; case KEY: String key = parseIdentifier(); parseColumnNames(); // factory.addPrimaryKey(parseColumnNames()); break; case CHECK: if ((token = scanToken()) != '(') throw error(L.l("Expected '(' at '{0}'", tokenName(token))); parseExpr(); if ((token = scanToken()) != ')') throw error(L.l("Expected ')' at '{0}'", tokenName(token))); break; default: throw error(L.l("unexpected token `{0}'", tokenName(token))); } token = scanToken(); } while (token == ','); if (token != ')') throw error(L.l("expected ')' at `{0}'", tokenName(token))); return new CreateQuery(_database, _sql, factory); } /** * Parses a column declaration. */ private void parseCreateColumn(TableFactory factory, String name) throws SQLException { int token; if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected column type at {0}", tokenName(token))); String type = _lexeme; int length = -1; int scale = -1; if (type.equalsIgnoreCase("double")) { if ((token = scanToken()) == IDENTIFIER) { if (_lexeme.equalsIgnoreCase("precision")) { } else throw error(L.l("unexpected double type at {0}", _lexeme)); } else _token = token; } if ((token = scanToken()) == '(') { if ((token = scanToken()) != INTEGER) throw error(L.l("expected column width at `{0}'", tokenName(token))); length = Integer.parseInt(_lexeme); if ((token = scanToken()) == ',') { if ((token = scanToken()) != INTEGER) throw error(L.l("expected column scale at `{0}'", tokenName(token))); scale = Integer.parseInt(_lexeme); token = scanToken(); } if (token != ')') throw error(L.l("expected ')' at '{0}'", tokenName(token))); } else _token = token; if (type.equalsIgnoreCase("varchar")) { if (length < 0) throw error(L.l("VARCHAR needs a defined length")); factory.addVarchar(name, length); } else if (type.equalsIgnoreCase("char")) { if (length < 0) length = 1; factory.addVarchar(name, length); } else if (type.equalsIgnoreCase("varbinary")) { if (length < 0) throw error(L.l("VARBINARY needs a defined length")); factory.addVarbinary(name, length); } else if (type.equalsIgnoreCase("binary")) { if (length < 0) throw error(L.l("BINARY needs a defined length")); factory.addBinary(name, length); } else if (type.equalsIgnoreCase("blob")) { factory.addBlob(name); } else if (type.equalsIgnoreCase("smallint") || type.equalsIgnoreCase("tinyint") || type.equalsIgnoreCase("bit")) { factory.addShort(name); } else if (type.equalsIgnoreCase("integer") || type.equalsIgnoreCase("int") || type.equalsIgnoreCase("mediumint")) { factory.addInteger(name); } else if (type.equalsIgnoreCase("bigint")) { factory.addLong(name); } else if (type.equalsIgnoreCase("double") || type.equalsIgnoreCase("float") || type.equalsIgnoreCase("real")) { factory.addDouble(name); } else if (type.equalsIgnoreCase("datetime") || type.equalsIgnoreCase("timestamp")) { factory.addDateTime(name); } else if (type.equalsIgnoreCase("text") || type.equalsIgnoreCase("clob")) { factory.addVarchar(name, 255); } else if (type.equalsIgnoreCase("decimal") || type.equalsIgnoreCase("numeric")) { factory.addNumeric(name, length, scale); } else throw error(L.l("Unknown type {0}", type)); token = scanToken(); if (token == IDENTIFIER && _lexeme.equalsIgnoreCase("default")) { Expr defaultExpr = parseExpr(); factory.setDefault(name, defaultExpr); } else _token = token; while (true) { token = scanToken(); // XXX: stuff like NOT NULL switch (token) { case ')': case ',': _token = token; return; case UNIQUE: factory.setUnique(name); break; case PRIMARY: token = scanToken(); if (token != KEY) throw error(L.l("expected key at {0}", tokenName(token))); factory.setPrimaryKey(name); break; case CHECK: if ((token = scanToken()) != '(') throw error(L.l("Expected '(' at '{0}'", tokenName(token))); parseExpr(); if ((token = scanToken()) != ')') throw error(L.l("Expected ')' at '{0}'", tokenName(token))); break; case IDENTIFIER: String id = _lexeme; if (id.equalsIgnoreCase("references")) { ArrayList<String> foreignKey = new ArrayList<String>(); foreignKey.add(name); parseReferences(foreignKey); } else if (id.equalsIgnoreCase("default")) { Expr expr = parseExpr(); } else if (id.equalsIgnoreCase("auto_increment")) { factory.setAutoIncrement(name, 1); } else if (id.equalsIgnoreCase("unsigned")) { } else if (id.equalsIgnoreCase("binary")) { } else throw error(L.l("unexpected token '{0}'", tokenName(token))); break; case NULL: break; case NOT: if ((token = scanToken()) == NULL) factory.setNotNull(name); else throw error(L.l("unexpected token '{0}'", tokenName(token))); break; default: throw error(L.l("unexpected token '{0}'", tokenName(token))); } } } /** * Parses a key constraint declaration. */ private void parseKeyConstraint(TableFactory factory) throws SQLException { String key = parseIdentifier(); int token = scanToken(); if (token == '(') { parseIdentifier(); token = scanToken(); if (token != ')') throw error("expected ')'"); } else _token = token; } /** * Parses the references clause. */ public void parseReferences(ArrayList<String> name) throws SQLException { String foreignTable = parseIdentifier(); int token = scanToken(); ArrayList<String> foreignColumns = new ArrayList<String>(); if (token == '(') { _token = token; foreignColumns = parseColumnNames(); } else _token = token; } /** * Parses a list of column names */ public ArrayList<String> parseColumnNames() throws SQLException { ArrayList<String> columns = new ArrayList<String>(); int token = scanToken(); if (token == '(') { do { columns.add(parseIdentifier()); token = scanToken(); } while (token == ','); if (token != ')') throw error(L.l("expected ')' at '{0}'", tokenName(token))); } else if (token == IDENTIFIER) { columns.add(_lexeme); _token = token; } else throw error(L.l("expected '(' at '{0}'", tokenName(token))); return columns; } /** * Parses the insert. */ private Query parseInsert() throws SQLException { int token; if ((token = scanToken()) != INTO) throw error(L.l("expected INTO at `{0}'", tokenName(token))); if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected identifier at `{0}'", tokenName(token))); Table table = _database.getTable(_lexeme); if (table == null) throw error(L.l("unknown table `{0}'", tokenName(token))); FromItem fromItem = new FromItem(table, table.getName()); FromItem[] fromList = new FromItem[] { fromItem }; ArrayList<Column> columns = new ArrayList<Column>(); if ((token = scanToken()) == '(') { do { String columnName = parseIdentifier(); Column column = table.getColumn(columnName); if (column == null) throw new SQLException(L.l("`{0}' is not a valid column in {1}", columnName, table.getName())); columns.add(column); } while ((token = scanToken()) == ','); if (token != ')') throw error(L.l("expected ')' at `{0}'", tokenName(token))); token = scanToken(); } else { Column []columnArray = table.getColumns(); for (int i = 0; i < columnArray.length; i++) columns.add(columnArray[i]); } if (token != VALUES) throw error(L.l("expected VALUES at `{0}'", tokenName(token))); if ((token = scanToken()) != '(') throw error(L.l("expected '(' at `{0}'", tokenName(token))); ArrayList<Expr> values = new ArrayList<Expr>(); InsertQuery query = new InsertQuery(_database, _sql, table, columns); _query = query; int i = 0; do { Expr expr = parseExpr(); expr = expr.bind(new TempQuery(fromList)); values.add(expr); i++; } while ((token = scanToken()) == ','); if (token != ')') throw error(L.l("expected ')' at {0}", tokenName(token))); if (columns.size() != values.size()) throw error(L.l("number of columns does not match number of values")); ParamExpr []params = _params.toArray(new ParamExpr[_params.size()]); query.setParams(params); query.setValues(values); query.init(); return query; } /** * Parses the delete. */ private Query parseDelete() throws SQLException { int token; if ((token = scanToken()) != FROM) throw error(L.l("expected FROM at `{0}'", tokenName(token))); if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected identifier at `{0}'", tokenName(token))); Table table = _database.getTable(_lexeme); if (table == null) throw error(L.l("unknown table `{0}'", tokenName(token))); DeleteQuery query = new DeleteQuery(_database, _sql, table); _query = query; Expr whereExpr = null; token = scanToken(); if (token == WHERE) whereExpr = parseExpr(); else if (token >= 0) throw error(L.l("expected WHERE at `{0}'", tokenName(token))); ParamExpr []params = _params.toArray(new ParamExpr[_params.size()]); query.setParams(params); query.setWhereExpr(whereExpr); return query; } /** * Parses the insert. */ private Query parseDrop() throws SQLException { int token; if ((token = scanToken()) != TABLE) throw error(L.l("expected TABLE at `{0}'", tokenName(token))); if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected identifier at `{0}'", tokenName(token))); String table = _lexeme; if ((token = scanToken()) >= 0) throw error(L.l("expected end of query at `{0}'", tokenName(token))); return new DropQuery(_sql, _database, table); } /** * Parses the select. */ private Query parseUpdate() throws SQLException { int token; if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected identifier at `{0}'", tokenName(token))); String name = _lexeme; Table table = _database.getTable(name); if (table == null) throw error(L.l("`{0}' is an unknown table in INSERT.", name)); if ((token = scanToken()) != SET) throw error(L.l("expected SET at {0}", tokenName(token))); UpdateQuery query = new UpdateQuery(_database, _sql, table); _query = query; ArrayList<SetItem> setItemList = new ArrayList<SetItem>(); do { SetItem item = parseSetItem(table); setItemList.add(item); } while ((token = scanToken()) == ','); Expr whereExpr = null; if (token == WHERE) whereExpr = parseExpr(); SetItem []setItems = new SetItem[setItemList.size()]; setItemList.toArray(setItems); ParamExpr []params = _params.toArray(new ParamExpr[_params.size()]); query.setSetItems(setItems); query.setParams(params); query.setWhereExpr(whereExpr); return query; } /** * Parses a set item. */ private SetItem parseSetItem(Table table) throws SQLException { int token; if ((token = scanToken()) != IDENTIFIER) throw error(L.l("expected identifier at `{0}'", tokenName(token))); Column column = table.getColumn(_lexeme); if (column == null) throw error(L.l("`{0}' is an unknown column in table {1}.", _lexeme, table.getName())); if ((token = scanToken()) != EQ) throw error(L.l("expected `=' at {0}", tokenName(token))); Expr expr = parseExpr(); return new SetItem(table, column, expr); } /** * Parses an expression. */ private Expr parseExpr() throws SQLException { int token = scanToken(); if (token == SELECT) return parseSubSelect(); else { _token = token; return parseOrExpr(); } } /** * Parses a sub-select expression. */ private Expr parseSubSelect() throws SQLException { return parseSubSelect(new SelectQuery(_database, _sql)); } /** * Parses a sub-select expression. */ private Expr parseSubSelect(SelectQuery query) throws SQLException { parseSelect(query); SubSelectExpr expr = new SubSelectExpr(query); query.setSubSelect(expr); _andExpr.add(new SubSelectEvalExpr(expr)); return expr; } /** * Parses an OR expression. */ private Expr parseOrExpr() throws SQLException { Expr left = parseAndExpr(); while (true) { int token = scanToken(); switch (token) { case OR: left = new OrExpr(left, parseAndExpr()); break; default: _token = token; return left; } } } /** * Parses an AND expression. */ private Expr parseAndExpr() throws SQLException { AndExpr oldAndExpr = _andExpr; AndExpr andExpr = new AndExpr(); _andExpr = andExpr; andExpr.add(parseNotExpr()); while (true) { int token = scanToken(); switch (token) { case AND: andExpr.add(parseNotExpr()); break; default: _token = token; _andExpr = oldAndExpr; return andExpr.getSingleExpr(); } } } /** * Parses a term. */ private Expr parseNotExpr() throws SQLException { int token = scanToken(); switch (token) { case NOT: return new NotExpr(parseNotExpr()); default: _token = token; return parseCmpExpr(); } } /** * Parses a CMP expression. */ private Expr parseCmpExpr() throws SQLException { Expr left = parseConcatExpr(); int token = scanToken(); boolean isNot = false; if (token == NOT) { isNot = true; token = scanToken(); if (token != BETWEEN && token != LIKE && token != IN) { _token = token; return left; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?