/* * Copyright 2010 NCHOVY * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.sqlparser.syntax; import java.nio.BufferUnderflowException; import java.text.ParseException; import java.util.HashSet; import java.util.Set; import org.krakenapps.bnf.Binding; import org.krakenapps.bnf.ParserContext; import org.krakenapps.bnf.Placeholder; import org.krakenapps.bnf.Result; import org.krakenapps.bnf.StringUtil; public class RegularIdentifierPlaceholder implements Placeholder { private static Set<String> keywords = new HashSet<String>(); static { String[] words = new String[] { "ABSOLUTE", "ACTION", "ADD", "ADMIN", "AFTER", "AGGREGATE", "ALIAS", "ALL", "ALLOCATE", "ALTER", "AND", "ANY", "ARE", "ARRAY", "AS", "ASC", "AT", "AUTHORIZATION", "BEFORE", "BEGIN", "BINARY", "BIT", "BLOB", "BOOLEAN", "BOTH", "BREADTH", "BY", "CALL", "CASCADE", "CASCADED", "CASE", "CAST", "CATALOG", "CHAR", "CHARACTER", "CHECK", "CLASS", "CLOB", "CLOSE", "COLLATE", "COLLATION", "COLUMN", "COMMIT", "COMPLETION", "CONDITION", "CONNECT", "CONNECTION", "CONSTRAINT", "CONSTRAINTS", "CONSTRUCTOR", "CONTAINS", "CONTINUE", "CORRESPONDING", "CREATE", "CROSS", "CUBE", "CURRENT", "CURRENT_DATE", "CURRENT_PATH", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "CURSOR", "CYCLE", "DATA", "DATALINK", "DATE", "DAY", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFERRABLE", "DELETE", "DEPTH", "ASSERTION", "DEREF", "DESC", "DESCRIPTOR", "DIAGNOSTICS", "DICTIONARY", "DISCONNECT", "DO", "DOMAIN", "DOUBLE", "DROP", "ENDEXEC", "EQUALS", "ESCAPE", "EXCEPT", "EXCEPTION", "EXECUTE", "EXECUTE", "EXIT", "EXPAND", "EXPANDING", "FALSE", "FIRST", "FLOAT", "FOR", "FOREIGN", "FREE", "FROM", "FUNCTION", "GENERAL", "GET", "GLOBAL", "GOTO", "GROUP", "GROUPING", "HANDLER", "HASH", "HOUR", "IDENTITY", "IF", "IGNORE", "IMMEDIATE", "IN", "INDICATOR", "INITIALIZE", "INITIALLY", "INNER", "INOUT", "INPUT", "INSERT", "INT", "INTEGER", "INTERSECT", "INTERVAL", "INTO", "IS", "ISOLATION", "ITERATE", "JOIN", "KEY", "LANGUAGE", "LARGE", "LAST", "LATERAL", "LEADING", "LEAVE", "LEFT", "LESS", "LEVEL", "LIKE", "LIMIT", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", "LOCATOR", "LOOP", "MATCH", "MEETS", "MINUTE", "MODIFIES", "MODIFY", "MODULE", "MONTH", "NAMES", "NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NEW", "NEXT", "NO", "NONE", "NORMALIZE", "NOT", "NULL", "NUMERIC", "OBJECT", "OF", "OFF", "OLD", "ON", "ONLY", "OPEN", "OPERATION", "OPTION", "OR", "ORDER", "ORDINALITY", "OUT", "OUTER", "USAGE", "USER", "USING", "VALUE", "VALUES", "VARIABLE", "VARYING", "VIEW", "WHEN", "WHENEVER", "WHERE", "WHILE", "WITH", "WRITE", "YEAR", "ZONE" }; for (String word : words) keywords.add(word); } @Override public Result eval(String text, int position, ParserContext ctx) throws ParseException { int i = StringUtil.skipSpaces(text, position); int begin = i; if (text.length() <= begin) throw new BufferUnderflowException(); char c = text.charAt(begin); if (!StringUtil.isAlpha(c) && c != '_') throw new ParseException("initial character must be alphabet", i); i = findEnd(text, i); String token = text.substring(begin, i); if (keywords.contains(token.toUpperCase())) throw new ParseException("reserved keyword", i); // remove trailing spaces i = StringUtil.skipSpaces(text, i); return new Result(new Binding(this, token), i); } private int findEnd(String text, int position) { int i = position; while (i < text.length() && (StringUtil.isAlphaNumeric(text.charAt(i)) || text.charAt(i) == '_')) i++; return i; } @Override public String toString() { return "regular_id"; } }