Skip to content

Instantly share code, notes, and snippets.

@mwnorman
Created March 12, 2012 19:22
Show Gist options
  • Save mwnorman/2024111 to your computer and use it in GitHub Desktop.
Save mwnorman/2024111 to your computer and use it in GitHub Desktop.
JavaCC grammar for PL/SQL DDL with choice conflict on keywords
options {
STATIC = false;
SUPPORT_CLASS_VISIBILITY_PUBLIC = true;
ERROR_REPORTING = false;
JAVA_UNICODE_ESCAPE = true;
UNICODE_INPUT = true;
NODE_USES_PARSER = false;
NODE_DEFAULT_VOID = true;
IGNORE_CASE = true;
VISITOR = true;
FORCE_LA_CHECK = true;
DEBUG_LOOKAHEAD = true;
DEBUG_TOKEN_MANAGER = true;
TRACK_TOKENS = true;
}
PARSER_BEGIN(DDLParser)
package simplified;
public class DDLParser {
protected String removeQuotes(String quotedString) {
return quotedString.substring(1, quotedString.length() - 1);
}
}
PARSER_END(DDLParser)
// white-space
SKIP: {
" " | "\t" | "\n" | "\r" | "\f"
}
// comments
SKIP: {
<COMMENT_LINE: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") >
}
SKIP:{
<COMMENT_BLOCK: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
}
// literals
// separator and operator literals (prefix with O_)
TOKEN: {
<O_ASSIGN: ":="> | <O_ASTERISK: "*"> | <O_ATSIGN: "@"> | <O_CLOSEPAREN: ")">
| <O_CONCAT: "||"> | <O_COLON: ":"> | <O_COMMA: ","> | <O_DOT: "."> | <O_DOUBLEDOT: "..">
| <O_DOLLAR: "$"> | <O_PERCENT: "%"> | <O_EQUAL: "="> | <O_GREATER: ">">
| <O_GREATEREQUAL: ">="> | <O_JOINPLUS: "(+)"> | <O_LESS: "<"> | <O_LESSEQUAL: "<=">
| <O_MINUS: "-"> | <O_NOTEQUAL2: "<>"> | <O_NOTEQUAL: "!="> | <O_OPENPAREN: "(">
| <O_PLUS: "+"> | <O_POUND: "#"> | <O_QUESTIONMARK: "?"> | <O_SEMICOLON: ";">
| <O_SLASH: "/"> | <O_TILDE: "~">
}
// numeric literals
TOKEN : {
<S_NUMBER: <FLOAT> | <FLOAT> ( ["e","E"] ([ "-","+"])? <FLOAT> )? >
| <#FLOAT: <INTEGER> | <INTEGER> ( "." <INTEGER> )? | "." <INTEGER> >
| <#INTEGER: ( <DIGIT> )+ >
| <#DIGIT: ["0" - "9"] >
}
//reserved words and keywords literals
/*
PLSQL reserved words (prefix with R_ ) and keyword (prefix with K_) [NB: incomplete list]
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/fundamentals.htm#CBJGBIGI
You cannot use reserved words as ordinary user-defined identifiers.
You can use keywords as ordinary user-defined identifiers, but it is not recommended.
If a new K_ keyword is add to this list of tokens, it must also be added to the
keywords() production
*/
TOKEN: {
//reserved words
<R_ALL: "ALL">
| <R_ALTER: "ALTER">
| <R_ANCHORED_ROWTYPE: "%ROWTYPE">
| <R_ANCHORED_TYPE: "%TYPE">
| <R_AND: "AND">
| <R_AS: "AS">
| <R_ASC: "ASC">
| <R_AT: "AT">
| <R_BEGIN: "BEGIN">
| <R_BETWEEN: "BETWEEN">
| <R_BY: "BY">
| <R_CASE: "CASE">
| <R_CHECK: "CHECK">
| <R_CLUSTERS: "CLUSTERS">
| <R_CLUSTER: "CLUSTER">
| <R_COLAUTH: "COLAUTH">
| <R_COLUMNS: "COLUMNS">
| <R_COMPRESS: "COMPRESS">
| <R_CONNECT: "CONNECT">
| <R_CRASH: "CRASH">
| <R_CREATE: "CREATE">
| <R_CURSOR: "CURSOR">
| <R_DECLARE: "DECLARE">
| <R_DEFAULT: "DEFAULT">
| <R_DESC: "DESC">
| <R_DISTINCT: "DISTINCT">
| <R_DROP: "DROP">
| <R_ELSE: "ELSE">
| <R_END: "END">
| <R_EXCEPTION: "EXCEPTION">
| <R_EXCLUSIVE: "EXCLUSIVE">
| <R_FETCH: "FETCH">
| <R_FOR: "FOR">
| <R_FROM: "FROM">
| <R_FUNCTION: "FUNCTION">
| <R_GOTO: "GOTO">
| <R_GRANT: "GRANT">
| <R_GROUP: "GROUP">
| <R_HAVING: "HAVING">
| <R_IDENTIFIED: "IDENTIFIED">
| <R_IF: "IF">
| <R_IN: "IN">
| <R_INDEX: "INDEX">
| <R_INDEXES: "INDEXES">
| <R_INSERT: "INSERT">
| <R_INTERSECT: "INTERSECT">
| <R_INTO: "INTO">
| <R_IS: "IS">
| <R_LIKE: "LIKE">
| <R_LOCK: "LOCK">
| <R_MINUS: "MINUS">
| <R_MODE: "MODE">
| <R_NOCOMPRESS: "NOCOMPRESS">
| <R_NO: "'NO'">
| <R_NOT: "NOT">
| <R_NOWAIT: "NOWAIT">
| <R_NULL: "NULL">
| <R_OF: "OF">
| <R_ON: "ON">
| <R_OPTION: "OPTION">
| <R_OR: "OR">
| <R_ORDER: "ORDER">
| <R_OVERLAPS: "OVERLAPS">
| <R_PROCEDURE: "PROCEDURE">
| <R_PUBLIC: "PUBLIC">
| <R_RESOURCE: "RESOURCE">
| <R_REVOKE: "REVOLE">
| <R_SELECT: "SELECT">
| <R_SHARE: "SHARE">
| <R_SIZE: "SIZE">
| <R_SQL: "SQL">
| <R_START: "START">
| <R_SUBTYPE: "SUBTYPE">
| <R_TABAUTH: "TABAUTH">
| <R_TABLE: "TABLE">
| <R_THEN: "THEN">
| <R_TO: "TO">
| <R_TYPE: "TYPE">
| <R_UNION: "UNION">
| <R_UNIQUE: "UNIQUE">
| <R_UPDATE: "UPDATE">
| <R_VALUES: "VALUES">
| <R_VIEW: "VIEW">
| <R_VIEWS: "VIEWS">
| <R_WHEN: "WHEN">
| <R_WHERE: "WHERE">
| <R_WITH: "WITH">
| <R_YES: "'YES'">
//keywords
| <K_ARRAY: "ARRAY">
| <K_AUTHID: "AUTHID">
| <K_AUTONOMOUS_TRANSACTION: "AUTONOMOUS_TRANSACTION">
| <K_BFILE: "BFILE">
| <K_BINARY_DOUBLE: "BINARY_DOUBLE">
| <K_BINARY_FLOAT: "BINARY_FLOAT">
| <K_BINARY_INTEGER: "BINARY_INTEGER">
| <K_BLOB: "BLOB">
| <K_BOOLEAN: "BOOLEAN">
| <K_BYTE: "BYTE">
| <K_CHAR: "CHAR">
| <K_CHARACTER: "CHARACTER">
| <K_CHARSET: "CHARSET">
| <K_CLOB: "CLOB">
| <K_COMMIT: "COMMIT">
| <K_CONSTANT: "CONSTANT">
| <K_CONSTRAINT: "CONSTRAINT">
| <K_CURRENT_USER: "CURRENT_USER">
| <K_DATE :"DATE">
| <K_DAY: "DAY">
| <K_DEC: "DEC">
| <K_DECIMAL: "DECIMAL">
| <K_DEFINER: "DEFINER">
| <K_DELETE: "DELETE">
| <K_DETERMINISTIC: "DETERMINISTIC">
| <K_DOUBLE: "DOUBLE">
| <K_ENABLE: "ENABLE">
| <K_EXCEPTION_INIT: "EXCEPTION_INIT">
| <K_FINAL: "FINAL">
| <K_FLOAT: "FLOAT">
| <K_FORCE: "FORCE">
| <K_GLOBAL: "GLOBAL">
| <K_INLINE: "INLINE">
| <K_INSTANTIABLE: "INSTANTIABLE">
| <K_INT: "INT">
| <K_INTEGER: "INTEGER">
| <K_INTERVAL: "INTERVAL">
| <K_KEY: "KEY">
| <K_LOCAL: "LOCAL">
| <K_LONG: "LONG">
| <K_MLSLABEL: "MLSLABEL">
| <K_MONTH: "MONTH">
| <K_NATIONAL: "NATIONAL">
| <K_NATURAL: "NATURAL">
| <K_NCHAR: "NCHAR">
| <K_NCLOB: "NCLOB">
| <K_NOCOPY: "NOCOPY">
| <K_NUMBER: "NUMBER">
| <K_NUMERIC: "NUMERIC">
| <K_NVARCHAR2: "NVARCHAR2">
| <K_NVARCHAR: "NVARCHAR">
| <K_OBJECT: "OBJECT">
| <K_OID: "OID">
| <K_ORGANIZATION: "ORGANIZATION">
| <K_OUT: "OUT">
| <K_OVERFLOW: "OVERFLOW">
| <K_PACKAGE: "PACKAGE">
| <K_PARALLEL_ENABLE: "PARALLEL_ENABLE">
| <K_PIPELINED: "PIPELINED">
| <K_PLS_INTEGER:"PLS_INTEGER">
| <K_POSITIVE: "POSITIVE">
| <K_PRAGMA: "PRAGMA">
| <K_PRECISION:"PRECISION">
| <K_PRESERVE: "PRESERVE">
| <K_PRIMARY: "PRIMARY">
| <K_RANGE: "RANGE">
| <K_RAW: "RAW">
| <K_REAL:"REAL">
| <K_RECORD: "RECORD">
| <K_REF: "REF">
| <K_REPLACE: "REPLACE">
| <K_RESTRICT_REFERENCES: "RESTRICT_REFERENCES">
| <K_RESULT_CACHE: "RESULT_CACHE">
| <K_RETURN: "RETURN">
| <K_RNDS: "RNDS">
| <K_RNPS: "RNPS">
| <K_ROWID:"ROWID">
| <K_ROWS: "ROWS">
| <K_SECOND: "SECOND">
| <K_SERIALLY_REUSABLE: "SERIALLY_REUSABLE">
| <K_SET: "SET">
| <K_SIGNTYPE: "SIGNTYPE">
| <K_SIMPLE_DOUBLE:"SIMPLE_DOUBLE">
| <K_SIMPLE_FLOAT:"SIMPLE_FLOAT">
| <K_SIMPLE_INTEGER:"SIMPLE_INTEGER">
| <K_SMALLINT:"SMALLINT">
| <K_STRING: "STRING">
| <K_SYS_REFCURSOR:"SYS_REFCURSOR">
| <K_TEMPORARY: "TEMPORARY">
| <K_TIME: "TIME">
| <K_TIMESTAMP: "TIMESTAMP">
| <K_TRUST: "TRUST">
| <K_UROWID:"UROWID">
| <K_VARCHAR2: "VARCHAR2">
| <K_VARCHAR: "VARCHAR">
| <K_VARRAY: "VARRAY">
| <K_VARYING: "VARYING">
| <K_WNDS: "WNDS">
| <K_WNPS: "WNPS">
| <K_YEAR: "YEAR">
| <K_ZONE: "ZONE">
}
// identifier literals
TOKEN: {
<S_IDENTIFIER: (<LETTER>)+ (<DIGIT> | <LETTER> | <SPECIAL_CHARS>)* >
| <#LETTER: ["a"-"z", "A"-"Z"] >
| <#SPECIAL_CHARS: "$" | "_" | "#" | "@" >
| <S_BIND: ":" ( <S_NUMBER> | <S_IDENTIFIER> ("." <S_IDENTIFIER>)?) >
| <S_CHAR_LITERAL: "'" (~["'"])* "'" ("'" (~["'"])* "'")*>
| <S_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" >
}
String keywords():
{Token t = null;}
{
(
t=<K_TIMESTAMP>
)
{
return t.image;
}
}
String OracleObjectName() #void:
{Token t = null;
String s = null;}
{
(
// s=keywords()
//|
t=<S_QUOTED_IDENTIFIER> {s = removeQuotes(t.image);}
| t=<S_IDENTIFIER> {s = t.image;}
)
{
return s;
}
}
String OracleObjectNamePossiblyDotted():
{String possiblyDottedName = "";
String afterDot = null;
}
{
possiblyDottedName=OracleObjectName() [ <O_DOT> afterDot=OracleObjectName() ]
{
if (afterDot != null) {
possiblyDottedName += "." + afterDot;
}
return possiblyDottedName;
}
}
String direction():
{String dir = "";
}
{
(
<R_IN> {dir = "IN";} [ <K_OUT> {dir += " OUT";} ]
| <K_OUT> {dir = "OUT";}
)
{
return dir;
}
}
// stripped-down version of PLSQL grammar: only parses package/top-level DDL specifications
// PLSQLPackage at 'top-level'
void parsePLSQLPackage():
{String dottedName = null;
String schema = null;
String packageName = null;
}
{
<R_CREATE> [ orReplaceClause() ] <K_PACKAGE>
dottedName=OracleObjectNamePossiblyDotted()
{
packageName = dottedName;
if (dottedName.contains(".")) {
int idx = dottedName.indexOf(".");
schema = dottedName.substring(0, idx);
packageName = dottedName.substring(idx+1, dottedName.length());
}
}
[ invokerRightsClause() ] asClause()
( packageDeclaration() )*
<R_END> skipToSemiColon()
<EOF>
}
void orReplaceClause(): {}
{
<R_OR> <K_REPLACE>
}
void invokerRightsClause(): {}
{
<K_AUTHID> (<K_CURRENT_USER> | <K_DEFINER>)
}
void asClause(): {}
{
( <R_AS> | <R_IS> )
}
// procedure at 'top-level'
void parseTopLevelProcedure():
{String dottedName = null;
String schema = null;
String procedureName = null;}
{
<R_CREATE> [ orReplaceClause() ] <R_PROCEDURE>
dottedName=OracleObjectNamePossiblyDotted()
{
procedureName = dottedName;
if (dottedName.contains(".")) {
int idx = dottedName.indexOf(".");
schema = dottedName.substring(0, idx);
procedureName = dottedName.substring(idx+1, dottedName.length());
}
}
[ <O_OPENPAREN> argumentList() <O_CLOSEPAREN> ] asClause() skipToEnd()
}
// function at 'top-level'
void parseTopLevelFunction():
{String dottedName = null;
String schema = null;
String functionName = null;
}
{
<R_CREATE> [ orReplaceClause() ] <R_FUNCTION>
dottedName=OracleObjectNamePossiblyDotted()
{
functionName = dottedName;
if (dottedName.contains(".")) {
int idx = dottedName.indexOf(".");
schema = dottedName.substring(0, idx);
functionName = dottedName.substring(idx+1, dottedName.length());
}
}
[ <O_OPENPAREN> argumentList() <O_CLOSEPAREN> ] functionReturnSpec() asClause() skipToEnd()
}
// table at 'top-level'
void parseTable():
{String dottedName = null;
String schema = null;
String tableName = null;
}
{
<R_CREATE> [ <K_GLOBAL> <K_TEMPORARY> ] <R_TABLE>
dottedName=OracleObjectNamePossiblyDotted()
{
tableName = dottedName;
if (dottedName.contains(".")) {
int idx = dottedName.indexOf(".");
schema = dottedName.substring(0, idx);
tableName = dottedName.substring(idx+1, dottedName.length());
}
}
<O_OPENPAREN> columnDeclarations() <O_CLOSEPAREN>
// todo - add support for ALTER ... clauses
[ <K_ORGANIZATION> ] [ <R_INDEX> ] [ <R_NOCOMPRESS> ] [ <K_OVERFLOW> ] [ onCommitClause() ]
<O_SEMICOLON>
<EOF>
}
boolean notNullClause(): {}
{
<R_NOT> <R_NULL> [ <K_ENABLE> ]
{
return true;
}
}
void onCommitClause(): {}
{
( <R_ON> <K_COMMIT> ( <K_DELETE> | <K_PRESERVE> ) <K_ROWS> )
}
// type at 'top-level'
void parseType():
{String dottedName = null;
}
//CREATE [OR REPLACE] TYPE [ schema. ] type_name [ FORCE ] [ OID 'object_identifier' ] [ object_type | | { IS | AS } { varray_type_def | nested_table_type_def } ];
{
<R_CREATE> [ orReplaceClause() ] <R_TYPE>
dottedName=OracleObjectNamePossiblyDotted()
[ <K_FORCE> ] [ <K_OID> <S_CHAR_LITERAL> ] [ invokerRightsClause() ] asClause()
(
<K_OBJECT> <O_OPENPAREN> columnDeclarations() <O_CLOSEPAREN>
| <K_VARRAY> <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> <R_OF> typeSpec()
| <R_TABLE> <R_OF> typeSpec()
)
[ [ <R_NOT> ] ( <K_FINAL> | <K_INSTANTIABLE> ) ] skipToEnd()
}
void columnDeclarations() #void:
{}
{
columnDeclaration() [ <O_COMMA> columnDeclarations() ]
}
void columnDeclaration() #void:
{String s = null;
}
{
s=OracleObjectName() typeSpec() [ notNullConstraint() ]
}
void notNullConstraint() #void:
{
}
{
[ <K_CONSTRAINT> <S_QUOTED_IDENTIFIER> ] <R_NOT> <R_NULL> [ <K_ENABLE> ]
}
void pkList() #void:
{}
{
pk() ( <O_COMMA> pk() )*
}
void pk() #void:
{
}
{
OracleObjectName()
}
void packageDeclaration() #void:
{}
{
variableDeclaration()
| typeOrSubTypeDeclaration()
| cursorDeclaration()
| procedureSpec()
| functionSpec()
| pragmaDeclaration()
}
void variableDeclaration():
{String varName = null;}
{
varName=OracleObjectName() [ <K_CONSTANT> ] typeSpec() [ <R_NOT> <R_NULL> ]
[variableDefaultAssignment() ]
<O_SEMICOLON>
}
void variableDefaultAssignment() #void:
{}
{
( <O_ASSIGN> | <R_DEFAULT> ) skipToSemiColon()
}
void datatype():
{Token t = null;
Token precision = null;
Token scale = null;
Token withTimeZone = null;
Token withLocalTimeZone = null;
}
{
<K_BINARY_INTEGER>
| <K_BINARY_FLOAT>
| <K_BINARY_DOUBLE>
| <K_NATURAL>
| <K_POSITIVE>
| <K_SIGNTYPE>
| ( t=<K_NUMBER>
| t=<K_NUMERIC>
| t=<K_DECIMAL>
| t=<K_DEC>
) [ <O_OPENPAREN> [ precision=<O_ASTERISK > | precision=<S_NUMBER> ] ( <O_COMMA> scale=<S_NUMBER> )* <O_CLOSEPAREN> ]
| <K_LONG> [ t=<K_RAW> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_RAW> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_BOOLEAN>
| <K_DATE>
| <K_INTERVAL>
(
<K_DAY> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] <R_TO> <K_SECOND> [ <O_OPENPAREN> scale=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_YEAR> [ <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ] <R_TO> <K_MONTH>
)
| <K_TIME>
| <K_TIMESTAMP> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] [ <R_WITH> [ withLocalTimeZone=<K_LOCAL> ] withTimeZone=<K_TIME> <K_ZONE> ]
| <K_INTEGER>
| <K_INT>
| <K_SMALLINT>
| <K_FLOAT> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_REAL>
| <K_MLSLABEL>
| <K_PLS_INTEGER>
| <K_SIMPLE_INTEGER>
| <K_SIMPLE_FLOAT>
| <K_SIMPLE_DOUBLE>
| <K_SYS_REFCURSOR>
| <K_BLOB >
| <K_CLOB>
| <K_NCLOB>
| <K_BFILE>
| <K_ROWID>
| <K_UROWID> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_DOUBLE> <K_PRECISION>
| <K_CHAR> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
| <K_CHARACTER> [ <K_VARYING> ] <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN>
| <K_VARCHAR> <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN>
| <K_VARCHAR2> [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
| <K_NCHAR> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_NVARCHAR2> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
| <K_NATIONAL> ( <K_CHARACTER> | <K_CHAR> ) [ <K_VARYING> ] <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN>
}
void typeSpec():
{boolean isTYPEType = false;
boolean isROWTYPEType = false;
String spec = null;
String s = null;}
{
(
datatype()
| columnSpec()
[
( <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> )
| <R_ANCHORED_TYPE>
| <R_ANCHORED_ROWTYPE>
]
)
}
String columnSpec() #void:
{String s1 = null;
String s2 = null;
String s3 = null;}
{
s1=OracleObjectName() [ <O_DOT> s2=OracleObjectName() [ <O_DOT> s3=OracleObjectName() ] ]
{
StringBuilder sb = new StringBuilder(s1);
if (s2 != null) {
sb.append('.');
sb.append(s2);
if (s3 != null) {
sb.append('.');
sb.append(s3);
}
}
return sb.toString();
}
}
String tableSpec() #void:
{}
{
OracleObjectName() [ <O_DOT> OracleObjectName() [ <O_ATSIGN> <S_IDENTIFIER> ] ]
{return token.image;}
}
String typeName() #void:
{}
{
OracleObjectName() [ <O_DOT> OracleObjectName() ]
{return token.image;}
}
void typeOrSubTypeDeclaration() #void:
{String s = null;}
{
typeDeclaration()
| subtypeDeclaration()
}
void typeDeclaration() #void:
{String s = null;}
{
<R_TYPE> s=typeName() <R_IS> aTypeDeclaration() <O_SEMICOLON>
}
void aTypeDeclaration() #void:
{}
{
recordDeclaration()
| plsqlTableDeclaration()
| varrayDeclaration()
| refCursorDeclaration()
}
void recordDeclaration() #void:
{
}
{
<K_RECORD> <O_OPENPAREN>
fieldDeclarations()
<O_CLOSEPAREN>
}
void fieldDeclarations() #void:
{}
{
fieldDeclaration() [ <O_COMMA> fieldDeclarations() ]
}
void fieldDeclaration( ):
{String s = null;
}
{
s=typeName() typeSpec() [ <R_NOT> <R_NULL> ] [ fieldDefaultAssignment() ]
}
void fieldDefaultAssignment() #void:
{}
{
( <O_ASSIGN> | <R_DEFAULT> ) skipToNextArg()
}
void subtypeDeclaration() #void:
{String subtypeName;
Token notNull = null;
Token rangeStart = null;
Token rangeEnd = null;}
{
<R_SUBTYPE> subtypeName=OracleObjectName() <R_IS> typeSpec()
[ <K_RANGE> rangeStart=<S_NUMBER> <O_DOUBLEDOT> rangeEnd=<S_NUMBER> ]
[ <R_NOT> notNull=<R_NULL> ] <O_SEMICOLON>
}
void plsqlTableDeclaration() #void:
{
}
{
<R_TABLE> <R_OF> typeSpec() [ <R_NOT> <R_NULL> ]
[ <R_INDEX> <R_BY> plsqlTableIndexByDeclaration() ]
}
void plsqlTableIndexByDeclaration() #void:
{}
{
(
<K_PLS_INTEGER>
| <K_BINARY_INTEGER>
| <K_VARCHAR2> <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN>
| <K_STRING> <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN>
)
}
void varrayDeclaration() #void:
{}
{
( <K_VARRAY> | <K_VARYING> <K_ARRAY> ) <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN>
<R_OF> datatype() [ <R_NOT> <R_NULL> ]
}
void refCursorDeclaration() #void:
{}
{
<K_REF> <R_CURSOR>
[
<K_RETURN> <S_IDENTIFIER> [ <R_ANCHORED_TYPE> | <R_ANCHORED_ROWTYPE> ]
]
}
void cursorReturnsColumnType() #void:
{}
{
columnSpec() [ <R_ANCHORED_TYPE> ]
}
void cursorReturnsTableType() #void:
{}
{
tableSpec() [ <R_ANCHORED_TYPE> ]
}
void cursorDeclaration() #void:
{}
{
<R_CURSOR> OracleObjectName()
<O_SEMICOLON>
}
// Procedure Specification
void procedureSpec() #void:
{String s = null;
}
{
<R_PROCEDURE> s=OracleObjectName()
[ <O_OPENPAREN> argumentList() <O_CLOSEPAREN> ]
<O_SEMICOLON>
}
void argumentList() #void:
{}
{
argument() ( <O_COMMA> argument() )*
}
// Function Specification
void functionSpec() #void:
{String s = null;
}
{
<R_FUNCTION> s=OracleObjectName()
[ <O_OPENPAREN> argumentList() <O_CLOSEPAREN> ] functionReturnSpec()
[ <K_DETERMINISTIC> | <K_PIPELINED> | <K_PARALLEL_ENABLE> | <K_RESULT_CACHE> ]
<O_SEMICOLON>
}
void functionReturnSpec():
{}
{
<K_RETURN> typeSpec()
}
void argument( ) #void:
{String s = null;
}
{
s=OracleObjectName() [ direction() ]
[ <K_NOCOPY> ] typeSpec() [ argumentDefaultAssignment() ]
}
boolean argumentDefaultAssignment(): {}
{
( <O_ASSIGN> | <R_DEFAULT> ) skipToNextArg()
{
return true;
}
}
void pragmaDeclaration() #void:
{}
{
<K_PRAGMA> skipToSemiColon()
}
void skipToSemiColon() #void:
{}
{
{
Token t = getNextToken();
while (t.kind != O_SEMICOLON) {
t = getNextToken();
}
token_source.input_stream.backup(1);
}
}
void skipToNextArg() #void:
{}
{
{
Token t = getNextToken();
while (t.kind != O_COMMA && t.kind != O_CLOSEPAREN) {
t = getNextToken();
}
token_source.input_stream.backup(1);
}
}
void skipToEnd() #void:
{}
{
{
/** skip through all the tokens. */
Token t = getNextToken();
while (t.kind != EOF) {
t = getNextToken();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment