Skip to content

Instantly share code, notes, and snippets.

@mwnorman
Created March 9, 2012 15:58
Show Gist options
  • Save mwnorman/2007231 to your computer and use it in GitHub Desktop.
Save mwnorman/2007231 to your computer and use it in GitHub Desktop.
stripped down JavaCC grammar for TABLE ddl
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; LOOKAHEAD = 2;
FORCE_LA_CHECK = true;
}
PARSER_BEGIN(TestParser)
package scratchpad.testparser;
public class TestParser {
public TestParser() {
super();
}
}
PARSER_END(TestParser)
// white-space
SKIP: { " " | "\t" | "\n" | "\r" | "\f" }
// comments
SKIP: { <COMMENT_LINE: "--" (~["\n","\r"])* ("\n"|"\r"|"\r\n") > }
SKIP:{ <COMMENT_BLOCK: "/*" (~["*"])* "*" ("*" | (~["*","/"] (~["*"])* "*"))* "/"> }
/*
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
keywordsThatCanBeIdentifiers() production
*/
TOKEN: {
<R_CREATE: "CREATE"> | <R_INDEX: "INDEX"> | <R_NOCOMPRESS: "NOCOMPRESS"> | <R_NOT: "NOT">
| <R_NULL: "NULL"> | <R_OF: "OF"> | <R_ON: "ON"> | <R_OR: "OR"> | <R_TABLE: "TABLE">
| <K_BINARY_INTEGER: "BINARY_INTEGER"> | <K_BYTE: "BYTE"> | <K_CHAR: "CHAR">
| <K_CHARACTER: "CHARACTER"> | <K_CHARSET: "CHARSET"> | <K_COMMIT: "COMMIT">
| <K_CONSTRAINT: "CONSTRAINT"> | <K_DATE :"DATE"> | <K_DEC: "DEC">
| <K_DECIMAL: "DECIMAL"> | <K_DELETE: "DELETE"> | <K_DETERMINISTIC: "DETERMINISTIC">
| <K_DOUBLE: "DOUBLE"> | <K_ENABLE: "ENABLE"> | <K_GLOBAL: "GLOBAL">
| <K_INTEGER: "INTEGER"> | <K_KEY: "KEY"> | <K_NUMBER: "NUMBER">
| <K_NUMERIC: "NUMERIC"> | <K_OID: "OID"> | <K_ORGANIZATION: "ORGANIZATION">
| <K_OVERFLOW: "OVERFLOW"> | <K_PRESERVE: "PRESERVE"> | <K_PRIMARY: "PRIMARY">
| <K_ROWID:"ROWID"> | <K_SET: "SET"> | <K_TEMPORARY: "TEMPORARY">
| <K_TIME: "TIME"> | <K_TIMESTAMP: "TIMESTAMP"> | <K_VARCHAR2: "VARCHAR2">
| <K_VARCHAR: "VARCHAR"> | <K_VARRAY: "VARRAY"> | <K_VARYING: "VARYING">
}
String keywordsThatCanBeIdentifiers() #void: {}
{
(
<K_BINARY_INTEGER> | <K_BYTE> | <K_CHAR> | <K_CHARACTER> | <K_CHARSET> | <K_COMMIT>
| <K_CONSTRAINT> | <K_DATE> | <K_DEC> | <K_DECIMAL> | <K_DELETE> | <K_DETERMINISTIC>
| <K_DOUBLE> | <K_ENABLE> | <K_GLOBAL> | <K_INTEGER> | <K_KEY> | <K_NUMBER> | <K_NUMERIC>
| <K_OID> | <K_ORGANIZATION> | <K_OVERFLOW> | <K_PRESERVE> | <K_PRIMARY> | <K_ROWID>
| <K_SET> | <K_TEMPORARY> | <K_TIME> | <K_TIMESTAMP> | <K_VARCHAR2> | <K_VARCHAR> | <K_VARRAY>
| <K_VARYING>
)
{
return getToken(0).image.toUpperCase();
}
}
// separators and operators (prefix with O_ to avoid naming conflicts)
TOKEN: {
<O_ASTERISK: "*"> | <O_CLOSEPAREN: ")">
| <O_COMMA: ","> | <O_DOT: ".">
| <O_DOLLAR: "$"> | <O_PERCENT: "%"> | <O_EQUAL: "="> | <O_GREATER: ">">
| <O_LESS: "<"> | <O_MINUS: "-"> | <O_NOTEQUAL2: "<>"> | <O_NOTEQUAL: "!="> | <O_OPENPAREN: "(">
| <O_PLUS: "+"> | <O_POUND: "#"> | <O_QUESTIONMARK: "?"> | <O_SEMICOLON: ";">
}
// 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","\""])* "\"" >
}
void parseTable(): {}
{
<R_CREATE> [ <K_GLOBAL> <K_TEMPORARY> ] <R_TABLE>
[ OracleObjectName() <O_DOT> ] OracleObjectName()
<O_OPENPAREN> columnDeclarations() <O_CLOSEPAREN>
[ <K_ORGANIZATION> ] [ <R_INDEX> ] [ <R_NOCOMPRESS> ] [ <K_OVERFLOW> ]
[ <R_ON> <K_COMMIT> [ <K_DELETE> | <K_PRESERVE> ] <K_ROWID> ] <O_SEMICOLON>
<EOF>
}
void columnDeclarations() #void: {}
{
columnDeclaration() [ <O_COMMA> columnDeclarations() ]
}
void columnDeclaration() #void: {}
{
(
OracleObjectName() columnTypeSpec() [ <R_NOT> <R_NULL> <K_ENABLE> ]
| [<K_CONSTRAINT> ] [ OracleObjectName() ] <K_PRIMARY> <K_KEY>
<O_OPENPAREN> pkList() <O_CLOSEPAREN> <K_ENABLE>
)
}
void columnTypeSpec(): {}
{
(
datatype()
| columnSpec() [ <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ]
)
}
void columnSpec() #void: {}
{
OracleObjectName() [ <O_DOT> OracleObjectName() [ <O_DOT> OracleObjectName() ] ]
}
void pkList() #void: {}
{
pk() ( <O_COMMA> pk() )*
}
void pk() #void: {}
{
OracleObjectName()
}
void datatype(): {}
{
<K_BINARY_INTEGER>
| ( <K_NUMBER>
| <K_NUMERIC>
| <K_DECIMAL>
| <K_DEC>
) [ <O_OPENPAREN> [ <O_ASTERISK > | <S_NUMBER> ] ( <O_COMMA> <S_NUMBER> )* <O_CLOSEPAREN> ]
| <K_DATE>
| <K_TIME>
| <K_INTEGER>
| <K_CHAR> [ <K_VARYING> ] [ <O_OPENPAREN> <S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ <K_CHARACTER> <K_SET> [ <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ]
| <K_VARCHAR> [ <K_VARYING> ] [ <O_OPENPAREN> <S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ <K_CHARACTER> <K_SET> [ <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ]
| <K_VARCHAR2> [ <K_VARYING> ] [ <O_OPENPAREN> <S_NUMBER> [ <K_BYTE> | <K_CHAR> ] <O_CLOSEPAREN> ]
[ <K_CHARACTER> <K_SET> [ <S_IDENTIFIER> | columnSpec() <K_CHARSET> ] ]
| <K_CHARACTER> [ <K_VARYING> ] [ <O_OPENPAREN> <S_NUMBER> <O_CLOSEPAREN> ]
}
void OracleObjectName() #void: {}
{
<S_IDENTIFIER>
| <S_QUOTED_IDENTIFIER>
| keywordsThatCanBeIdentifiers()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment