| /******************************************************************************* | |
| * Copyright (c) 2006, 2007 Ingres Corporation and others. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License 2.0 | |
| * which accompanies this distribution, and is available at | |
| * https://www.eclipse.org/legal/epl-2.0/ | |
| * | |
| * Contributors: | |
| * Ingres Corporation - initial API and implementation | |
| *******************************************************************************/ | |
| options{ | |
| STATIC=false; | |
| MULTI=true; | |
| NODE_DEFAULT_VOID=true; | |
| NODE_SCOPE_HOOK=true; | |
| VISITOR=true; | |
| IGNORE_CASE=true; | |
| } | |
| PARSER_BEGIN(IngresSQLParser) | |
| package org.eclipse.datatools.enablement.ingres.internal.ui.parser; | |
| import java.util.ArrayList; | |
| import java.io.StringReader; | |
| import org.eclipse.datatools.sqltools.sql.parser.SQLParser; | |
| import org.eclipse.datatools.sqltools.sql.parser.ast.Node; | |
| import org.eclipse.datatools.sqltools.sql.parser.ast.SimpleNode; | |
| import org.eclipse.datatools.sqltools.sql.parser.ParseException; | |
| import org.eclipse.datatools.sqltools.sql.parser.SQLParserConstants; | |
| import org.eclipse.datatools.sqltools.sql.parser.JavaCharStream; | |
| import org.eclipse.datatools.sqltools.sql.parser.Token; | |
| import org.eclipse.datatools.sqltools.sql.parser.TokenMgrError; | |
| import org.eclipse.datatools.sqltools.sql.parser.ParsingResult; | |
| import org.eclipse.datatools.sqltools.sql.parser.util.ParserUtil; | |
| import org.eclipse.datatools.sqltools.sql.parser.ParserParameters; | |
| /** | |
| * Ingres SQL parser. | |
| * | |
| * @author stefan.reddig@ingres.com | |
| */ | |
| public class IngresSQLParser extends SQLParser implements SQLParserConstants | |
| { | |
| private static IngresSQLParser _instance = new IngresSQLParser(new StringReader("")); | |
| private boolean _debug = false; | |
| private ParsingResult result = null; | |
| private ArrayList exceptions = new ArrayList(); | |
| private ArrayList knownExceptions = new ArrayList(); | |
| private static final int[] STMT_START = new int[]{ALTER, //BEGIN, | |
| CLOSE, COMMIT, //CONTINUE, | |
| CREATE, | |
| DECLARE, DELETE, | |
| DROP, //DUMP, | |
| EXECUTE, EXEC, | |
| FETCH, //GOTO, GRANT, | |
| IF, INSERT, //KILL, LOAD, | |
| OPEN, PREPARE, //MOUNT, PRINT, | |
| REMOVE,RETURN, REVOKE, ROLLBACK, SAVE, SELECT, SET, | |
| UPDATE, //UNMOUNT, | |
| WHILE | |
| }; | |
| public static final String[] STMT_START_STRING = new String[]{"ALTER",//"BEGIN", | |
| "CLOSE","COMMIT", //"CONTINUE", | |
| "CREATE", | |
| "DECLARE","DELETE", | |
| "DROP",//"DUMP", | |
| "EXECUTE","EXEC", | |
| "FETCH",//"GOTO","GRANT", | |
| "IF","INSERT",//"KILL","LOAD", | |
| "OPEN","PREPARE",//"PRINT", | |
| "REMOVE","RETURN","REVOKE","ROLLBACK","SAVE","SELECT","SET", | |
| "UPDATE", | |
| "WHILE" | |
| }; | |
| private static final int[] DEFINED_STMT_START = new int[]{ALTER, //BEGIN, | |
| CREATE, DECLARE, DELETE, EXECUTE, EXEC, | |
| FETCH, IF, INSERT, //PRINT, | |
| RETURN, SELECT, UPDATE | |
| }; | |
| private static final int[] TERMINATORS = new int[]{GO, SEMICOLON}; | |
| private static final String[] TERMINATORS_STRING = new String[]{"\\g", ";"}; | |
| private static int[] STMT_START_TERMINATORS = new int[STMT_START.length + TERMINATORS.length]; | |
| static | |
| { | |
| System.arraycopy(STMT_START, 0, STMT_START_TERMINATORS, 0, STMT_START.length); | |
| System.arraycopy(TERMINATORS, 0, STMT_START_TERMINATORS, STMT_START.length, TERMINATORS.length); | |
| } | |
| //FIXME do we need this field? | |
| private boolean isContentAssist = true; | |
| /* | |
| * Singleton | |
| */ | |
| public static IngresSQLParser getInstance(){ | |
| return _instance; | |
| } | |
| public IngresSQLParser() | |
| { | |
| } | |
| //Implements JavaCC methods | |
| void jjtreeOpenNodeScope(Node n) | |
| { | |
| ((SimpleNode)n).setFirstToken ( getToken(1)); | |
| } | |
| void jjtreeCloseNodeScope(Node n) | |
| { | |
| ((SimpleNode)n).setLastToken( getToken(0)); | |
| } | |
| //Implements SQLParser abstract methods | |
| /** | |
| * Returns the statement terminator array. Different vendors will have their | |
| * own terminators defined, so we just leave this method as abstract here. | |
| * | |
| * @return statement terminator array | |
| */ | |
| public String[] getStatementTerminators() | |
| { | |
| return TERMINATORS_STRING; | |
| } | |
| /** | |
| * Returns the token strings that can be used to begin a SQL statement. | |
| * | |
| * @return statement start token array | |
| */ | |
| public String[] getStatementStartTokens() | |
| { | |
| return STMT_START_STRING; | |
| } | |
| /** | |
| * Concrete parsers must imlement this method to do the real parsing. | |
| * @param text sql text to be parsed. | |
| * @return <code>ParsingResult</code> containing root AST node and <code>ParseException</code>s. | |
| */ | |
| protected synchronized ParsingResult doParse(String text) | |
| { | |
| java.io.StringReader sr = new java.io.StringReader( text ); | |
| java.io.Reader r = new java.io.BufferedReader( sr ); | |
| //ReInit will be generated by JavaCC | |
| ReInit(r); | |
| initParsing(); | |
| return startIgnoreException(); | |
| } | |
| //Other methods | |
| private ParsingResult startIgnoreException() | |
| { | |
| Node node = new ASTStart(JJTSTART); | |
| try | |
| { | |
| node = startRootIgnoreException(); | |
| }catch (ParseException e) { | |
| exceptions.add(e); | |
| } | |
| catch (TokenMgrError t) | |
| { | |
| ParseException e = new ParseException(t.getMessage()); | |
| if (token == null){ | |
| //when the error token occurs at the beginning | |
| e.currentToken = new Token(); | |
| }else{ | |
| e.currentToken = token; | |
| } | |
| if (t.getToken() != null){ | |
| e.currentToken.next = t.getToken(); | |
| }else{ | |
| Token errtoken = new Token(); | |
| errtoken.beginLine = token.endLine; | |
| errtoken.beginColumn = token.endColumn + 1; | |
| errtoken.endLine = token.endLine; | |
| errtoken.endColumn = token.endColumn + 1; | |
| e.currentToken.next = errtoken; | |
| } | |
| exceptions.add(e); | |
| } | |
| catch (Throwable t) | |
| { | |
| // Activator.getDefault().log(t); | |
| } | |
| Boolean consumeException = (Boolean)getParameters().getProperty(ParserParameters.PARAM_CONSUME_EXCEPTION); | |
| result.setRootNode(node); | |
| if ( consumeException == null || consumeException.booleanValue()) | |
| { | |
| result.setExceptions(knownExceptions); | |
| } | |
| else | |
| { | |
| result.setExceptions(exceptions); | |
| } | |
| return result; | |
| } | |
| private void initParsing(){ | |
| result = new IngresParsingResult(); | |
| exceptions = new ArrayList(); | |
| knownExceptions = new ArrayList(); | |
| } | |
| private boolean isSupportedStatementStartToken(int kind) | |
| { | |
| for (int i=0; i<DEFINED_STMT_START.length; i++) | |
| { | |
| if (kind == DEFINED_STMT_START[i]) | |
| { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| private boolean isStatementStartToken(int kind) | |
| { | |
| for (int i=0; i<STMT_START.length; i++) | |
| { | |
| if (kind == STMT_START[i]) | |
| { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| private boolean isStatementToken(int kind) | |
| { | |
| if (kind == 0 || isStatementStartToken(kind)) | |
| { | |
| return false; | |
| } | |
| for (int i=0; i<TERMINATORS.length; i++) | |
| { | |
| if (kind == TERMINATORS[i]) | |
| { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| private boolean check(String unReservedKeyword) | |
| { | |
| Token currentToken = getToken(1); | |
| int currentTokenKind = currentToken.kind; | |
| String currentTokenImage = currentToken.image; | |
| if (currentTokenKind == ID && currentTokenImage.equalsIgnoreCase(unReservedKeyword)) | |
| { | |
| return true; | |
| } | |
| if (currentTokenKind == INVALID_TOKEN) | |
| { | |
| result.addExpectedUnreservedKeywords(unReservedKeyword); | |
| } | |
| return false; | |
| } | |
| private boolean check(int type, String multiKeyword) | |
| { | |
| return check(type, new String[]{multiKeyword}); | |
| } | |
| /** | |
| *multiKeywords will show as content assist proposal | |
| */ | |
| private boolean check(int type, String[] multiKeywords) | |
| { | |
| Token currentToken = getToken(1); | |
| int currentTokenKind = currentToken.kind; | |
| String currentTokenImage = currentToken.image; | |
| if (currentTokenKind == type) | |
| { | |
| return true; | |
| } | |
| if (currentTokenKind == INVALID_TOKEN) | |
| { | |
| for (int i=0; i< multiKeywords.length; i++) | |
| { | |
| result.addExpectedUnreservedKeywords(multiKeywords[i]); | |
| } | |
| } | |
| return false; | |
| } | |
| final private void logDebug(String message) | |
| { | |
| if (_debug) | |
| { | |
| //Activator.getDefault().log(message); | |
| } | |
| } | |
| } | |
| PARSER_END(IngresSQLParser) | |
| SKIP: | |
| { | |
| " " | |
| | "\n" | |
| | "\r" | |
| | "\t" | |
| | "\f" | |
| } | |
| /* COMMENTS */ | |
| MORE : | |
| { | |
| "--" : IN_SINGLE_LINE_COMMENT | |
| } | |
| <IN_SINGLE_LINE_COMMENT> | |
| SPECIAL_TOKEN : | |
| { | |
| <SINGLE_LINE_COMMENT: "\n" | "\r" | "\r\n" > : DEFAULT | |
| } | |
| <IN_SINGLE_LINE_COMMENT> | |
| MORE : | |
| { | |
| < ~[] > | |
| } | |
| /* | |
| SPECIAL_TOKEN : | |
| { | |
| < SINGLE_LINE_COMMENT: "--"(~["\n","\r"])* ("\n"|"\r"|"\r\n")? > | |
| } | |
| */ | |
| TOKEN_MGR_DECLS : { | |
| int commentNestingDepth = 0 ; | |
| } | |
| MORE : { "/*" { commentNestingDepth = 1 ; } : IN_MULTI_LINE_COMMENT } | |
| < IN_MULTI_LINE_COMMENT > MORE : { "/*" { commentNestingDepth += 1 ; } } | |
| < IN_MULTI_LINE_COMMENT > SPECIAL_TOKEN : { "*/" { | |
| commentNestingDepth -= 1; | |
| SwitchTo( commentNestingDepth==0 ? DEFAULT : IN_MULTI_LINE_COMMENT ); } } | |
| < IN_MULTI_LINE_COMMENT > MORE : { <COMMENT_CONTENT: ~[]> {} } | |
| TOKEN: | |
| { | |
| < INVALID_TOKEN: "!%^&" > //Using token will always causes exception | |
| | < ADD: "add" > | |
| | < ALTER: "alter" > | |
| | < AND: "and" > | |
| | < ANY: "any" > | |
| | < AS: "as" > | |
| | < ASC: "asc" > | |
| | < AT: "at" > | |
| | < AUTHORIZATION: "authorization" > | |
| | < AVG: "avg" > | |
| | < BEGIN: "begin" > | |
| | < BETWEEN: "between" > | |
| | < BY: "by" > | |
| | < CASCADE: "cascade" > | |
| | < CASE: "case" > | |
| | < CHECK: "check" > | |
| | < CHECKPOINT: "checkpoint" > | |
| | < CLOSE: "close" > | |
| | < COALESCE: "coalesce" > | |
| | < COMMIT: "commit" > | |
| | < CONSTRAINT: "constraint" > | |
| | < CONTINUE: "continue" > | |
| | < COUNT: "count" > | |
| | < CREATE: "create" > | |
| | < CURRENT: "current" > | |
| | < CURSOR: "cursor" > | |
| | < DATABASE: "database" > | |
| | < DBEVENT: "dbevent" > | |
| | < DECLARE: "declare" > | |
| | < DEFAULT_VAL: "default" > | |
| | < DELETE: "delete" > | |
| | < DESC: "desc" > | |
| | < DISTINCT: "distinct" > | |
| | < DOMAIN: "domain" > | |
| | < DROP: "drop" > | |
| | < DUMP: "dump" > | |
| | < ELSE: "else" > | |
| | < END: "end" > | |
| | < ESCAPE: "escape" > | |
| | < EXCEPT: "except" > | |
| | < EXCLUSIVE: "exclusive" > | |
| | < EXEC: "exec" > | |
| | < EXECUTE: "execute" > | |
| | < EXISTS: "exists" > | |
| | < FETCH: "fetch" > | |
| | < FILLFACTOR: "fillfactor" > | |
| | < FOR: "for" > | |
| | < FOREIGN: "foreign" > | |
| | < FROM: "from" > | |
| | < FUNC: "func" > | |
| | < FUNCTION: "function" > | |
| | < GO: "\\g" > //terminator | |
| | < GOTO: "goto" > | |
| | < GRANT: "grant" > | |
| | < GROUP: "group" > | |
| | < HAVING: "having" > | |
| | < IF: "if" > | |
| | < IN: "in" > | |
| | < INDEX: "index" > | |
| | < INSERT: "insert" > | |
| | < INTERSECT: "intersect" > | |
| | < INTEGRITY: "integrity" > | |
| | < INTO: "into" > | |
| | < IS: "is" > | |
| | < ISOLATION: "isolation" > | |
| | < JOIN: "join" > | |
| | < KEY: "key" > | |
| | < KILL: "kill" > | |
| | < LEVEL: "level" > | |
| | < LIKE: "like" > | |
| | < LOAD: "load" > | |
| | < LOCATION: "location" > | |
| | < MAX: "max" > | |
| | < MIN: "min" > | |
| | < MODIFY: "modify" > | |
| | < NO: "no" > | |
| | < NOT: "not" > | |
| | < NULL: "null" > | |
| | < NULLIF: "nullif" > | |
| | < OF: "of" > | |
| | < OFF: "off" > | |
| | < ON: "on" > | |
| | < ONLY: "only" > | |
| | < OPEN: "open" > | |
| | < OPTION: "option" > | |
| | < OR: "or" > | |
| | < ORDER: "order" > | |
| | < OUT: "out" > | |
| | < OUTPUT: "output" > | |
| | < PARTITION: "partition" > | |
| | < PERM: "perm" > | |
| | < PERMANENT: "permanent" > | |
| | < PREPARE: "prepare" > | |
| | < PRIMARY: "primary" > | |
| | < PRIVILEGES: "privileges" > | |
| | < PRINT: "print" > | |
| | < PROCEDURE: "procedure" > | |
| | < PROFILE: "profile" > | |
| | < PUBLIC: "public" > | |
| | < READ: "read" > | |
| | < REFERENCES: "references" > | |
| | < REMOVE: "remove" > | |
| | < REORGANIZE: "reorganize" > | |
| | < RETURN: "return" > | |
| | < REVOKE: "revoke" > | |
| | < ROLE: "role" > | |
| | < ROLLBACK: "rollback" > | |
| | < ROWCOUNT: "rowcount" > | |
| | < ROWS: "rows" > | |
| | < RULE: "rule" > | |
| | < SAVE: "save" > | |
| | < SCHEMA: "schema" > | |
| | < SECURITY_AUDIT: "security_audit" > | |
| | < SECURITY_ALARM: "security_alarm" > | |
| | < SELECT: "select" > | |
| | < SEQUENCE: "sequence" > | |
| | < SESSION: "session" > | |
| | < SET: "set" > | |
| | < SHARED: "shared" > | |
| | < SOME: "some" > | |
| | < STATISTICS: "statistics" > | |
| | < SUM: "sum" > | |
| | < SYNONYM: "synonym" > | |
| | < TABLE: "table" > | |
| | < TEMPORARY: "temporary" > | |
| | < TO: "to" > | |
| | < TRANSACTION: "transaction" > | |
| | < UNION: "union" > | |
| | < UNIQUE: "unique" > | |
| | < UNPARTITION: "unpartition" > | |
| | < UPDATE: "update" > | |
| | < USER: "user" > | |
| | < USING: "using" > | |
| | < VALUES: "values" > | |
| | < VARYING: "varying" > | |
| | < VIEW: "view" > | |
| | < WHEN: "when" > | |
| | < WHERE: "where" > | |
| | < WHILE: "while" > | |
| | < WITH: "with" > | |
| | < WORK: "work" > | |
| | < II_DBA: "$dba"> | |
| | < II_INGRES: "$ingres" > | |
| } | |
| /* | |
| <DESCRIPTION_START_STATE> TOKEN: | |
| { | |
| < OPENDESCRIPTION: "\r\n" > : DESCRIPTION_STATE | |
| } | |
| */ | |
| // <DESCRIPTION_STATE> TOKEN: /* Line */ | |
| /* | |
| { | |
| < CLOSEDESCRIPTION: "~" > : DEFAULT | |
| | < DESCRIPTION: (~["~"])* "~" > : DEFAULT | |
| } | |
| */ | |
| TOKEN: /* Literals */ | |
| { | |
| < INTEGER_LITERAL: (["0"-"9"])+ > | |
| | < FLOATING_POINT_LITERAL: | |
| (["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? | |
| | "." (["0"-"9"])+ (<EXPONENT>)? | |
| | (["0"-"9"])+ (<EXPONENT>)? | |
| > | |
| | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | |
| | < SINGLE_STRING_LITERAL: "'" (~["'"])* ( "''" (~["'"])* )* "'" > | |
| | < DOUBLE_STRING_LITERAL: "\"" (~["\""])* ( "\"\"" (~["\""])* )* "\"" > | |
| | < BINARY_LITERAL: "0" ("x" | "X" ) ( <HEXDIGIT> )+ > | |
| | < #HEXDIGIT: ["A"-"F", "a"-"f", "0"-"9"] > | |
| | < MONEY_LITERAL: ("$" | "\u00a5" | "\u00a3" )? <FLOATING_POINT_LITERAL> > | |
| } | |
| Token string_literal() : {Token t;} | |
| { | |
| ( t = <SINGLE_STRING_LITERAL> | t = <DOUBLE_STRING_LITERAL> ) | |
| {return t;} | |
| } | |
| TOKEN: /* Identifiers */ | |
| { | |
| < ID: ( <LETTER> | "_" )+ ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )* > | |
| | < SQUARE_BRACKET_ID: ("[" <ID> "]")> | |
| | < #VAR_NAME_BODY: ( <SYMBOL> | <DIGIT> | <LETTER> | "#" )+ ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )* > | |
| | < VAR_NAME: "@"<VAR_NAME_BODY> > | |
| | < LABEL: <ID>":" > | |
| | < GLOBAL_VAR_NAME: "@@"<VAR_NAME_BODY> > | |
| | < TEMP_TABLE_NAME: "#" ( <SYMBOL> | <DIGIT> | <LETTER> | "#" | "@" )+ > | |
| /*FIXME: Unicode code point ranges from 0000 to 10ffff, but JavaCC seems only recognize four digits following "u". Not sure what the consequence will be for now.*/ | |
| // | < #LETTER: ["A"-"Z", "a"-"z", "\u0080"-"\uffff"] > //Umlaute?!? | |
| | < #LETTER: ["A"-"Z", "a"-"z", "ä", "Ä", "ö", "Ö", "ü", "Ü","ß","\u0080"-"\uffff"] > | |
| | < #DIGIT: ["0"-"9"] > | |
| | < #SYMBOL: ["$","_"] > | |
| } | |
| TOKEN: /* Ingres specific Identifiers */ | |
| { | |
| //32chars max, unique til 24.char | |
| //start with letter or "_", contain "#", "@", "$", digits, no keywords | |
| //delimited-> "", additional: keywords, specsymb | |
| < #SPECSYMB: | |
| ["&", "*", "@", ":", ",", "#", "=", "/", "<", ">", "(", ")", "-", "%", ".", "+", "?", | |
| "'"," ", "_", "|", "\\","^", "{", "}", "!", "~"]> //+ASCII96, never ASCII127 aka DEL | |
| |< #DELIM_START: ( <SPECSYMB> | <DIGIT> | <LETTER> )* > //no $ allowed | |
| |< #DELIM_PART: ( <SPECSYMB> | <DIGIT> | <LETTER> | "$" )* > | |
| |< DELIM_IDENT: "\"" ( <DELIM_START> )* ("\"\"" (<DELIM_PART>)* )* "\""> | |
| } | |
| TOKEN: /* Separators and operators */ | |
| { | |
| < CONCAT: "||" > | |
| | < COMMA: "," > | |
| | < SEMICOLON: ";" > | |
| | < DOT: "." > | |
| | < ROWTYPE: "%rowtype" > | |
| | < TILDE: "~" > | |
| | < LESS: "<" > | |
| | < LESSEQUAL: "<=" > | |
| | < GREATER: ">" > | |
| | < GREATEREQUAL: ">=" > | |
| | < EQUAL: "=" > | |
| | < NOTEQUAL: "!=" > | |
| | < JOINPLUS: "(+)" > | |
| | < OPENPAREN: "(" > | |
| | < CLOSEPAREN: ")" > | |
| | < ASTERISK: "*" > | |
| | < SLASH: "/" > | |
| | < PLUS: "+" > | |
| | < MINUS: "-" > | |
| | < QUESTIONMARK: "?" > | |
| | < LEQJOIN: "*="> //FIXME: | |
| | < REQJOIN: "=*"> | |
| | < JAVA_REF: ">>"> | |
| } | |
| /******************************************************************* | |
| * Unreserved Keywords | |
| *******************************************************************/ | |
| Token UK_ABSOLUTE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("absolute")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_AFTER() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("after")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_ALL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("all")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_BIGINT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("bigint")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_BINARY() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("binary")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_BEFORE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("before")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_BIT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("bit")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_BOOLEAN() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("boolean")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_CHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("char")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_CHAR_S() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("character")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_DATE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("date")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_DATETIME() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("datetime")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_DB2SQL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("db2sql")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_DECIMAL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("decimal")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_DECIMAL_S() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("dec")}) t = <ID> ) | |
| {return t;} | |
| } | |
| TOKEN:{ < UK_DOUBLE_PRECISION: "double" ("\t"|" "|"\r"|"\n")+ "precision"> } | |
| Token UK_DOUBLE_PRECISION() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( UK_DOUBLE_PRECISION, "double precision")}) t = <UK_DOUBLE_PRECISION> ) | |
| {return t;} | |
| } | |
| Token UK_EACH() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("each")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FALSE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("false")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FIRST() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("first")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FLOAT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("float")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FLOAT4() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("float4")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FLOAT8() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("float8")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_FULL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("full")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_IMAGE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("image")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INNER() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( "inner")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INSENSITIVE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("insensitive")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("integer")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INT1() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("integer1")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INT2() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("integer2")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INT4() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("integer4")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_INT8() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("integer8")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_LAST() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("last")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_LEFT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("left")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_MODE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("mode")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_MONEY() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("money")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NAME() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("name")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NCHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("nchar")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NEXT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("next")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NEW() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("new")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NEW_TABLE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("new_table")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NONE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("none")}) t = <ID> ) | |
| {return t;} | |
| } | |
| TOKEN:{ < UK_NO_SCROLL: "no" ("\t"|" "|"\r"|"\n")+ "scroll"> } | |
| Token UK_NO_SCROLL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( UK_NO_SCROLL, "no scroll")}) t = <UK_NO_SCROLL> ) | |
| {return t;} | |
| } | |
| Token UK_NUMERIC() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("numeric")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_NVARCHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("nvarchar")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_OF() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("of")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_OLD() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("old")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_OLD_TABLE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("old_table")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_OUTER() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("outer")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_PRIOR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("prior")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_REAL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("real")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_REFERENCING() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("referencing")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_RELATIVE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("relative")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_RESULT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("result")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_RIGHT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("right")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_ROW() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("row")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_SCROLL() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("scroll")}) t = <ID> ) | |
| {return t;} | |
| } | |
| TOKEN:{ < UK_SEMI_SENSITIVE: "semi" ("\t"|" "|"\r"|"\n")+ "sensitive"> } | |
| Token UK_SEMI_SENSITIVE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( UK_SEMI_SENSITIVE, "semi sensitive")}) t = <UK_SEMI_SENSITIVE> ) | |
| {return t;} | |
| } | |
| Token UK_SMALLDATETIME() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("smalldatetime")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_SMALLINT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("smallint")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_SMALLMONEY() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("smallmoney")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_STATEMENT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("statement")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_TEXT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("text")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_THEN() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("then")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_TIME() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("time")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_TIMESTAMP() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("timestamp")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_TINYINT() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("tinyint")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_TRUE() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("true")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_UNICHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("unichar")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_UNIVARCHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("univarchar")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_VARBINARY() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("varbinary")}) t = <ID> ) | |
| {return t;} | |
| } | |
| Token UK_VARCHAR() : {Token t;} | |
| { | |
| (LOOKAHEAD({check("varchar")}) t = <ID> ) | |
| {return t;} | |
| } | |
| TOKEN:{ < UK_VARCHAR_S: "char" ("\t"|" "|"\r"|"\n")+ "varying"> } | |
| Token UK_VARCHAR_S() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( UK_VARCHAR_S, "char varying")}) t = <UK_VARCHAR_S> ) | |
| {return t;} | |
| } | |
| TOKEN:{ < UK_VARCHAR_S1: "character" ("\t"|" "|"\r"|"\n")+ "varying"> } | |
| Token UK_VARCHAR_S1() : {Token t;} | |
| { | |
| (LOOKAHEAD({check( UK_VARCHAR_S1, "character varying")}) t = <UK_VARCHAR_S1> ) | |
| {return t;} | |
| } | |
| /** | |
| * Ignore exception during parsing so that the rest part can be parsed | |
| * rule: [ delimiter()] ( statement() )* <EOF> | |
| */ | |
| Node startRootIgnoreException() #Start: {} | |
| { | |
| ( | |
| [ delimiter()] | |
| ( | |
| try{ | |
| statement() | |
| }catch (ParseException e) { | |
| //TODO can we create an UnknownStatement? | |
| exceptions.add(e); | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| } catch (Throwable t) { | |
| //TODO: handle this throwable separately in SQLEditor:setOutlineContent. | |
| ParseException e = new ParseException(ParserUtil.getErrorMessage(getToken(0))); | |
| e.currentToken = getToken(0); | |
| exceptions.add(e); | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| } | |
| )* <EOF> | |
| ) | |
| { return jjtThis; } | |
| } | |
| ASTSQLDelimiter delimiter() #SQLDelimiter:{} | |
| { | |
| (LOOKAHEAD(2) (<SEMICOLON>|<GO>))+ | |
| { | |
| return jjtThis; | |
| } | |
| } | |
| void statement() : {setScope("SQL Statement", SCOPE_DEFAULT);/*the default scope*/result.clearCurrentTableNames(isContentAssist);} | |
| { | |
| try{ | |
| ( | |
| ( | |
| LOOKAHEAD( <CREATE> ) create_stmts() | |
| | LOOKAHEAD( <ALTER> ) alter_stmts() | |
| | LOOKAHEAD( <DROP> ) drop_stmts() | |
| | LOOKAHEAD( <INSERT> ) insert_stmts() | |
| | LOOKAHEAD( <UPDATE> ) update_stmts() | |
| | LOOKAHEAD( <SELECT> ) select() | |
| | LOOKAHEAD( <DELETE> ) delete_stmts() | |
| | LOOKAHEAD( <REMOVE> ) remove_stmts() | |
| | LOOKAHEAD(1) return_stmt() | |
| | LOOKAHEAD(2) execute_stmt() | |
| | LOOKAHEAD(1) if_stmt() | |
| | LOOKAHEAD(1) print() | |
| | LOOKAHEAD(1) unknown_sql_stmt() | |
| ) #SQLStatement | |
| | LOOKAHEAD(1) declare() | |
| ) | |
| [LOOKAHEAD(<SEMICOLON>|<GO>) delimiter()] | |
| }catch(ParseException e){ | |
| exceptions.add(e); | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| //to generate an ASTSQLDelimiter node so that the statement can be separated | |
| if (getToken(1).kind == SEMICOLON ) | |
| { | |
| delimiter(); | |
| } | |
| } catch (Throwable t) { | |
| //TODO: handle this throwable separately in SQLEditor:setOutlineContent. | |
| ParseException e = new ParseException(ParserUtil.getErrorMessage(getToken(0))); | |
| e.currentToken = getToken(0); | |
| exceptions.add(e); | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| if ( getToken(1).kind == SEMICOLON ) | |
| { | |
| delimiter(); | |
| } | |
| } | |
| { | |
| } | |
| } | |
| void unknown_sql_stmt() : {} | |
| { | |
| LOOKAHEAD({ !isSupportedStatementStartToken(getToken(1).kind) }) | |
| ( | |
| <CLOSE> | <COMMIT> | <CONTINUE> | <DECLARE> | <DUMP> | <EXEC> | | |
| <GOTO> | <GRANT> | <KILL> | <LOAD> | <MODIFY> | <OPEN> | <PREPARE> | | |
| <RETURN> | <REVOKE> |<ROLLBACK> | <SAVE> | <SET> | <WHILE> | <ID> | |
| ) | |
| { | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| } | |
| } | |
| void any_stmt_token():{} | |
| { | |
| { | |
| error_skiptobefore(new int[]{END}, STMT_START_TERMINATORS); | |
| } | |
| } | |
| void create_stmts() : {} | |
| { | |
| LOOKAHEAD(2) <CREATE> <PROCEDURE> create_proc_body() | |
| | LOOKAHEAD(2) <CREATE> | |
| (<DBEVENT> | |
| |<GROUP> | |
| |unique() <INDEX> | |
| |<INTEGRITY> | |
| |<LOCATION> | |
| |<PROFILE> | |
| |<ROLE> | |
| |<SCHEMA> | |
| |<SECURITY_ALARM> | |
| |<SEQUENCE> | |
| |<SYNONYM> | |
| |<TABLE> | |
| |<USER> | |
| |<VIEW> | |
| ) | |
| any_stmt_token() | |
| } | |
| void create_proc_body() : {} | |
| { | |
| <ID> | |
| [cdbp_parmspec()] [cdbp_resrowspec()] | |
| (<AS>|<EQUAL>) cdbp_beblock() | |
| } | |
| void cdbp_parmspec() : {} | |
| { | |
| <OPENPAREN> cdbp_parmlist() <CLOSEPAREN> | |
| } | |
| void cdbp_parmlist() : {} | |
| { | |
| cdbp_parmitem() (<COMMA> cdbp_parmitem())* | |
| } | |
| void cdbp_parmitem() : {} | |
| { | |
| <ID> [<EQUAL>] datatype() //ID zuwenig -> lokale Vars bei dynSQL :ID | |
| ( (<WITH>|<NOT>) (<DEFAULT_VAL>|<NULL>) )* //FIXME: "default" und "null" sollen nur je 1x auftreten | |
| } | |
| void cdbp_resrowspec() : {} | |
| { | |
| UK_RESULT() UK_ROW() | |
| ( | |
| datatype() | |
| ( (<WITH>|<NOT>) (<DEFAULT_VAL>|<NULL>) )* | |
| )+ | |
| } | |
| void cdbp_beblock() : {} | |
| { | |
| [declare()] <BEGIN> (statement())+ <END> | |
| } | |
| void unique() : {} | |
| { | |
| [ <UNIQUE> ] | |
| } | |
| void alter_stmts() : {} | |
| { | |
| <ALTER> | |
| (<GROUP> | |
| |<LOCATION> | |
| |<PROFILE> | |
| |<ROLE> | |
| |<SECURITY_AUDIT> | |
| |<SEQUENCE> | |
| |<TABLE> | |
| |<USER> | |
| ) | |
| any_stmt_token() | |
| } | |
| void drop_stmts() : {} | |
| { | |
| LOOKAHEAD(2) <DROP> <PROCEDURE> <ID> | |
| |LOOKAHEAD (2)<DROP> | |
| (<DBEVENT> | |
| |<DOMAIN> | |
| |<GROUP> | |
| |<INDEX> | |
| |<INTEGRITY> | |
| |<LOCATION> | |
| |<PROFILE> | |
| |<ROLE> | |
| |<RULE> | |
| |<SECURITY_ALARM> | |
| |<SEQUENCE> | |
| |<SYNONYM> | |
| |<TABLE> | |
| |<USER> | |
| |<VIEW> | |
| |<ID> | |
| ) | |
| any_stmt_token() | |
| } | |
| void delete_stmts() : {} | |
| { | |
| delete() | |
| } | |
| void insert_stmts() : {} | |
| { | |
| insert() | |
| } | |
| void update_stmts() : {} | |
| { | |
| update() | |
| } | |
| void remove_stmts() : {} | |
| { | |
| <REMOVE> | |
| (<DBEVENT> | |
| |<TABLE> | |
| ) | |
| any_stmt_token() | |
| } | |
| ASTSQLDataType datatype() #SQLDataType: {} | |
| { | |
| ( | |
| base_datatype() | |
| ) | |
| {return jjtThis;} | |
| } | |
| ASTSQLDataType base_datatype() #SQLDataType: {Token t= null; int length=0, scale=-1; String name=null; } | |
| { | |
| try{ | |
| ( | |
| ( t = UK_CHAR() | t = UK_CHAR_S() | t = UK_TEXT() | UK_VARCHAR() ) [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | t = UK_NCHAR() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | t = UK_NVARCHAR() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | ( t = UK_TINYINT() | t = UK_SMALLINT() | t = UK_INT() | t = UK_BIGINT() ) | |
| | ( t = UK_INT1() | t = UK_INT2() | t = UK_INT4() | t = UK_INT8() ) | |
| | ( t = UK_NUMERIC() | t = UK_DECIMAL() | t = UK_DECIMAL_S() ) | |
| [ LOOKAHEAD(2) "(" length = number() [ "," scale = number() ] ")" | |
| { | |
| if ((length < scale)) | |
| { | |
| ParseException e = new ParseException("You must specify a scale that is less than or equal to the size"); | |
| e.currentToken = t.next; | |
| exceptions.add(e); | |
| } | |
| } | |
| ] | |
| | t = UK_FLOAT() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | t = UK_DOUBLE_PRECISION() | |
| | t = UK_FLOAT4() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | t = UK_FLOAT8() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| | t = UK_REAL() | |
| | t = UK_DATE() | |
| | t = UK_MONEY() | |
| // TODO: | |
| // logical types | |
| // byte, byte varying, long varchar, long byte | |
| // | t = UK_BINARY() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| // | t = UK_BIT() | |
| // | t = UK_DATETIME() | |
| // | t = UK_SMALLDATETIME() | |
| // | t = UK_SMALLMONEY() | |
| // | t = UK_TIMESTAMP() | |
| // | t = UK_TIME() | |
| // | t = UK_UNICHAR()[ LOOKAHEAD(2) "(" length = number() ")" ] | |
| // | t = UK_UNIVARCHAR()[ LOOKAHEAD(2) "(" length = number() ")" ] | |
| // | t = UK_VARBINARY() [ LOOKAHEAD(2) "(" length = number() ")" ] | |
| // | name = java_name() [ LOOKAHEAD(2) "(" length = number() ")" ] //TODO: retrieve user defined datatype from ASE system table | |
| ) | |
| { | |
| if (t != null ) | |
| { | |
| ((ASTSQLDataType)jjtThis).setName(t.image); | |
| }else{ | |
| ((ASTSQLDataType)jjtThis).setName(name); | |
| } | |
| ((ASTSQLDataType)jjtThis).setLength(length); | |
| ((ASTSQLDataType)jjtThis).setScale(scale); | |
| return jjtThis; | |
| } | |
| }catch(ParseException e){ | |
| exceptions.add(e); | |
| return jjtThis; | |
| } | |
| } | |
| //not needed, if not in DataTypes | |
| String java_name() : {Token t = null; String wholename = null; String part = null;} | |
| { | |
| t = id_or_string() {wholename = t.image;} [LOOKAHEAD(2) "." part = java_name() {wholename += "." + part;} ] | |
| {return wholename;} | |
| } | |
| void insert() : {setScope("insert", SCOPE_TABLES);} | |
| { | |
| <INSERT> <INTO> ii_obj_spec() {setScope("insert", SCOPE_COLUMNS);} | |
| optional_insert_col_list() insert_source() | |
| } | |
| void optional_insert_col_list() : {} | |
| { | |
| [ LOOKAHEAD(2) "(" insert_column_list() ")" ] | |
| } | |
| void insert_column_list() : {} | |
| { | |
| ii_col_spec() | |
| ( "," ii_col_spec() )* | |
| } | |
| void insert_source() : {} | |
| { | |
| <VALUES> "(" insert_values() ")" | |
| | select() | |
| } | |
| void insert_values() : {} | |
| { | |
| [ insert_value_list()] | |
| } | |
| void insert_value_list() : {} | |
| { | |
| insert_value() | |
| ( "," insert_value() )* | |
| } | |
| void insert_value() : {} | |
| { | |
| expression() | |
| | <DEFAULT_VAL> | |
| } | |
| void update() : {} | |
| { | |
| <UPDATE> | |
| {setScope("update", SCOPE_TABLES);} ii_obj_spec() | |
| <SET> | |
| {setScope("update", SCOPE_COLUMNS);} set_clause_list() | |
| {setScope("update", SCOPE_TABLES);} from_where_clause() | |
| } | |
| void set_clause_list() : {} | |
| { | |
| set_clause() | |
| ( "," set_clause() )* | |
| } | |
| void set_clause() : {} | |
| { | |
| ( | |
| LOOKAHEAD(3) primary() | |
| | variable_assignment() | |
| ) | |
| "=" expression() | |
| } | |
| void select() : {} | |
| { | |
| query_expression() order_by_clause() | |
| } | |
| void query_expression() : {} | |
| { | |
| query_term() ( <UNION> all_option() query_term() )* | |
| } | |
| void query_term() : {} | |
| { | |
| query_primary() | |
| } | |
| void all_option() : {} | |
| { | |
| [ UK_ALL() ] | |
| } | |
| void query_primary() : {} | |
| { | |
| simple_table() | |
| | "(" query_expression() ")" | |
| } | |
| void simple_table() : {} | |
| { | |
| query_specification() | |
| } | |
| void query_specification() : {} | |
| { | |
| <SELECT> all_distinct() | |
| {setScope("query_specification", SCOPE_COLUMNS);} select_list() | |
| {setScope("query_specification", SCOPE_TABLES);} | |
| optional_from_clause() [ where_clause() ] group_by_clause() having_clause() | |
| } | |
| void all_distinct() : {} | |
| { | |
| [ UK_ALL() | |
| | <DISTINCT> ] | |
| } | |
| void delete() : {setScope("delete", SCOPE_TABLES);} | |
| { | |
| <DELETE> <FROM> ii_tbl_spec() | |
| [where_clause()] | |
| } | |
| void subquery() : {} | |
| { | |
| "(" subquery_content() ")" | |
| } | |
| void subquery_content() #SQLStatement: {} | |
| { | |
| <SELECT> subq_select() | |
| {} | |
| } | |
| void subq_select() : {} | |
| { | |
| [ subq_all_distinct() subquery_select_expression() | |
| optional_from_clause() | |
| [ where_clause() ] | |
| group_by_clause() having_clause() subq_fake_union() subq_fake_order_by_clause() ] | |
| } | |
| void subq_all_distinct() : {} | |
| { | |
| [ UK_ALL() | |
| | <DISTINCT> ] | |
| } | |
| void subq_fake_union() : {} | |
| { | |
| [ <UNION> subq_fake_select() ] | |
| } | |
| void subq_fake_select() : {} | |
| { | |
| [ LOOKAHEAD(2) subq_fake_primary() <UNION> ] subq_fake_primary() | |
| } | |
| void subq_fake_primary() : {} | |
| { | |
| <SELECT> subq_fake_all_distinct() subq_fake_select_expression() | |
| optional_from_clause() | |
| [ where_clause() ] | |
| group_by_clause() having_clause() | |
| } | |
| void subq_fake_all_distinct() : {} | |
| { | |
| [ UK_ALL() | |
| | <DISTINCT> ] | |
| } | |
| void subq_fake_select_expression() : {} | |
| { | |
| LOOKAHEAD(2) subq_expression_list() | |
| | [ ii_schema_spec() ] "*" | |
| } | |
| void subq_fake_order_by_clause() : {} | |
| { | |
| [ <ORDER> <BY> subq_fake_order_by_list() ] | |
| } | |
| void subq_fake_order_by_list() : {} | |
| { | |
| subq_fake_order_by_item() | |
| ( "," subq_fake_order_by_item() )* | |
| } | |
| void subq_fake_order_by_item() : {} | |
| { | |
| expression() [ order_by_option() ] | |
| } | |
| void subq_fake_cursor_update_list() : {} | |
| { | |
| [ <OF> subq_fake_cursor_column_list()] | |
| } | |
| void subq_fake_cursor_column_list() : {} | |
| { | |
| subq_fake_curs_upd_column() | |
| ( "," subq_fake_curs_upd_column() )* | |
| } | |
| void subq_fake_curs_upd_column() : {} | |
| { | |
| ii_obj_spec() | |
| } | |
| void compound_statement() : {} | |
| { | |
| <BEGIN> nullprogram() <END> | |
| } | |
| void nullprogram() : {} | |
| { | |
| [ program() ] | |
| } | |
| void program() : {} | |
| { | |
| ( statement() )+ | |
| } | |
| void declare() : {} | |
| { | |
| {int oldScope = setScope(SCOPE_DEFINE_VARIABLES);} | |
| declare_prefix() declaration_list() | |
| {setScope(oldScope);} | |
| } | |
| void declare_prefix() #DeclareKeyword : {} | |
| { | |
| <DECLARE> | |
| } | |
| void fetch_orientation() : {} | |
| { | |
| //Though weird, FIRST can be used as object name, so LOOKAHEAD(2) | |
| <FETCH> [LOOKAHEAD( UK_NEXT() | UK_PRIOR() | UK_FIRST() | UK_LAST() | UK_ABSOLUTE() | UK_RELATIVE(), | |
| {getToken(2).kind != INTO && getToken(2).kind != FROM} ) | |
| ( UK_NEXT() | UK_PRIOR() | UK_FIRST() | UK_LAST() | UK_ABSOLUTE() | UK_RELATIVE() ) | |
| ] | |
| } | |
| void fetch_val_spec() : {Token t=null;} | |
| { | |
| [ t = <VAR_NAME> | |
| | number()] | |
| } | |
| void fetch_into_clause() : {} | |
| { | |
| [ <INTO> fetch_into_list()] | |
| } | |
| void fetch_into_list() : {} | |
| { | |
| variable_assignment() | |
| ( "," variable_assignment() )* | |
| } | |
| void fetch_from_spec() : {} | |
| { | |
| [ <FROM> ] | |
| } | |
| void return_stmt() : {} | |
| { | |
| <RETURN> optional_expression() | |
| } | |
| void execute_stmt() : {} | |
| { | |
| <EXECUTE> <PROCEDURE> any_stmt_token() | |
| } | |
| void optional_expression() : {} | |
| { | |
| [ LOOKAHEAD(2) expression()] | |
| } | |
| void if_stmt() : {} | |
| { | |
| (if_prefix() statement() [ LOOKAHEAD(1) <ELSE> statement() ]) | |
| } | |
| void if_prefix() : {} | |
| { | |
| <IF> boolean_expression() | |
| } | |
| void begin_tran() : {} | |
| { | |
| <BEGIN> <TRANSACTION> optional_xact_name() | |
| } | |
| void commit_tran() : {} | |
| { | |
| <COMMIT> tran_or_work() optional_xact_name() | |
| } | |
| void tran_or_work() : {} | |
| { | |
| [ <TRANSACTION> | |
| | <WORK> ] | |
| } | |
| void rollback_tran() : {} | |
| { | |
| <ROLLBACK> tran_or_work() optional_xact_name() | |
| } | |
| void optional_xact_name() : {} | |
| { | |
| [ LOOKAHEAD(2) xact_name()] | |
| } | |
| void xact_name() : {} | |
| { | |
| <INTEGER_LITERAL> ":" <ID> "." <ID> | |
| | id() | |
| } | |
| void print() : {} | |
| { | |
| <PRINT> pr_arglist() | |
| } | |
| void pr_arglist() : {} | |
| { | |
| printstring() arglist() | |
| } | |
| void arglist() : {} | |
| { | |
| ( "," literal() )* | |
| } | |
| void printstring() : {} | |
| { | |
| string_literal() | |
| | variable() | |
| | null_stmt() | |
| } | |
| Token id_or_string() : {Token t;} | |
| { | |
| ( t = idplus() | |
| | t = string_literal() | |
| ) | |
| {return t;} | |
| } | |
| //Special case: "NEW" can be used as id | |
| Token idplus() : {Token t;} | |
| { | |
| ( t = <ID> | |
| | t = <TEMP_TABLE_NAME> //TEMP_TABLE_NAME can also be used as column name | |
| | t = <SQUARE_BRACKET_ID> | |
| ) | |
| {return t;} | |
| } | |
| void select_list() : {} | |
| { | |
| select_expression() | |
| ( "," select_expression() )* | |
| } | |
| void select_expression() : {} | |
| { | |
| LOOKAHEAD(<VAR_NAME> "=") ( select_or_set_variable_assignment()) | |
| | LOOKAHEAD(idplus() "=") idplus() "=" ( expression() ) | |
| | LOOKAHEAD(string_literal() "=") string_literal() "=" ( expression()) | |
| // | "*" | |
| | LOOKAHEAD([ii_schema_spec()] "*") [ii_schema_spec()] "*" | |
| | LOOKAHEAD(expression()) ( expression()) | |
| [ | |
| LOOKAHEAD(2) | |
| ( LOOKAHEAD(2)( optional_as() ( idplus() | string_literal() ) ) | |
| | "=" expression() | |
| ) | |
| ] | |
| //we have put java_memberref support in expression() | |
| //| java_memberref() "=" expression() | |
| } | |
| void select_or_set_variable_assignment() : {} | |
| { | |
| variable_assignment() "=" expression() | |
| } | |
| void optional_as() : {} | |
| { | |
| [ <AS> ] | |
| } | |
| void subquery_select_expression() : {} | |
| { | |
| LOOKAHEAD(3) subq_expression_list() | |
| | [ ii_schema_spec() ] "*" | |
| } | |
| void declaration_list() : {} | |
| { | |
| declaration() | |
| ( comma() declaration() )* | |
| } | |
| void comma() #DeclareComma : {} | |
| { | |
| "," | |
| } | |
| void declaration() #SQLParam: {Token name=null; String defaultValue=null; Node type=null; int direction = 0;} | |
| { | |
| try{ | |
| name = <VAR_NAME> | |
| type = base_datatype() | |
| defaultValue = optional_param_default() | |
| direction = param_options() | |
| }catch(ParseException e){ | |
| exceptions.add(e); | |
| error_skiptobefore(new int[]{}, new int[]{COMMA, CLOSEPAREN, WITH, AS}); | |
| } | |
| { | |
| ((ASTSQLParam)jjtThis).setName(name.image); | |
| ((ASTSQLParam)jjtThis).setType(type.toString()); | |
| ((ASTSQLParam)jjtThis).setTypeObject((ASTSQLDataType)type); | |
| if (defaultValue != null){ | |
| ((ASTSQLParam)jjtThis).setDefaultValue(defaultValue); | |
| } | |
| ((ASTSQLParam)jjtThis).setDirection(direction); | |
| } | |
| } | |
| String optional_param_default() : {String t = null;} | |
| { | |
| [ "=" t = literal()] | |
| {return t;} | |
| } | |
| int param_options() : {int direction = 0;} | |
| { | |
| [ <IN> | |
| | out_option() {direction = 1;}] | |
| {return direction;} | |
| } | |
| void out_option() : {} | |
| { | |
| <OUT> | |
| | <OUTPUT> | |
| } | |
| void shared() : {} | |
| { | |
| [ <SHARED> ] | |
| } | |
| void forceoptions() : {} | |
| { | |
| [ LOOKAHEAD(2) | |
| "(" | |
| [ LOOKAHEAD(2) | |
| <INTEGER_LITERAL> [ LOOKAHEAD(2) forceoption_terms() ] | |
| | <PARTITION> <ID> | |
| | forceoption_terms() | |
| ] | |
| ")" | |
| ] | |
| } | |
| void forceoption_terms() : {} | |
| { | |
| ( forceoption_term() )+ | |
| } | |
| void forceoption_term() : {} | |
| { | |
| forceindex() | |
| | forcestrategy() | |
| } | |
| void forceindex() : {} | |
| { | |
| <INDEX> ( <INTEGER_LITERAL> | idplus() ) | |
| } | |
| void forcestrategy() : {} | |
| { | |
| <ID> [ number() ] | |
| | "(" <ID> ( <ID> ")" | number() number() ")" ) | |
| } | |
| void inner_join() : {} | |
| { | |
| [UK_INNER()] <JOIN> | |
| } | |
| void oj_operator() : {} | |
| { | |
| UK_LEFT() [UK_OUTER()] <JOIN> | |
| | UK_RIGHT() [UK_OUTER()] <JOIN> | |
| | inner_join() | |
| } | |
| void from_where_clause() : {} | |
| { | |
| [ LOOKAHEAD(2) <WHERE> <CURRENT> <OF> ii_obj_spec() | |
| | from_clause() [ where_clause() ] | |
| | where_clause() ] | |
| } | |
| void where_current_clause() : {} | |
| { | |
| [ LOOKAHEAD(2) <WHERE> <CURRENT> <OF> ii_obj_spec() | |
| | where_clause() ] | |
| } | |
| void from_clause() : {} | |
| { | |
| <FROM> | |
| from_list() | |
| } | |
| void optional_from_clause() : {} | |
| { | |
| [ from_clause() ] | |
| } | |
| void from_list() : {} | |
| { | |
| from_table() | |
| ( "," from_table() {} )* | |
| } | |
| void from_table() : {} | |
| { | |
| {setScope("from_clause", SCOPE_TABLES);} | |
| from_item() | |
| {setScope("from_clause", SCOPE_DEFAULT);} | |
| } | |
| void from_item() : {} | |
| { | |
| ( | |
| LOOKAHEAD(from_unit()) from_unit() | |
| ( | |
| LOOKAHEAD(2) oj_operator() from_unit() <ON> | |
| {setScope("from_item", SCOPE_COLUMNS);} | |
| boolean_expression() | |
| )* | |
| | LOOKAHEAD(3) "(" from_unit() | |
| ( | |
| LOOKAHEAD(2) oj_operator() from_unit() <ON> boolean_expression() | |
| )+ ")" | |
| ) | |
| } | |
| void from_unit() : {} | |
| { | |
| ( ii_obj_spec() | |
| ( [LOOKAHEAD({(getToken(1).kind == AS || getToken(1).kind == ID) | |
| && !(getToken(1).image.equalsIgnoreCase("inner") | |
| || getToken(1).image.equalsIgnoreCase("left") | |
| || getToken(1).image.equalsIgnoreCase("right")) | |
| }) | |
| optional_as() idplus() ] | |
| forceoptions() shared() | |
| ) | |
| | "(" select() ")" optional_as() derived_table_name() optional_derived_col_name_list() shared() | |
| ) | |
| } | |
| void derived_table_name() : {} | |
| { | |
| [LOOKAHEAD({!(getToken(1).image.equalsIgnoreCase("inner") || getToken(1).image.equalsIgnoreCase("left") || getToken(1).image.equalsIgnoreCase("right"))}) idplus()] | |
| } | |
| void optional_derived_col_name_list() : {} | |
| { | |
| [LOOKAHEAD(2) "(" derived_column_list() ")"] | |
| } | |
| void derived_column_list() : {} | |
| { | |
| derived_col_name() ("," derived_col_name() )* | |
| } | |
| void derived_col_name() : {} | |
| { | |
| idplus() | |
| } | |
| void where_clause() : {setScope("from_clause", SCOPE_COLUMNS);} | |
| { | |
| <WHERE> boolean_expression() | |
| {setScope("where_clause", SCOPE_DEFAULT);} | |
| } | |
| void boolean_expression() : {} | |
| { | |
| boolean_term() ( <OR> boolean_term() )* | |
| } | |
| void boolean_term() : {} | |
| { | |
| boolean_factor() ( <AND> boolean_factor() )* | |
| } | |
| void boolean_factor() : {} | |
| { | |
| boolean_primary() | |
| | <NOT> boolean_primary() | |
| } | |
| void boolean_primary() : {} | |
| { | |
| boolean_function() | |
| | LOOKAHEAD ("(" boolean_expression() ")" ) "(" boolean_expression() ")" | |
| | predicate() | |
| } | |
| void group_by_clause() : {} | |
| { | |
| [ <GROUP> <BY> by_all() group_by_list() ] | |
| } | |
| void by_all() : {} | |
| { | |
| [ UK_ALL() ] | |
| } | |
| void group_by_list() : {} | |
| { | |
| group_by_item() | |
| ( "," group_by_item() )* | |
| } | |
| void group_by_item() : {} | |
| { | |
| {setScope("group_clause", SCOPE_COLUMNS);} | |
| expression() | |
| {setScope("group_clause", SCOPE_DEFAULT);} | |
| } | |
| void having_clause() : {} | |
| { | |
| [ <HAVING> {setScope("having_clause", SCOPE_COLUMNS);} boolean_expression() {setScope("having_clause", SCOPE_DEFAULT);}] | |
| } | |
| void order_by_clause() : {} | |
| { | |
| [ <ORDER> <BY> order_by_list() ] | |
| } | |
| void order_by_list() : {} | |
| { | |
| order_by_item() | |
| ( "," order_by_item() )* | |
| } | |
| void order_by_item() : {setScope("order_by_clause", SCOPE_COLUMNS);} | |
| { | |
| expression() [ order_by_option() ]{setScope("order_by_clause", SCOPE_DEFAULT);} | |
| } | |
| void order_by_option() : {} | |
| { | |
| <ASC> | |
| | <DESC> | |
| } | |
| void predicate() : {} | |
| { | |
| LOOKAHEAD(<EXISTS>) exists_predicate() //starts with exists | |
| | LOOKAHEAD( ("(")+ <SELECT> | expression() ) (expression() | |
| ( | |
| LOOKAHEAD( comp_op() <ANY> ) any_predicate() | |
| | LOOKAHEAD( comp_op() UK_ALL() ) all_predicate() | |
| | LOOKAHEAD( comp_op() | join_op() ) comparison_predicate() | |
| | LOOKAHEAD( [ <NOT> ] <BETWEEN> ) between_predicate() | |
| | LOOKAHEAD( <IS> [ <NOT> ] ) null_predicate() | |
| | LOOKAHEAD([ <NOT> ] <IN> ) in_predicate() | |
| | LOOKAHEAD([ <NOT> ] <LIKE> ) like_predicate() | |
| ) | |
| ) | |
| | LOOKAHEAD( row_constructor()) row_constructor() row_comparison_predicate() | |
| } | |
| void predicate_op() : {} | |
| { | |
| <EXISTS> | |
| | LOOKAHEAD( expression() (comp_op() | join_op() | [ <NOT> ] ( <BETWEEN> | <IN> | <LIKE> ) | <IS> )) expression() (comp_op() | join_op() | [ <NOT> ] ( <BETWEEN> | <IN> | <LIKE> ) | <IS> ) | |
| | row_constructor() ( comp_op() | join_op() ) | |
| } | |
| void comparison_predicate() : {} | |
| { | |
| ( comp_op() | join_op() ) expression() | |
| } | |
| void row_comparison_predicate() : {} | |
| { | |
| comp_op() row_constructor() | |
| } | |
| void comp_op() : {} | |
| { | |
| "=" | |
| | "!" [ ">" | "=" | "<" ] | |
| | "!>" | "!=" | "!<" | |
| | ">" [ "=" ] | |
| | ">=" | |
| | "<" [ ">" | "=" ] | |
| | "<>" | "<=" | |
| } | |
| void join_op() : {} | |
| { | |
| <LEQJOIN> | |
| | <REQJOIN> | |
| } | |
| void between_predicate() : {} | |
| { | |
| [ <NOT> ] <BETWEEN> expression() <AND> expression() | |
| } | |
| void null_predicate() : {} | |
| { | |
| <IS> [ <NOT> ] null_stmt() | |
| } | |
| void in_predicate() : {} | |
| { | |
| [ <NOT> ] <IN> "(" ( in_value_list() | <SELECT> subq_select() ) ")" | |
| } | |
| void in_value_list() : {} | |
| { | |
| expression() | |
| ( "," expression() )* | |
| } | |
| void any_predicate() : {} | |
| { | |
| comp_op() <ANY> subquery() | |
| } | |
| void all_predicate() : {} | |
| { | |
| comp_op() UK_ALL() subquery() | |
| } | |
| void exists_predicate() : {} | |
| { | |
| <EXISTS> subquery() | |
| } | |
| void like_predicate() : {} | |
| { | |
| [ <NOT> ] <LIKE> pattern_clause() | |
| } | |
| void pattern_clause() : {} | |
| { | |
| expression() escape_clause() | |
| } | |
| void escape_clause() : {} | |
| { | |
| [ <ESCAPE> expression()] | |
| } | |
| void row_constructor() : {} | |
| { | |
| "(" row_constructor_list() ")" | |
| } | |
| void row_constructor_list() : {} | |
| { | |
| row_constructor_elem() | |
| ( "," row_constructor_elem() )* | |
| } | |
| void row_constructor_elem() : {} | |
| { | |
| expression() | |
| } | |
| ASTExpression expression() #Expression: {} | |
| { | |
| term() | |
| (LOOKAHEAD(3) | |
| ( LOOKAHEAD(3) "|" "|" | |
| | LOOKAHEAD(2) "+" | |
| | LOOKAHEAD(2) "-" | |
| | LOOKAHEAD(2) "&" | |
| | LOOKAHEAD(2) "|" | |
| | LOOKAHEAD(2) "^" | |
| ) term() | |
| )* | |
| { | |
| return jjtThis; | |
| } | |
| } | |
| void term() : {} | |
| { | |
| factor() | |
| ( "*" factor() | |
| | "/" factor() | |
| | "%" factor() | |
| )* | |
| } | |
| void factor() : {} | |
| { | |
| [ "~" ] subfactor() | |
| } | |
| void subfactor() : {} | |
| { | |
| [ "+" | "-" ] primary() | |
| } | |
| void primary_1() : {} | |
| { | |
| LOOKAHEAD(constant()) constant() | |
| | LOOKAHEAD("(" <SELECT>) subquery() | |
| | LOOKAHEAD(function()) function() | |
| | LOOKAHEAD(column()) column() | |
| | case_expression() | |
| | "(" expression() ")" | |
| } | |
| //supports javaname>>javaref | |
| void primary() : {} | |
| { | |
| primary_1() ( LOOKAHEAD(2) ( <DOT> | <JAVA_REF> ) id_or_string() [ LOOKAHEAD(2) "(" expression_list() ")" ] )* | |
| } | |
| void case_expression() : {} | |
| { | |
| case_abbreviation() | |
| | case_specification() | |
| } | |
| void case_abbreviation() : {} | |
| { | |
| nullif_format() | |
| | coalesce_format() | |
| } | |
| void case_specification() : {} | |
| { | |
| <CASE> simple_or_searched_case() | |
| } | |
| void simple_or_searched_case() : {} | |
| { | |
| simple_case() | |
| | searched_case() | |
| } | |
| void simple_case() : {} | |
| { | |
| expression() simple_when_clause_list() optional_else_clause() <END> | |
| } | |
| void searched_case() : {} | |
| { | |
| searched_when_clause_list() optional_else_clause() <END> | |
| } | |
| void simple_when_clause_list() : {} | |
| { | |
| simple_when_clause() | |
| ( simple_when_clause() )* | |
| } | |
| void simple_when_clause() : {} | |
| { | |
| <WHEN> expression() UK_THEN() result() | |
| } | |
| void searched_when_clause_list() : {} | |
| { | |
| searched_when_clause() | |
| ( searched_when_clause() )* | |
| } | |
| void searched_when_clause() : {} | |
| { | |
| <WHEN> boolean_expression() UK_THEN() result() | |
| } | |
| void optional_else_clause() : {} | |
| { | |
| [ <ELSE> result()] | |
| } | |
| void result() : {} | |
| { | |
| expression() | |
| } | |
| void coalesce_format() : {} | |
| { | |
| <COALESCE> "(" coalesce_list() ")" | |
| } | |
| void coalesce_list() : {} | |
| { | |
| coalesce_element() | |
| ( "," coalesce_element() )* | |
| } | |
| void coalesce_element() : {} | |
| { | |
| expression() | |
| } | |
| void nullif_format() : {} | |
| { | |
| <NULLIF> "(" expression() "," expression() ")" | |
| } | |
| void column() : {} | |
| { | |
| LOOKAHEAD(ii_col_spec()) ii_col_spec() | |
| | LOOKAHEAD (idplus()) idplus() | |
| } | |
| Token id() : {Token t = null;} | |
| { | |
| (t = idplus() | |
| | t = variable() | |
| ) | |
| {return t;} | |
| } | |
| void string() : {} | |
| { | |
| string_literal() | |
| | variable() | |
| } | |
| void id_string() : {} | |
| { | |
| idplus() | |
| | <DOUBLE_STRING_LITERAL> | |
| | variable() | |
| } | |
| void integer() : {} | |
| { | |
| <INTEGER_LITERAL> | |
| | variable() | |
| } | |
| int number() : {int retval = 0;} | |
| { | |
| ( "-" <INTEGER_LITERAL> {try {retval = Integer.parseInt("-" + getToken(0).image);}catch(Exception e){}} | |
| | [ "+" ] <INTEGER_LITERAL> {try {retval = Integer.parseInt(getToken(0).image);}catch(Exception e){}} | |
| ) | |
| {return retval;} | |
| } | |
| void constant() : {} | |
| { | |
| signed_const() | |
| | unsigned_const() | |
| } | |
| Token signed_const() : {Token t;} | |
| { | |
| ( t = <INTEGER_LITERAL> | |
| | t = <FLOATING_POINT_LITERAL> | |
| | t = <MONEY_LITERAL> | |
| ) | |
| {return t;} | |
| } | |
| Token unsigned_const() : {Token t;} | |
| { | |
| ( t = <BINARY_LITERAL> | |
| | t = string_literal() | |
| | t = null_stmt() | |
| | t = variable() | |
| ) | |
| {return t;} | |
| } | |
| String literal() : {Token t; boolean negative = false;} | |
| { | |
| ( [ "+" | "-" { negative = true;} ] t = signed_const() | |
| | t = unsigned_const() | |
| | t = idplus() | |
| | t = <PRIMARY> | |
| | t = <FOREIGN> | |
| ) | |
| {return negative?"-"+t.image:t.image;} | |
| } | |
| void binary() : {} | |
| { | |
| UK_BINARY() | |
| | variable() | |
| } | |
| Token null_stmt() : {Token t;} | |
| { | |
| t = <NULL> | |
| {return t;} | |
| } | |
| //variable reference | |
| Token variable() : {Token t;} | |
| { | |
| ( t = <VAR_NAME> | |
| | t = dyn_question_mark() | |
| | t = <GLOBAL_VAR_NAME> | |
| ) | |
| {return t;} | |
| } | |
| Token variable_assignment() : {Token t;} | |
| { | |
| ( t = <VAR_NAME> | |
| ) | |
| {return t;} | |
| } | |
| Token dyn_question_mark() : {Token t;} | |
| { | |
| t = <QUESTIONMARK> | |
| {return t;} | |
| } | |
| //include field reference and method reference | |
| void java_memberref() : {} | |
| { | |
| primary_1() ( LOOKAHEAD(3) ( <DOT> | <JAVA_REF> ) id_or_string() [ "(" expression_list() ")" ] )* | |
| } | |
| void function() : {} | |
| { | |
| LOOKAHEAD(2) builtin_function() | |
| | LOOKAHEAD(2) agg_function() | |
| } | |
| void builtin_function() : {} | |
| { | |
| <USER> | |
| | ii_obj_spec() "(" expression_list() optional_using_clause() ")" | |
| } | |
| void subq_expression_list() : {} | |
| { | |
| subq_expression() | |
| ( "," subq_expression() )* | |
| } | |
| void subq_expression() : {} | |
| { | |
| LOOKAHEAD(2) idplus() "=" [ expression() ] | |
| | LOOKAHEAD(2) expression() [ optional_as() ( idplus() | string_literal() ) ] | |
| | LOOKAHEAD(2) string_literal() "=" expression() | |
| } | |
| void expression_list() : {} | |
| { | |
| [LOOKAHEAD(2) expression() | |
| ( LOOKAHEAD(2) "," expression() )* ] | |
| } | |
| void optional_using_clause() : {} | |
| { | |
| [ "," [ <USING> <ID>] | |
| | <AS> datatype() | |
| ] | |
| } | |
| void optional_comma_argument() : {} | |
| { | |
| [ "," expression()] | |
| } | |
| void agg_function() : {} | |
| { | |
| agg_function_specification() | |
| } | |
| void agg_function_specification() : {} | |
| { | |
| <COUNT> "(" ( "*" | ( <DISTINCT> | all() ) expression() ) ")" | |
| | <AVG> "(" ( ( <DISTINCT> | all() ) expression() ) ")" | |
| | <MAX> "(" ( ( <DISTINCT> | all() ) expression() ) ")" | |
| | <MIN> "(" ( ( <DISTINCT> | all() ) expression() ) ")" | |
| | <SUM> "(" ( ( <DISTINCT> | all() ) expression() ) ")" | |
| } | |
| void all() : {} | |
| { | |
| [ UK_ALL() ] | |
| } | |
| void boolean_function() : {} | |
| { | |
| <UPDATE> "(" idplus() ")" | |
| } | |
| /**************************************************************************** | |
| ** GENERIC RULES @RH@ | |
| ** | |
| ** These rules are "generic" in that they are referenced by several | |
| ** productions from different statements, but serve a common purpose. | |
| ** They include: | |
| ** | |
| ** nonkeyword same as NAME; used to distinguish non-keywords in the grammar | |
| ** name_or_sconst Use for any constant; not valid for identifiers | |
| ** generic_ident any user-defined object | |
| ** internal_ident same as generic_ident, but may also include SCONST | |
| ** sconst_ident same is internal_ident, but doesn't check length of SCONST, | |
| ** used in WITH-clauses where need more context to verify length limits. | |
| ** auth_ident same as internal_ident; used to distinguish authorization identifiers | |
| ** user_ident same as auth_ident, but may also include $dba or $ingres | |
| ** schema_spec same as user_ident; used to distinguish schema identifiers | |
| ** obj_spec generic object specification | |
| ** tbl_spec same as generic_ident; used to distinguish table names | |
| ** col_spec same as generic_ident; used to distinguish column names | |
| *****************************************************************************/ | |
| Token ii_generic_ident(): {Token t;} | |
| { | |
| (t = <DELIM_IDENT>) | |
| // (t = string_literal()) | |
| |(t = <ID>) | |
| {return t;} | |
| } | |
| void ii_sconst_ident(): {} | |
| { | |
| ii_generic_ident() | |
| // | string_literal() | |
| } | |
| void ii_internal_ident(): {} | |
| { | |
| ii_generic_ident() | |
| // | string_literal() | |
| } | |
| void ii_auth_ident(): {} | |
| { | |
| LOOKAHEAD(2) ii_internal_ident() | |
| // | string_literal() | |
| } | |
| void ii_user_ident(): {} | |
| { | |
| ii_internal_ident() | |
| |<II_DBA> | |
| |<II_INGRES> | |
| } | |
| void ii_schema_spec(): {} | |
| { | |
| ii_user_ident() | |
| } | |
| void ii_tbl_spec(): {} | |
| { | |
| ii_generic_ident() | |
| } | |
| void ii_col_spec(): {} | |
| { | |
| ii_generic_ident() | |
| } | |
| void ii_obj_spec(): {} | |
| { | |
| LOOKAHEAD(2) ii_schema_spec() <DOT> ii_generic_ident() | |
| | LOOKAHEAD(<SESSION>) <SESSION> <DOT> ii_generic_ident() | |
| | ii_generic_ident() | |
| } | |
| JAVACODE | |
| /** | |
| * Skips the subsequent tokens when parsing error occurrs. | |
| * The process will continue until the current consumed token matches <code>tokinds</code> | |
| * or the next token to be consumed matches <code>beforekinds</code>. | |
| */ | |
| void error_skiptobefore(int[] tokinds, int[] beforekinds) { | |
| boolean match = false; | |
| Token t1 = getToken(0); | |
| // The following loop consumes tokens all the way up to a token of | |
| // "kind". We use a do-while loop rather than a while because the | |
| // current token is the one immediately before the erroneous token | |
| // (in our case the token immediately before what should have been | |
| // "if"/"while". | |
| do { | |
| match = token.kind == 0 || getToken(1).kind == 0 ; // 0 means the <EOF> | |
| if (match) {break;} | |
| for (int i=0; i< tokinds.length; i++){ | |
| match = match || token.kind == tokinds[i]; | |
| if (match) {break;} | |
| } | |
| if (match) {break;} | |
| for (int i=0; i< beforekinds.length; i++){ | |
| match = match || getToken(1).kind == beforekinds[i]; | |
| if (match) {break;} | |
| } | |
| if (!match){ | |
| logDebug("current token:" + token.image); | |
| getNextToken() ; | |
| } | |
| } while (!match); | |
| Token t2 = getToken(0); | |
| if (t1 == t2 ){ | |
| //force get next token | |
| logDebug("current token:" + token.image); | |
| getNextToken() ; | |
| } | |
| } | |