blob: 4a8c8a1a7883867969438a9e662070ed580b3470 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Mike Norman - June 10 2011, created DDL parser package
******************************************************************************/
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;
VISITOR = true;
}
PARSER_BEGIN(DDLParser)
/*******************************************************************************
* Copyright (c) 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Mike Norman - June 10 2011, created DDL parser package
******************************************************************************/
package org.eclipse.persistence.tools.oracleddl.parser;
//javase imports
import java.io.InputStream;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
//metadata imports
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType;
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentTypeDirection;
import org.eclipse.persistence.tools.oracleddl.metadata.BlobType;
import org.eclipse.persistence.tools.oracleddl.metadata.CharType;
import org.eclipse.persistence.tools.oracleddl.metadata.ClobType;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.DecimalType;
import org.eclipse.persistence.tools.oracleddl.metadata.DoubleType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
import org.eclipse.persistence.tools.oracleddl.metadata.FloatType;
import org.eclipse.persistence.tools.oracleddl.metadata.FunctionType;
import org.eclipse.persistence.tools.oracleddl.metadata.IntervalDayToSecond;
import org.eclipse.persistence.tools.oracleddl.metadata.IntervalYearToMonth;
import org.eclipse.persistence.tools.oracleddl.metadata.LongType;
import org.eclipse.persistence.tools.oracleddl.metadata.LongRawType;
import org.eclipse.persistence.tools.oracleddl.metadata.NCharType;
import org.eclipse.persistence.tools.oracleddl.metadata.NClobType;
import org.eclipse.persistence.tools.oracleddl.metadata.NumericType;
import org.eclipse.persistence.tools.oracleddl.metadata.NVarChar2Type;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectType;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectTableType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLRecordType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLSubType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;
import org.eclipse.persistence.tools.oracleddl.metadata.RawType;
import org.eclipse.persistence.tools.oracleddl.metadata.RealType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import org.eclipse.persistence.tools.oracleddl.metadata.TimeStampType;
import org.eclipse.persistence.tools.oracleddl.metadata.URowIdType;
import org.eclipse.persistence.tools.oracleddl.metadata.UnresolvedSizedType;
import org.eclipse.persistence.tools.oracleddl.metadata.UnresolvedType;
import org.eclipse.persistence.tools.oracleddl.metadata.VarCharType;
import org.eclipse.persistence.tools.oracleddl.metadata.VarChar2Type;
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType;
import org.eclipse.persistence.tools.oracleddl.util.DatabaseTypesRepository;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BFILE_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_INTEGER_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_FLOAT_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BINARY_DOUBLE_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.BOOLEAN_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.DATE_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.INTEGER_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.MLSLABEL_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.NATURAL_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.PLS_INTEGER_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.POSITIVE_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.ROWID_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIGN_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_INTEGER_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_DOUBLE_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SIMPLE_FLOAT_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SMALLINT_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.SYS_REFCURSOR_TYPE;
import static org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseTypeEnum.TIME_TYPE;
public class DDLParser {
protected Map<String, DatabaseType> localTypes = new HashMap<String, DatabaseType>();
protected DatabaseTypesRepository typesRepository = new DatabaseTypesRepository();
public DDLParser() {
super();
}
public void setTypesRepository(DatabaseTypesRepository typesRepository) {
this.typesRepository = typesRepository;
}
public DatabaseTypesRepository getTypesRepository() {
return typesRepository;
}
}
PARSER_END(DDLParser)
// white-space
SKIP: {
" "
| "\t"
| "\n"
| "\r"
| "\f"
}
// comments
SKIP: {
<COMMENT_LINE: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") >
}
SKIP:{
<COMMENT_BLOCK: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/">
}
// PLSQL reserved keywords (prefix with K_ to avoid naming conflicts) - NB: incomplete list
TOKEN [IGNORE_CASE]: {
<K_A: "A">
| <K_ADD: "ADD">
| <K_ALTER: "ALTER">
| <K_ARRAY: "ARRAY">
| <K_AS: "AS">
| <K_AUTHID: "AUTHID">
| <K_AUTOMATIC: "AUTOMATIC">
| <K_AUTONOMOUS_TRANSACTION: "AUTONOMOUS_TRANSACTION">
| <K_BEGIN: "BEGIN">
| <K_BFILE: "BFILE">
| <K_BINARY_DOUBLE: "BINARY_DOUBLE">
| <K_BINARY_FLOAT: "BINARY_FLOAT">
| <K_BINARY_INTEGER: "BINARY_INTEGER">
| <K_BLOB: "BLOB">
| <K_BODY: "BODY">
| <K_BOOLEAN: "BOOLEAN">
| <K_BUILTIN: "BUILTIN">
| <K_BULK: "BULK">
| <K_BY: "BY">
| <K_BYTE: "BYTE">
| <K_CHAR: "CHAR">
| <K_CHARACTER: "CHARACTER">
| <K_CHARSET: "%CHARSET">
| <K_CLOB: "CLOB">
| <K_CLOSE: "CLOSE">
| <K_COLLECT: "COLLECT">
| <K_COMMIT: "COMMIT">
| <K_CONSTANT: "CONSTANT">
| <K_CONSTRAINT: "CONSTRAINT">
| <K_COUNT: "COUNT">
| <K_CREATE: "CREATE">
| <K_CROSS: "CROSS">
| <K_CUBE: "CUBE">
| <K_CURRENT_OF: "CURRENT_OF">
| <K_CURRENT_USER: "CURRENT_USER">
| <K_CURSOR: "CURSOR">
| <K_DATE: "DATE">
| <K_DAY: "DAY">
| <K_DBTIMEZONE: "DBTIMEZONE">
| <K_DEC: "DEC">
| <K_DECIMAL: "DECIMAL">
| <K_DECREMENT: "DECREMENT">
| <K_DEFAULT: "DEFAULT">
| <K_DEFINER: "DEFINER">
| <K_DELETE: "DELETE">
| <K_DETERMINISTIC: "DETERMINISTIC">
| <K_DIMENSION: "DIMENSION">
| <K_DOUBLE: "DOUBLE">
| <K_ELSIF: "ELSIF">
| <K_EMPTY: "EMPTY">
| <K_ENABLE: "ENABLE">
| <K_END: "END">
| <K_EQUALS_PATH: "EQUALS_PATH">
| <K_ESCAPE: "ESCAPE">
| <K_EXCEPTION: "EXCEPTION">
| <K_EXCEPTION_INIT: "EXCEPTION_INIT">
| <K_EXIT: "EXIT">
| <K_FALSE: "FALSE">
| <K_FINAL: "FINAL">
| <K_FIPSFLAG: "FIPSFLAG">
| <K_FIRST: "FIRST">
| <K_FLOAT: "FLOAT">
| <K_FORCE: "FORCE">
| <K_FULL: "FULL">
| <K_FUNCTION: "FUNCTION">
| <K_GLOBAL: "GLOBAL">
| <K_GROUPING: "GROUPING">
| <K_IGNORE: "IGNORE">
| <K_IN: "IN">
| <K_INCREMENT: "INCREMENT">
| <K_INDEX: "INDEX">
| <K_INFINITE: "INFINITE">
| <K_INLINE: "INLINE">
| <K_INNER: "INNER">
| <K_INSTANTIABLE: "INSTANTIABLE">
| <K_INT: "INT">
| <K_INTEGER: "INTEGER">
| <K_INTERFACE: "INTERFACE">
| <K_INTERVAL: "INTERVAL">
| <K_IS: "IS">
| <K_ITERATE: "ITERATE">
| <K_JOIN: "JOIN">
| <K_KEY: "KEY">
| <K_KEEP: "KEEP">
| <K_LAST: "LAST">
| <K_LEFT: "LEFT">
| <K_LIKE2: "LIKE2">
| <K_LIKE4: "LIKE4">
| <K_LIKEC: "LIKEC">
| <K_LOCAL: "LOCAL">
| <K_LONG: "LONG">
| <K_LOOP: "LOOP">
| <K_MAIN: "MAIN">
| <K_MEASURES: "MEASURES">
| <K_MEMBER: "MEMBER">
| <K_MLSLABEL: "MLSLABEL">
| <K_MODEL: "MODEL">
| <K_MONTH: "MONTH">
| <K_NAN: "NAN">
| <K_NATIONAL: "NATIONAL">
| <K_NATURAL: "NATURAL">
| <K_NAV: "NAV">
| <K_NCHAR: "NCHAR">
| <K_NCLOB: "NCLOB">
| <K_NEW_NAMES: "NEW_NAMES">
| <K_NO: "'NO'">
| <K_NOCOMPRESS: "NOCOMPRESS">
| <K_NOCOPY: "NOCOPY">
| <K_NOCYCLE: "NOCYCLE">
| <K_NOT: "NOT">
| <K_NULL: "NULL">
| <K_NULLS: "NULLS">
| <K_NUMBER: "NUMBER">
| <K_NUMERIC: "NUMERIC">
| <K_NVARCHAR2: "NVARCHAR2">
| <K_NVARCHAR: "NVARCHAR">
| <K_OBJECT: "OBJECT">
| <K_OF: "OF">
| <K_OID: "OID">
| <K_ON: "ON">
| <K_ONLY: "ONLY">
| <K_OPEN: "OPEN">
| <K_OR: "OR">
| <K_ORGANIZATION: "ORGANIZATION">
| <K_OUT: "OUT">
| <K_OUTER: "OUTER">
| <K_OVERFLOW: "OVERFLOW">
| <K_PACKAGE: "PACKAGE">
| <K_PARALLEL_ENABLE: "PARALLEL_ENABLE">
| <K_PARTITION: "PARTITION">
| <K_PIPELINED: "PIPELINED">
| <K_PLS_INTEGER: "PLS_INTEGER">
| <K_POSITIVE: "POSITIVE">
| <K_PRAGMA: "PRAGMA">
| <K_PRECISION: "PRECISION">
| <K_PRESENT: "PRESENT">
| <K_PRESERVE: "PRESERVE">
| <K_PRIMARY: "PRIMARY">
| <K_PROCEDURE: "PROCEDURE">
| <K_RAISE: "RAISE">
| <K_RANGE: "RANGE">
| <K_RAW: "RAW">
| <K_READ: "READ">
| <K_REAL: "REAL">
| <K_RECORD: "RECORD">
| <K_REF: "REF">
| <K_REFERENCE: "REFERENCE">
| <K_REGEXP_LIKE: "REGEXP_LIKE">
| <K_REPLACE: "REPLACE">
| <K_RESTRICT_REFERENCES: "RESTRICT_REFERENCES">
| <K_RESULT_CACHE: "RESULT_CACHE">
| <K_RETURN: "RETURN">
| <K_RETURNING: "RETURNING">
| <K_REVERSE: "REVERSE">
| <K_RIGHT: "RIGHT">
| <K_RNDS: "RNDS">
| <K_RNPS: "RNPS">
| <K_ROLLBACK: "ROLLBACK">
| <K_ROLLUP: "ROLLUP">
| <K_ROWID: "ROWID">
| <K_ROWS: "ROWS">
| <K_ROWTYPE: "%ROWTYPE">
| <K_RULES: "RULES">
| <K_SECOND: "SECOND">
| <K_SEQUENTIAL: "SEQUENTIAL">
| <K_SERIALLY_REUSABLE: "SERIALLY_REUSABLE">
| <K_SESSIONTIMEZONE: "SESSIONTIMEZONE">
| <K_SET: "SET">
| <K_SETS: "SETS">
| <K_SIBLINGS: "SIBLINGS">
| <K_SIGNTYPE: "SIGNTYPE">
| <K_SINGLE: "SINGLE">
| <K_SIMPLE_INTEGER: "SIMPLE_INTEGER">
| <K_SIMPLE_DOUBLE: "SIMPLE_DOUBLE">
| <K_SIMPLE_FLOAT: "SIMPLE_FLOAT">
| <K_SMALLINT: "SMALLINT">
| <K_SOME: "SOME">
| <K_STRING: "STRING">
| <K_SUBMUlookISET: "SUBMUlookISET">
| <K_SUBTYPE: "SUBTYPE">
| <K_SYS_REFCURSOR: "SYS_REFCURSOR">
| <K_TABLE: "TABLE">
| <K_TEMPORARY: "TEMPORARY">
| <K_THE: "THE">
| <K_TIME: "TIME">
| <K_TIMESTAMP: "TIMESTAMP">
| <K_TO: "TO">
| <K_TRANSACTION: "TRANSACTION">
| <K_TRUE: "TRUE">
| <K_TRUST: "TRUST">
| <K_TYPE: "TYPE">
| <K_TYPE2: "%TYPE">
| <K_UNDER_PATH: "UNDER_PATH">
| <K_UNTIL: "UNTIL">
| <K_UPDATED: "UPDATED">
| <K_UPSERT: "UPSERT">
| <K_UROWID: "UROWID">
| <K_USING: "USING">
| <K_VARCHAR2: "VARCHAR2">
| <K_VARCHAR: "VARCHAR">
| <K_VARRAY: "VARRAY">
| <K_VARYING: "VARYING">
| <K_WITH: "WITH">
| <K_WHILE: "WHILE">
| <K_WNDS: "WNDS">
| <K_WNPS: "WNPS">
| <K_WORK: "WORK">
| <K_YEAR: "YEAR">
| <K_YES: "'YES'">
| <K_ZONE: "ZONE">
}
// separators and operators (prefix with O_ to avoid naming conflicts)
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"] >
}
// identifiers
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","\""])* "\"" >
}
// stripped-down version of PLSQL grammar: only parses package/top-level DDL specifications
// PLSQLPackage at 'top-level'
PLSQLPackageType parsePLSQLPackage():
{String schema = null;
String packageName = null;
PLSQLPackageType packageType = new PLSQLPackageType();
}
{
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_PACKAGE>
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] packageName=OracleObjectName()
{
if (schema != null) {
packageType.setSchema(schema);
}
packageType.setPackageName(packageName);
}
[ <K_AUTHID> [ <K_CURRENT_USER> | <K_DEFINER> ] ]
[ <K_AS> | <K_IS> ]
( packageDeclaration(packageType) )*
<K_END> [ OracleObjectName() ] <O_SEMICOLON>
<EOF>
{
typesRepository.setDatabaseType(packageName, packageType);
return packageType;
}
}
// procedure at 'top-level'
ProcedureType parseTopLevelProcedure():
{ProcedureType procedureType = null;
String schema = null;
String procedureName = null;}
{
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_PROCEDURE>
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] procedureName=OracleObjectName()
{
procedureType = new ProcedureType(procedureName);
if (schema != null) {
procedureType.setSchema(schema);
} }
[ <O_OPENPAREN> argumentList(procedureType) <O_CLOSEPAREN> ] [ <K_AS> | <K_IS> ]
skipToEnd()
{
typesRepository.setDatabaseType(procedureName, procedureType);
return procedureType;
}
}
// function at 'top-level'
FunctionType parseTopLevelFunction():
{FunctionType functionType = null;
String schema = null;
String functionName = null;
ArgumentType returnType = null;}
{
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_FUNCTION>
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] functionName=OracleObjectName()
{
functionType = new FunctionType(functionName);
if (schema != null) {
functionType.setSchema(schema);
} }
[ <O_OPENPAREN> argumentList(functionType) <O_CLOSEPAREN> ] returnType=functionReturnSpec() [ <K_AS> | <K_IS> ]
skipToEnd()
{
functionType.setReturnArgument(returnType);
typesRepository.setDatabaseType(functionName, functionType);
return functionType;
}
}
// table at 'top-level'
TableType parseTable():
{
TableType tableType = null;
String schema = null;
String tableName = null;
Token iot = null;
}
{
<K_CREATE> [ <K_GLOBAL> <K_TEMPORARY> ] <K_TABLE>
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] tableName=OracleObjectName()
{
tableType = new TableType(tableName);
if (schema != null) {
tableType.setSchema(schema);
} }
<O_OPENPAREN> columnDeclarations(tableType) <O_CLOSEPAREN>
[ <K_ORGANIZATION> ] [ iot=<K_INDEX> ] [ <K_NOCOMPRESS> ] [ <K_OVERFLOW> ]
[ <K_ON> <K_COMMIT > [<K_DELETE> | <K_PRESERVE> ] <K_ROWS> ] <O_SEMICOLON>
<EOF>
{
if (iot != null) {
tableType.setIOT(true);
}
typesRepository.setDatabaseType(tableName, tableType);
return tableType;
}
}
// type at 'top-level'
CompositeDatabaseType parseType():
{CompositeDatabaseType databaseType = null;
DatabaseType enclosedType = null;
String schema = null;
String typeName = null;
Token vsize = null;
boolean varray = false;
boolean nestedTable = false;
}
{
<K_CREATE> [ <K_OR> <K_REPLACE> ] <K_TYPE>
[LOOKAHEAD(2) schema=OracleObjectName() <O_DOT> ] typeName=OracleObjectName()
[ <K_FORCE> ] [ <K_OID> <S_CHAR_LITERAL> ] [ <K_AUTHID> [ <K_CURRENT_USER> | <K_DEFINER> ] ]
( <K_AS> | <K_IS> )
[ <K_OBJECT> <O_OPENPAREN>
{
databaseType = new ObjectType(typeName);
if (schema != null) {
((ObjectType)databaseType).setSchema(schema); }
} columnDeclarations(databaseType) <O_CLOSEPAREN>
| <K_VARRAY> <O_OPENPAREN> vsize=<S_NUMBER> <O_CLOSEPAREN> <K_OF>
{ databaseType = new VArrayType(typeName);
if (schema != null) {
((VArrayType)databaseType).setSchema(schema);
}
if (vsize != null) {
Long size = Long.decode(vsize.image);
((VArrayType)databaseType).setSize(size);
}
} enclosedType=columnTypeSpec(databaseType)
| <K_TABLE> <K_OF> {
databaseType = new ObjectTableType(typeName);
if (schema != null) {
((ObjectTableType)databaseType).setSchema(schema);
} } enclosedType=columnTypeSpec(databaseType)
]
[ [ <K_NOT> ] ( <K_FINAL> | <K_INSTANTIABLE> ) ] [ <O_SEMICOLON> ]
<EOF>
{
if (enclosedType != null) {
((CompositeDatabaseType)databaseType).addCompositeType(enclosedType); }
typesRepository.setDatabaseType(typeName, databaseType);
return databaseType;
}
}
void columnDeclarations(CompositeDatabaseType enclosingType) #void:
{}
{
columnDeclaration(enclosingType) [ <O_COMMA> columnDeclarations(enclosingType) ]
}
void columnDeclaration(CompositeDatabaseType enclosingType) #void:
{String s = null;
String pk = null;
boolean notNull = false;
DatabaseType columnType = null;
FieldType column = null;
}
{
( LOOKAHEAD(2) s=OracleObjectName()
{
column = new FieldType(s);
if (enclosingType != null) {
enclosingType.addCompositeType(column);
} }
columnType=columnTypeSpec(enclosingType) [ <K_NOT> <K_NULL> <K_ENABLE> {notNull = true;} ]
| LOOKAHEAD(2)
[ <K_CONSTRAINT> ] [ OracleObjectName() ] <K_PRIMARY> <K_KEY>
<O_OPENPAREN> pkList((TableType)enclosingType) <O_CLOSEPAREN> <K_ENABLE>
)
{
if (column != null) {
column.setDataType(columnType);
if (columnType instanceof UnresolvedType) {
((UnresolvedType)columnType).setOwningType(column);
}
if (notNull) {
column.setNotNull();
}
}
}
}
DatabaseType columnTypeSpec(CompositeDatabaseType enclosingType):
{String s = null;
Token t = null;
DatabaseType dt = null;}
{
(
dt=datatype()
| s=columnSpec() [ <O_OPENPAREN> t=<S_NUMBER> <O_CLOSEPAREN> ]
)
{
if (s != null) {
for (String typeName : localTypes.keySet()) {
if (typeName.equals(s)) {
dt = localTypes.get(s);
break;
}
}
if (dt == null) {
if (t != null) {
Long size = Long.decode(t.image);
dt = new UnresolvedSizedType(s, size);
}
else {
dt = new UnresolvedType(s);
}
((UnresolvedType)dt).setOwningType(enclosingType);
}
}
return dt;
}
}
void pkList(TableType tableType) #void:
{}
{
pk(tableType) ( <O_COMMA> pk(tableType) )*
}
void pk(TableType tableType) #void:
{
String s = null;
}
{
s=OracleObjectName()
{
List<FieldType> columns = tableType.getColumns();
for (FieldType column : columns) {
if (column.getFieldName().equals(s)) {
column.setPk();
break;
}
} }
}
void packageDeclaration(PLSQLPackageType packageType) #void:
{}
{
LOOKAHEAD(2) variableDeclaration(packageType)
| typeOrSubTypeDeclaration(packageType)
| cursorDeclaration(packageType)
| procedureSpec(packageType)
| functionSpec(packageType)
| exceptionDeclaration(packageType)
| pragmaDeclaration(packageType)
}
void variableDeclaration(PLSQLPackageType packageType):
{Token varName = null;
DatabaseType varType;}
{
varName=<S_IDENTIFIER> [ <K_CONSTANT> ] varType=typeSpec() [ <K_NOT> <K_NULL> ]
[ variableDefaultAssignment() ]
<O_SEMICOLON>
{
FieldType variable = new FieldType(varName.image);
variable.setDataType(varType);
packageType.addLocalVariable(variable); } }
void variableDefaultAssignment() #void:
{}
{
( <O_ASSIGN> | <K_DEFAULT> ) skipToSemiColon()
}
DatabaseType datatype():
{Token t = null;
DatabaseType dt = null;
Token precision = null;
Long sl;
Long pl;
Token scale = null;
Token withTimeZone = null;
Token withLocalTimeZone = null;
}
{
<K_BINARY_INTEGER> { return BINARY_INTEGER_TYPE;}
| <K_BINARY_FLOAT> { return BINARY_FLOAT_TYPE;}
| <K_BINARY_DOUBLE> { return BINARY_DOUBLE_TYPE;}
| <K_NATURAL> { return NATURAL_TYPE;}
| <K_POSITIVE> { return POSITIVE_TYPE;}
| <K_SIGNTYPE> { return SIGN_TYPE;}
| ( 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> ]
{
if (t.kind == K_NUMBER || t.kind == K_NUMERIC) {
if (precision != null && precision.image.equals("*")) {
precision = null; }
if (precision == null) {
if (scale != null && scale.image.equals("0")) {
dt = INTEGER_TYPE; } else {
dt = new NumericType(); }
}
else {
pl = Long.decode(precision.image);
if (scale == null) {
dt = new NumericType(pl);
}
else {
sl = Long.decode(scale.image);
dt = new NumericType(pl, sl);
}
}
//sometimes need to know difference between NUMERIC and NUMBER
if (dt != INTEGER_TYPE && t.kind == K_NUMBER) {
((NumericType)dt).setNumberSynonym(true);
}
}
else if (t.kind == K_DECIMAL || t.kind == K_DEC) {
if (precision != null && precision.image.equals("*")) {
precision = null;
}
if (precision == null) {
dt = new DecimalType();
}
else {
pl = Long.decode(precision.image);
if (scale == null) {
dt = new DecimalType(pl);
}
else {
sl = Long.decode(scale.image);
dt = new DecimalType(pl, sl);
}
}
} return dt; }
| <K_LONG> [ t=<K_RAW> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] {
if (t == null) {
if (precision == null) {
dt = new LongType();
}
else {
pl = Long.decode(precision.image);
dt = new LongType(pl);
}
}
else {
if (precision == null) {
dt = new LongRawType();
}
else {
pl = Long.decode(precision.image);
dt = new LongRawType(pl);
}
}
return dt; }
| <K_RAW> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] {
if (precision == null) {
dt = new RawType();
}
else {
pl = Long.decode(precision.image);
dt = new RawType(pl);
}
return dt;
}
| <K_BOOLEAN> { return BOOLEAN_TYPE;}
| <K_DATE> { return DATE_TYPE;}
| LOOKAHEAD(2) <K_INTERVAL> <K_DAY> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] <K_TO> <K_SECOND> [ <O_OPENPAREN> scale=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (precision == null) {
dt = new IntervalDayToSecond();
}
else {
pl = Long.decode(precision.image);
if (scale == null) {
dt = new IntervalDayToSecond(pl);
}
else {
sl = Long.decode(scale.image);
dt = new IntervalDayToSecond(pl, sl);
}
}
return dt; }
| <K_INTERVAL> <K_YEAR> [ <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ] <K_TO> <K_MONTH> {
if (precision == null) {
dt = new IntervalYearToMonth();
}
else {
pl = Long.decode(precision.image);
dt = new IntervalYearToMonth(pl);
}
return dt; }
| <K_TIME> { return TIME_TYPE;}
| <K_TIMESTAMP> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
[ <K_WITH> [ withLocalTimeZone=<K_LOCAL> ] withTimeZone=<K_TIME> <K_ZONE> ]
{
if (precision == null) {
dt = new TimeStampType();
}
else {
pl = Long.decode(precision.image);
dt = new TimeStampType(pl);
}
if (withLocalTimeZone != null) {
((TimeStampType)dt).setWithLocalTimeZone(); }
else if (withTimeZone != null) {
((TimeStampType)dt).setWithTimeZone(); }
return dt; }
| <K_INTEGER> { return INTEGER_TYPE;}
| <K_INT> { return INTEGER_TYPE;}
| <K_SMALLINT> { return SMALLINT_TYPE;}
| <K_FLOAT> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (precision == null) {
return new FloatType();
}
else {
pl = Long.decode(precision.image);
FloatType ft = new FloatType(pl);
return ft; }
}
| <K_REAL> { return new RealType();}
| <K_MLSLABEL> { return MLSLABEL_TYPE;}
| <K_PLS_INTEGER> { return PLS_INTEGER_TYPE;}
| <K_SIMPLE_INTEGER> { return SIMPLE_INTEGER_TYPE;}
| <K_SIMPLE_FLOAT> { return SIMPLE_FLOAT_TYPE;}
| <K_SIMPLE_DOUBLE> { return SIMPLE_DOUBLE_TYPE;}
| <K_SYS_REFCURSOR> { return SYS_REFCURSOR_TYPE;}
| <K_BLOB > { return new BlobType();}
| <K_NCLOB> { return new NClobType();}
| <K_BFILE> { return BFILE_TYPE;}
| <K_ROWID> { return ROWID_TYPE;}
| <K_UROWID> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (precision == null) {
return new URowIdType();
}
else {
pl = Long.decode(precision.image);
return new URowIdType(pl);
} }
| <K_DOUBLE> <K_PRECISION> { return new DoubleType();}
| <K_CHAR> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] {
if (t == null) {
if (precision == null) {
return new CharType();
}
else {
pl = Long.decode(precision.image);
return new CharType(pl); }
}
else {
// ANSI syntax for VARCHAR2
if (precision == null) {
return new VarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new VarChar2Type(pl);
} } }
| <K_VARCHAR> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ]
{
if (precision == null) {
return new VarCharType();
}
else {
pl = Long.decode(precision.image);
return new VarCharType(pl);
}
}
| <K_VARCHAR2> [ <K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ]
{
if (precision == null) {
return new VarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new VarChar2Type(pl); } }
| <K_CHARACTER> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (t == null) {
if (precision == null) {
return new CharType();
}
else {
pl = Long.decode(precision.image);
return new CharType(pl);
}
}
else {
// ANSI syntax for VARCHAR
if (precision == null) {
return new VarCharType();
}
else {
pl = Long.decode(precision.image);
return new VarCharType(pl);
}
}
}
| <K_NCHAR> [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (t == null) {
if (precision == null) {
return new NCharType();
}
else {
pl = Long.decode(precision.image);
return new NCharType(pl);
}
}
else {
// ANSI syntax for NVARCHAR2
if (precision == null) {
return new NVarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new NVarChar2Type(pl);
}
}
}
| <K_NVARCHAR> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ] {
if (precision == null) {
return new NVarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new NVarChar2Type(pl);
} }
| <K_NVARCHAR2> [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (precision == null) {
return new NVarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new NVarChar2Type(pl);
}
}
| <K_NATIONAL> ( <K_CHARACTER> | <K_CHAR> ) [ t=<K_VARYING> ] [ <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN> ]
{
if (t == null) {
if (precision == null) {
return new NCharType();
}
else {
pl = Long.decode(precision.image);
return new NCharType(pl);
}
}
else {
// ANSI syntax for NVARCHAR2
if (precision == null) {
return new NVarChar2Type();
}
else {
pl = Long.decode(precision.image);
return new NVarChar2Type(pl);
}
}
}
| <K_CLOB> [ LOOKAHEAD(2) <K_CHARACTER> <K_SET> [ LOOKAHEAD(2) <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ] { return new ClobType();}
}
DatabaseType typeSpec():
{DatabaseType dataType = null;
String s = null;}
{
(
dataType=datatype()
|
s=columnSpec()
[
( <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ) |
<K_TYPE2> {s += tokenImage[K_TYPE2].substring(1, tokenImage[K_TYPE2].length() - 1);} |
<K_ROWTYPE> {s += tokenImage[K_ROWTYPE].substring(1, tokenImage[K_ROWTYPE].length() - 1);}
]
)
{
if (dataType == null && localTypes != null) {
for (String typeName : localTypes.keySet()) {
if (typeName.equals(s)) {
dataType = localTypes.get(s);
break;
}
}
}
if (dataType == null) {
dataType = new UnresolvedType(s);
}
return dataType; }
}
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(PLSQLPackageType packageType) #void:
{String s = null;}
{
typeDeclaration(packageType)
| subtypeDeclaration(packageType)
}
void typeDeclaration(PLSQLPackageType packageType) #void:
{String s = null;}
{
<K_TYPE> s=typeName() <K_IS> aTypeDeclaration(packageType, s) <O_SEMICOLON>
}
void aTypeDeclaration(PLSQLPackageType packageType, String typeName) #void:
{}
{
recordDeclaration(packageType, typeName)
| plsqlTableDeclaration(packageType, typeName)
| varrayDeclaration(packageType)
| refCursorDeclaration(packageType, typeName)
}
void recordDeclaration(PLSQLPackageType packageType, String typeName) #void:
{
PLSQLRecordType plsqlRecordType = new PLSQLRecordType(typeName);
plsqlRecordType.setParentType(packageType);
}
{
<K_RECORD> <O_OPENPAREN>
fieldDeclarations(plsqlRecordType)
<O_CLOSEPAREN>
{ packageType.addType(plsqlRecordType);
localTypes.put(typeName, plsqlRecordType);
}
}
void fieldDeclarations(PLSQLRecordType plsqlRecordType) #void:
{}
{
fieldDeclaration(plsqlRecordType) [ <O_COMMA> fieldDeclarations(plsqlRecordType) ]
}
void fieldDeclaration(PLSQLRecordType plsqlRecordType):
{
String s = null;
DatabaseType dataType = null;
FieldType fieldType = null;
}
{
s=typeName() dataType=typeSpec() [ <K_NOT> <K_NULL> ] [ fieldDefaultAssignment() ]
{
fieldType = new FieldType(s);
fieldType.setDataType(dataType);
plsqlRecordType.addCompositeType(fieldType);
if (dataType instanceof UnresolvedType) {
((UnresolvedType)dataType).setOwningType(plsqlRecordType);
} }
}
void fieldDefaultAssignment() #void:
{}
{
( <O_ASSIGN> | <K_DEFAULT> ) skipToNextArg()
}
void subtypeDeclaration(PLSQLPackageType packageType) #void:
{String subtypeName;
DatabaseType subtype;
Token notNull = null;
Token rangeStart = null;
Token rangeEnd = null;}
{
<K_SUBTYPE> subtypeName=OracleObjectName() <K_IS> subtype=typeSpec()
[ <K_RANGE> rangeStart=<S_NUMBER> <O_DOUBLEDOT> rangeEnd=<S_NUMBER> ]
[ <K_NOT> notNull=<K_NULL> ] <O_SEMICOLON>
{
PLSQLSubType newPLSQLSubType = new PLSQLSubType(subtypeName);
newPLSQLSubType.addCompositeType(subtype);
if (subtype instanceof UnresolvedType) {
((UnresolvedType)subtype).setOwningType(newPLSQLSubType); }
packageType.addType(newPLSQLSubType);
if (notNull != null) {
newPLSQLSubType.setNotNull(true); }
if (rangeStart != null) {
long rStart = Long.decode(rangeStart.image).longValue();
long rEnd = Long.decode(rangeEnd.image).longValue();
newPLSQLSubType.setHasRange(true);
newPLSQLSubType.setRangeStart(rStart);
newPLSQLSubType.setRangeEnd(rEnd); }
localTypes.put(subtypeName, newPLSQLSubType);
}
}
void plsqlTableDeclaration(PLSQLPackageType packageType, String typeName) #void:
{
PLSQLCollectionType plsqlTable = new PLSQLCollectionType(typeName);
plsqlTable.setParentType(packageType);
DatabaseType nestedType;
}
{
<K_TABLE> <K_OF> nestedType = typeSpec() [ <K_NOT> <K_NULL> ]
[ <K_INDEX> <K_BY> plsqlTableIndexByDeclaration(plsqlTable) ]
{
if (nestedType instanceof UnresolvedType) {
((UnresolvedType)nestedType).setOwningType(plsqlTable); }
plsqlTable.addCompositeType(nestedType);
packageType.addType(plsqlTable);
// TODO - TBD typesRepository.setDatabaseType(typeName, plsqlTable);
localTypes.put(typeName, plsqlTable);
}
}
void plsqlTableIndexByDeclaration(PLSQLCollectionType plsqlTable) #void:
{
DatabaseType indexType = null;
Token precision = null;
Token otherIndexByType = null;
}
{
( <K_PLS_INTEGER> {indexType = PLS_INTEGER_TYPE; }
| <K_BINARY_INTEGER> {indexType = BINARY_INTEGER_TYPE; }
| <K_VARCHAR2> <O_OPENPAREN> precision=<S_NUMBER> <O_CLOSEPAREN>
{
if (precision == null) {
indexType = new VarChar2Type();
}
else {
Long pl = Long.decode(precision.image);
indexType = new VarChar2Type(pl);
}
}
| otherIndexByType=<K_STRING> <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN>
{
String indexTypename = otherIndexByType.image;
for (String typeName : localTypes.keySet()) {
if (typeName.equals(indexTypename)) {
indexType = localTypes.get(indexTypename);
break;
}
}
//what else can INDEX BY be? Unresolved for now ...
if (indexType == null) {
indexType = new UnresolvedType(indexTypename);
((UnresolvedType)indexType).setOwningType(plsqlTable);
}
}
)
{ plsqlTable.setIndexed(true);
plsqlTable.setIndexType(indexType);
}
}
void varrayDeclaration(PLSQLPackageType packageType) #void:
{}
{
( <K_VARRAY> | <K_VARYING> <K_ARRAY> ) <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN>
<K_OF> datatype() [ <K_NOT> <K_NULL> ]
}
void refCursorDeclaration(PLSQLPackageType packageType, String cursorTypeName) #void:
{PLSQLCursorType cursorType = null;}
{
<K_REF> <K_CURSOR>
{
cursorType = new PLSQLCursorType(cursorTypeName);
packageType.addCursor(cursorType);
localTypes.put(cursorTypeName, cursorType);
}
[ refCursorTypeSpec(cursorType) ]
}
void refCursorTypeSpec(PLSQLCursorType cursorType) #void:
{String s = null;}
{
<K_RETURN> [LOOKAHEAD(3) s=columnSpec() [ <K_TYPE2>
{
s += tokenImage[K_TYPE2].substring(1, tokenImage[K_TYPE2].length() - 1);
}
]
| LOOKAHEAD(3) s=tableSpec() [ <K_ROWTYPE>
{
s += tokenImage[K_ROWTYPE].substring(1, tokenImage[K_ROWTYPE].length() - 1);
}
]
]
{
DatabaseType localType = localTypes.get(s);
if (localType == null) { cursorType.setDataType(new UnresolvedType(s));
}
else {
cursorType.setDataType(localType); } }
}
void cursorDeclaration(PLSQLPackageType packageType) #void:
{Token t = null;}
{
<K_CURSOR> t=<S_IDENTIFIER>
<O_SEMICOLON>
}
// Procedure Specification
void procedureSpec(PLSQLPackageType packageType) #void:
{Token t = null;
ProcedureType procedureType = null;
}
{
<K_PROCEDURE> t=<S_IDENTIFIER> {
procedureType = new ProcedureType(t.image);
procedureType.setCatalogName(packageType.getPackageName());
procedureType.setSchema(packageType.getSchema()); }
[ <O_OPENPAREN> argumentList(procedureType) <O_CLOSEPAREN> ]
<O_SEMICOLON>
{ packageType.addProcedure(procedureType);
}
}
void argumentList(ProcedureType procedureType) #void:
{}
{
argument(procedureType) ( <O_COMMA> argument(procedureType) )*
}
// Function Specification
void functionSpec(PLSQLPackageType packageType) #void:
{Token t = null;
FunctionType functionType = null;
ArgumentType returnDataType = null;
}
{
<K_FUNCTION> t=<S_IDENTIFIER>
{
functionType = new FunctionType(t.image);
functionType.setCatalogName(packageType.getPackageName());
functionType.setSchema(packageType.getSchema());
}
[ <O_OPENPAREN> argumentList(functionType) <O_CLOSEPAREN> ]
returnDataType = functionReturnSpec()
[ <K_DETERMINISTIC> | <K_PIPELINED> | <K_PARALLEL_ENABLE> | <K_RESULT_CACHE> ]
<O_SEMICOLON>
{
functionType.setReturnArgument(returnDataType);
packageType.addProcedure(functionType);
}
}
ArgumentType functionReturnSpec():
{DatabaseType dataType = null;} { (<K_RETURN> dataType=typeSpec())
{
ArgumentType returnType = new ArgumentType(null);
returnType.setDirection(ArgumentTypeDirection.RETURN);
returnType.setDataType(dataType);
if (dataType instanceof UnresolvedType) {
((UnresolvedType)dataType).setOwningType(returnType); }
return returnType;
}
}
void argument(ProcedureType procedureType) #void:
{Token t = null;
ArgumentType argumentType = null;
DatabaseType argumentDataType = null;
ArgumentTypeDirection argDirection = ArgumentTypeDirection.IN; // by default, arguments are IN
String direction = null;
boolean defaultAssignment = false;
}
{
t=<S_IDENTIFIER> [(direction=direction())]
[ <K_NOCOPY> ] argumentDataType=typeSpec() [ defaultAssignment=argumentDefaultAssignment() ]
{
argumentType = new ArgumentType(t.image);
argumentType.setDataType(argumentDataType);
if (argumentDataType instanceof UnresolvedType) {
((UnresolvedType)argumentDataType).setOwningType(argumentType);
}
if (direction != null) {
if ("OUT".equals(direction)) {
argDirection = ArgumentTypeDirection.OUT;
}
else if ("IN OUT".equals(direction)) {
argDirection = ArgumentTypeDirection.INOUT; }
argumentType.setDirection(argDirection); } if (defaultAssignment) {
argumentType.setOptional(); }
procedureType.addCompositeType(argumentType);
}
}
String direction() #void:
{}
{
LOOKAHEAD(2) <K_IN> <K_OUT> { return "IN OUT"; }
| <K_IN> { return "IN"; }
| <K_OUT> { return "OUT"; }
}
boolean argumentDefaultAssignment():
{}
{
( <O_ASSIGN> | <K_DEFAULT> ) skipToNextArg()
{
return true;
}
}
void exceptionDeclaration(PLSQLPackageType packageType) #void:
{}
{
<S_IDENTIFIER> <K_EXCEPTION> <O_SEMICOLON>
}
void pragmaDeclaration(PLSQLPackageType packageType) #void:
{}
{ <K_PRAGMA>
[ <K_AUTONOMOUS_TRANSACTION>
| <K_EXCEPTION_INIT> <O_OPENPAREN> <S_IDENTIFIER> <O_COMMA> <S_NUMBER> <O_CLOSEPAREN>
| <K_SERIALLY_REUSABLE>
| <K_INLINE> <O_OPENPAREN> <S_IDENTIFIER> <O_COMMA> [ <K_YES> | <K_NO> ] <O_CLOSEPAREN>
| <K_RESTRICT_REFERENCES> <O_OPENPAREN> [ <S_IDENTIFIER> | <K_DEFAULT> ]
( <O_COMMA> [ <K_RNDS> | <K_WNDS> | <K_RNPS> | <K_WNPS> | <K_TRUST>] )+ <O_CLOSEPAREN>
]
<O_SEMICOLON>
}
String OracleObjectName() #void:
{}
{
<S_IDENTIFIER>
{return token.image;}
| <S_QUOTED_IDENTIFIER>
{
String s = token.image;
return s.substring(1, s.length() - 1); // strip-off quotes
}
}
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();
}
}
}