⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plsqlgrammar.g

📁 一个实现PLSQL语法分析的语法分析软件。
💻 G
📖 第 1 页 / 共 4 页
字号:
	|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 + -