📄 plsqlgrammar.g
字号:
|column_spec
|boolean_literal
;
plsql_exp_list:
plsql_expression (COMMA plsql_expression)*
;
char_expression:
char_term ("||" char_term)*
;
char_term:
(char_literal
|variable_name
|host_variable
|(function (OPEN_PAREN plsql_exp_list CLOSE_PAREN)?)
|(OPEN_PAREN! char_expression CLOSE_PAREN!)
|"null")
;
char_literal:
QUOTED_STRING
;
date_expression :
( date_literal
| variable_name
| host_variable
| ( function (OPEN_PAREN plsql_exp_list CLOSE_PAREN)? )
| ( OPEN_PAREN! date_expression CLOSE_PAREN! )
| "null" )
;
date_literal:
QUOTED_STRING
;
commit_statement:
"commit"
;
//Added the greedy funda on 21st of August
if_statement:
"if"^ plsql_condition "then" seq_of_statements
("elsif" plsql_condition "then" seq_of_statements)*
("else" seq_of_statements )?
"end""if"
;
//Removed the (SEMI)? after the sql_command as sql_statement already comes under statement
sql_statement:
sql_command
{ #sql_statement = #([SQL_STATEMENT, "sql_statement"], #sql_statement); }
;
sql_command:
to_modify_data
| to_control_data
;
to_modify_data:
select_command
| insert_command
| update_command
// | delete_command
| set_transaction_command
;
to_control_data:
close_statement
| commit_statement
| fetch_statement
| lock_table_statement
| open_statement
| rollback_statement
| savepoint_statement
;
select_command:
select_statement ( "union" select_statement )*
{ #select_command = #([SELECT_COMMAND, "select_command"], #select_command); }
;
select_statement:
( OPEN_PAREN! select_command CLOSE_PAREN! ) => OPEN_PAREN! select_command CLOSE_PAREN!
| select_expression
;
select_expression:
"select"^ ( "all"! | "distinct"! )? select_list
("into" column_name)?
//"from" table_reference_list
table_reference_list_from
//( "where" where_condition )?
(where_condition_whole)?
( connect_clause )?
( group_clause )?
( ( set_clause ) => set_clause )?
( ( order_clause ) => order_clause )?
( ( update_clause ) => update_clause )?
{ #select_expression = #([SELECT_EXPRESSION,"select_expression"], #select_expression); }
;
select_list:
( ( displayed_column ) => displayed_column ( COMMA displayed_column )*
| ASTERISK )
{ #select_list = #([SELECT_LIST, "select_list"], #select_list); }
;
table_reference_list_from:
"from" selected_table ( COMMA! selected_table )*
{ #table_reference_list_from = #([TABLE_REFERENCE_LIST, "table_reference_list_from"], #table_reference_list_from); }
;
table_reference_list:
selected_table ( COMMA selected_table )*
{ #table_reference_list = #([TABLE_REFERENCE_LIST, "table_reference_list"], #table_reference_list); }
;
where_condition_whole:
"where" condition
;
where_condition:
condition
{ #where_condition = #([WHERE_CONDITION, "where_condition"], #where_condition); }
;
displayed_column :
( (schema_name DOT)? (variable)? table_name DOT ASTERISK ) => ( ( schema_name DOT )? table_name DOT ASTERISK )
| ( exp_simple ( alias )? )
;
schema_name:
identifier
;
table_name:
identifier
;
exp_simple:
expression
;
expression:
term ( ( PLUS | MINUS ) term )*
| boolean_literal
;
alias:
( "as" )? identifier
;
term:
factor ( ( multiply | DIVIDE ) factor )*
;
multiply:
ASTERISK
{ #multiply = #([MULTIPLY, "multiply"], #multiply); }
;
factor:
factor2 ( VERTBAR VERTBAR factor2 )*
;
factor2:
( sql_literal ) => sql_literal
| ( ( PLUS | MINUS ) expression ) => ( PLUS | MINUS ) expression
| ( function ( OPEN_PAREN! expression ( COMMA expression )* CLOSE_PAREN ) ) => function ( OPEN_PAREN expression ( COMMA expression )* CLOSE_PAREN )
//Commented by Qazi on 28th of August
//{ #factor2 = #([FUNCTION, "function"], #factor2); }
| ( group_function OPEN_PAREN ( ASTERISK | "all" | "distinct" )? (expression)? CLOSE_PAREN ) => group_function OPEN_PAREN ( ASTERISK | "all" | "distinct" )? (expression)? CLOSE_PAREN
//{ #factor2 = #([GROUP_FUNCTION, "group_function"], #factor2); }
| ( user_defined_function ( OPEN_PAREN expression ( COMMA expression )* CLOSE_PAREN ) ) => user_defined_function ( OPEN_PAREN expression ( COMMA expression )* CLOSE_PAREN )
//{ #factor2 = #([USER_FUNCTION, "user_function"], #factor2); }
| ( OPEN_PAREN! expression CLOSE_PAREN! ) => OPEN_PAREN! expression CLOSE_PAREN!
| ( variable ) => variable
| expression_list
;
expression_list:
OPEN_PAREN! expression ( COMMA expression )+ CLOSE_PAREN!
;
sql_literal:
( NUMBER | QUOTED_STRING | "null" )
{ #sql_literal = #([SQL_LITERAL, "sql_literal"], #sql_literal); }
;
variable:
( column_spec ( OPEN_PAREN! PLUS CLOSE_PAREN! ) ) => column_spec ( OPEN_PAREN! PLUS CLOSE_PAREN! )
| column_spec
;
column_spec:
( ( schema_name DOT )? table_name DOT )? column_name
;
user_defined_function:
( ( schema_name DOT )? package_name DOT )? identifier
;
column_name:
identifier
;
function:
number_function
| char_function
| group_function
| conversion_function
| other_function
;
number_function:
"abs" | "ceil" | "floor" | "mod" | "power" | "round"
| "sign" | "sqrt" | "trunc"
;
char_function:
"chr" | "initcap" | "lower" | "lpad" | "ltrim" | "replace"
| "rpad" | "rtrim" | "soundex" | "substr" | "translate" | "upper"
| "ascii" | "instr" | "length"
| "concat"
;
group_function:
"avg" | "count" | "max" | "min" | "stddev" | "sum"
| "variance"
;
conversion_function:
"chartorowid" | "convert" | "hextoraw" | "rawtohex" | "rowidtochar"
| "to_char" | "to_date" | "to_number"
;
other_function
:
"decode" | "dump" | "greatest" | "least" | "nvl"
| "uid" | "userenv" | "vsize"
;
pseudo_column:
"user" | "sysdate"
;
selected_table:
( table_spec | subquery ) ( alias )?
;
table_spec:
( schema_name DOT )? table_name ( AT_SIGN link_name )?
;
table_alias:
( schema_name DOT )? table_name ( AT_SIGN link_name )? ( alias )?
;
link_name:
identifier
;
condition:
logical_term ( "or" logical_term )*
;
logical_term:
logical_factor ( "and" logical_factor )*
;
logical_factor:
( ( "prior" ) ? exp_simple relational_op ( "prior" )? exp_simple ) => ( ( "prior" ) ? exp_simple relational_op ( "prior" )? exp_simple )
| ( exp_simple ( "not" )? "in" ) => exp_simple ("not")? "in" exp_set
| ( exp_simple ( "not" )? "like" ) => exp_simple ( "not" )? "like" expression ( "escape" QUOTED_STRING )?
| ( exp_simple ( "not" )? "between" ) => exp_simple ( "not" )? "between" exp_simple "and" exp_simple
| ( exp_simple "is" ( "not" )? "null" ) => exp_simple "is" ( "not" )? "null"
| ( quantified_factor ) => quantified_factor
| ( "not" condition ) => "not" condition
| ( OPEN_PAREN! condition CLOSE_PAREN! )
;
quantified_factor:
( exp_simple relational_op ( "all" | "any" )? subquery ) => exp_simple relational_op ( "all" | "any" )? subquery
| ( ( "not" )? "exists" subquery ) => ( "not" )? "exists" subquery
| subquery
;
relational_op:
EQ | LT | GT | NOT_EQ | LE | GE
;
exp_set:
( exp_simple ) => exp_simple
| subquery
;
subquery:
OPEN_PAREN! select_command CLOSE_PAREN!
{ #subquery = #([SUBQUERY, "subquery"], #subquery); }
;
connect_clause:
( "start" "with" condition )? // the start can be before the connect by
"connect" "by"
// This appears to allow multiple comparisons, so just use the updated
// condition rule.
( ( "prior" exp_simple relational_op exp_simple )
| ( exp_simple relational_op exp_simple "prior" ) )
( ( ( "prior" )? condition ) => ("prior")? condition
// Qazi made a change here replace ? with *
| exp_simple relational_op ( "prior" )? exp_simple ( "and" condition )?
)
condition
( "start" "with" condition )?
;
group_clause:
"group" "by" expression ( COMMA expression )* ( "having" condition )?
;
// Would this really do what is necessary? The following does not look
// right, but not that familiar with what is being refered to here.
set_clause:
( ( "union" "all" ) | "intersect" | "minus" ) select_command
;
order_clause:
"order" "by" sorted_def ( COMMA sorted_def )*
;
sorted_def:
(( expression ) => expression | ( NUMBER ) => NUMBER ) ( "asc" | "desc" )?
;
update_clause:
"for" "update" ( "of" column_name ( COMMA column_name )* )? ( "nowait" )?
;
//In the Insert statement insted of plsql_exp_list, modified it to variable_name,
//and character literals.
insert_command:
"insert" "into" table_reference_list
( OPEN_PAREN! column_spec CLOSE_PAREN! )?
( ( "values" OPEN_PAREN! (variable_name) (COMMA variable_name)* CLOSE_PAREN! )
| select_statement )
;
update_command:
( subquery_update ) => subquery_update
| simple_update
;
simple_update:
"update" table_alias
"set" column_spec EQ ( ( expression ) => expression | subquery )
( COMMA column_spec EQ ( ( expression ) => expression | subquery ) )*
"where" condition
;
subquery_update:
"update" table_alias
"set" OPEN_PAREN! column_spec ( COMMA column_spec )* CLOSE_PAREN! EQ subquery
"where" condition
;
set_transaction_command:
"set" "transaction" "read" "only"
;
close_statement :
"close" cursor_name
;
fetch_statement:
"fetch" cursor_name "into"
( ( variable_name (COMMA variable_name )* )
| record_name )
;
lock_table_statement:
"lock" "table" table_reference_list
"in" lock_mode "mode" ( "nowait" )?
;
lock_mode:
"row" "share"
|"row" "exclusive"
|"share" "update"
|"share"
|"share""row""exclusive"
|"exclusive"
;
open_statement:
"open" cursor_name (OPEN_PAREN! plsql_exp_list! CLOSE_PAREN!)?
;
rollback_statement:
"rollback" ( "work" )?
( "to" ( "savepoint" )? savepoint_name )?
( "comment" quoted_string )?
;
savepoint_statement:
"savepoint" savepoint_name
;
savepoint_name:
identifier
;
// Direct mappings to lexer.
identifier:
( IDENTIFIER | QUOTED_STRING | keyword )
;
quoted_string : QUOTED_STRING ;
match_string : QUOTED_STRING ;
//
// These are non reserve words that can be used as identifiers. If it is
// a reserved word in Oracle but not ANSI, that is noted and commented out
// (can not be used). If it is a reserve word in ANSI and not in Oracle,
// that is noted but it is not commented out (can be used).
//
keyword
:
"abs"
| "ascii"
| "ceil"
| "chartorowid"
| "chr"
| "concat"
| "convert"
| "count"
| "decode"
| "dump"
| "floor"
| "greatest"
| "hextoraw"
| "initcap"
| "instr"
| "intersect"
| "least"
| "length"
| "lower"
| "lpad"
| "ltrim"
// | "max" // oracle
// | "min" // oracle
// | "minus" // oracle
// | "mod" // oracle
// | "not" // oracle
// | "nowait" // oracle
| "nvl"
| "power"
// | "prior" // oracle
| "rawtohex"
| "replace"
| "round"
| "rowidtochar"
| "rpad"
| "rtrim"
| "sign"
| "soundex"
| "sqrt"
// | "stddev" // oracle
| "substr"
// | "sum" // oracle
| "sysdate"
| "to_char"
| "to_date"
| "to_number"
| "translate"
| "trunc"
// | "uid" // oracle
| "upper"
| "user" // ansi
| "userenv"
// | "variance" // oracle
| "vsize"
;
//Below code deals with TreeWalker part that extends TreeParser
class PLSqlTreeWalker extends TreeParser;
options {
exportVocab = PLSql;
k = 4;
buildAST = true;
}
start_rule:
(create_package)* EOF
;
create_package:
"create" ( "or" "replace" )?
(package_spec | package_body)?
;
package_spec:
"package" package_name ("is" | "as")
package_obj_spec ( package_obj_spec )*
"end" (package_name)? SEMI!
;
package_body:
"package" ("body")? package_name ("is" | "as")
package_obj_body ( package_obj_body )*
("begin")? (seq_of_statements)?
"end" (package_name )? SEMI!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -