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

📄 plsqlgrammar.g

📁 一个实现PLSQL语法分析的语法分析软件。
💻 G
📖 第 1 页 / 共 4 页
字号:
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

PROJECT:        PL/SQL Grammer
FILE:           PLSQLGrammar.g

AUTHOR: Qazi Firdous Ahmed (qazif_ahmed@infosys.com) 
		Krupa Benhur (krupa_bg@infosys.com)
		Manojaba Banerjee (manojaba_banerjee@infosys.com)
		Infosys Technologies Ltd., Bangalore, India

DATED:		Sept 18, 2002

DESCRIPTION:    This grammar is for PL/SQL.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/


header
{
package MyParser;
}

class PLSqlParser extends Parser;

options {
    exportVocab = PLSql;
    k = 4;
    buildAST = true;
}


tokens {
    START_RULE;
    CREATE_PACKAGE;
    PACKAGE_SPEC;
    PACKAGE_BODY;
    SELECT_EXPRESSION<AST=SELECT_EXPRESSIONNode>;
    PLSQL_BLOCK;
    CURSOR_DECLARATION;
    PARAMETER_SPEC;
    SQL_STATEMENT;
    SELECT_COMMAND;
    SELECT_LIST;
    TABLE_REFERENCE_LIST;
    WHERE_CONDITION;
    SUBQUERY;
    SQL_IDENTIFIER;
    SQL_LITERAL;
    FUNCTION;
    GROUP_FUNCTION;
    USER_FUNCTION;
    MULTIPLY;
    ARGUMENT;
}

start_rule: (create_package)* EOF
	    { #start_rule = #([START_RULE, "start_rule"], #start_rule); }
	  ;

create_package: 
	"create" ( "or" "replace" )?
	(package_spec | package_body)?
	{ #create_package = #([CREATE_PACKAGE, "create_package"], #create_package); }
	;
	
package_spec:
	"package" package_name ("is" | "as") 
	package_obj_spec ( package_obj_spec )*
	"end" (package_name)? SEMI!
	{ #package_spec = #([PACKAGE_SPEC, "package_spec"], #package_spec); }
	;
	
package_body: 
	"package" ("body")? package_name ("is" | "as")
	package_obj_body ( package_obj_body )*
	("begin")? (seq_of_statements)?  
	"end" (package_name )? SEMI!
	{ #package_body = #([PACKAGE_BODY, "package_body"], #package_body); }
	;
		
	
package_name:
	(schema_name DOT)? identifier 
	;
		

package_obj_spec:
	variable_declaration 
	| subtype_declaration 
	| cursor_declaration 
	| cursor_spec 
	| exception_declaration 
	| record_declaration 
	| plsql_table_declaration 
	| procedure_spec 
	| function_spec 
	;
	
variable_declaration: 
	variable_name ("constant")?
	type_spec ("not" "null")? 
	((ASSIGNMENT_EQ|"default") plsql_expression)? SEMI!
      	;	
      	
subtype_declaration 
      	:
      	"subtype" type_name "is" type_spec SEMI!
      	;      	
      	
cursor_declaration:
	"cursor" cursor_name
      	(OPEN_PAREN! parameter_spec! (COMMA! parameter_spec!)* CLOSE_PAREN! )?
      	"is"! select_command SEMI! 
      	{ #cursor_declaration = #([CURSOR_DECLARATION, "cursor_declaration"], #cursor_declaration); }
      	;

package_obj_body: 
	variable_declaration 
	| subtype_declaration 
	| cursor_declaration 
	| exception_declaration 
	| record_declaration 
	| plsql_table_declaration 
	| procedure_body 
	| function_body 
	;

seq_of_statements: 
	statement SEMI!
	(statement SEMI!)*
	;  
	
statement:
	 assignment_statement
	| exit_statement
	| goto_statement
	| if_statement 
	| loop_statement 
	| null_statement
	| raise_statement
	| return_statement
	| sql_statement
//	| plsql_block
	| begin_block
	| function_call
	;
		
plsql_block:
	( START_LABEL label_name END_LABEL )?
	(("declare")? (declare_spec)+)? 
	("begin")?
     	seq_of_statements
     	("exception" exception_handler (exception_handler)*)? 
     	("end" (label_name)? SEMI!)?
     	{ #plsql_block = #([PLSQL_BLOCK, "plsql_block"], #plsql_block); }
     	;
      	
declare_spec:
	variable_declaration 
	| subtype_declaration 
	| cursor_declaration 
	| exception_declaration 
	| exception_pragma 
	| record_declaration 
	| plsql_table_declaration 
	| procedure_declaration 
	| function_declaration
	;

assignment_statement: 
	(object ASSIGNMENT_EQ function_call) => (object ASSIGNMENT_EQ function_call)
	|(object ASSIGNMENT_EQ plsql_expression)  => (object ASSIGNMENT_EQ plsql_expression)
	|function_call
	;

object: 
	variable_name
	| ( record_name DOT field_name ) 
	| ( plsql_table_name OPEN_PAREN! subscript CLOSE_PAREN! ) 
	| ( COLON host_variable ) 
	;

field_name:
	identifier
	;
	
subscript:
	plsql_expression 
	;
	
host_variable:
	identifier
	;
	
goto_statement:
	"goto" label_name
	;
	
label_name:
	identifier
	;	

exit_statement:
	"exit" (label_name)? ("when" plsql_condition)?
	;
	
datatype:
	"binary_integer" 
      	| "natural" 
      	| "positive" 
      	| ("number"(OPEN_PAREN! NUMBER (COMMA NUMBER)? CLOSE_PAREN! )? ) 
      	| ( "char" (OPEN_PAREN! NUMBER CLOSE_PAREN! )? ) 
      	| ("long" ("raw")?)
      	| "raw"
      	| "boolean"  
      	| "date"
      	| "smallint"
      	| "real"
      	| "numeric"
      	| "int"
      	| "integer"
      	| "double precesion"
      	| "decimal"
      	| "dec"
      	| ( "varchar2" ( OPEN_PAREN! NUMBER CLOSE_PAREN! )? )
      	| ( "varchar" ( OPEN_PAREN! NUMBER CLOSE_PAREN! )? )
      	| ( "character" ( OPEN_PAREN! NUMBER CLOSE_PAREN! )? )
      	| "mlslabel"
      	;      
      	
//Added package_name.variable_name
type_spec 
      	:
      	datatype 
      	| ( variable_name PERCENTAGE "type" ) 
      	| ( table_name DOT column_name PERCENTAGE "type" ) 
//     	| ( package_name DOT variable_name) 
      	| ( table_name PERCENTAGE"rowtype" ) 
      	| type_name
      	;

//Changed the type name to handle variable declaration      	      	
type_name:
	identifier (DOT identifier)*
	;
     	
parameter_spec :
      	parameter_name (type_spec)?
      	{ #parameter_spec = #([PARAMETER_SPEC, "parameter_spec"], #parameter_spec); }
      	;	
      	
parameter_name :
      	identifier
      	;
      	
cursor_spec: 
	"cursor" cursor_name 
	(OPEN_PAREN! parameter_spec (COMMA parameter_spec)* CLOSE_PAREN!)?
	"return" return_type SEMI! 
	;

procedure_spec: 
	"procedure" procedure_name 
	( OPEN_PAREN! argument ( COMMA argument )* CLOSE_PAREN! )? SEMI! 
	;
	
function_spec: 
	"function" function_name 
	OPEN_PAREN! argument ( COMMA argument)* CLOSE_PAREN! 
	"return" return_type SEMI! 
	;
   	   
exception_declaration :
      	exception_name "exception" SEMI!
      	;      	   

exception_name:
	(exception_package_name DOT)? identifier 
	;

exception_package_name:
	identifier
	;

exception_pragma :
	"pragma""exception_init" OPEN_PAREN! exception_name COMMA oracle_err_number CLOSE_PAREN! SEMI!
	;
	
oracle_err_number:
	NUMBER
	;
	
record_declaration :
      	record_type_dec 
      	| record_var_dec
      	;
      	
record_type_dec :
      	"type" type_name "is" "record" 
      	OPEN_PAREN! field_spec ( COMMA field_spec )* CLOSE_PAREN! SEMI!
      	;
      	
record_var_dec :
      	record_name type_name PERCENTAGE "rowtype" SEMI!
      	;	
	
field_spec:
        column_spec
    	;
    	
plsql_table_declaration :
      	table_type_dec | table_var_dec
      	;
      	
table_type_dec :
      	"type" type_name "is" "table" 
      	"of" field_spec 
      	"indexed" "by" "binary_integer" SEMI!
      	;
      	
table_var_dec :
      	plsql_table_name type_name SEMI!
      	;
      	
plsql_table_name :
      	identifier
      	;    	
      	
procedure_declaration :
      	procedure_body
      	;
      	
procedure_body :
      	(proc_fun_start)? "procedure" procedure_name 
      	( OPEN_PAREN! argument ( COMMA argument )* CLOSE_PAREN! )? 
      	( "return" return_type)?
	( "is" | "as" )
      	( ("declare")? ( declare_spec )* )?
      	("begin" )?
      	(seq_of_statements )?
     	( "exception" ( exception_handler )* )?
      	"end" ( procedure_name )? SEMI!
      	;
      	
begin_block:
	"begin"
	(seq_of_statements )?
	( "exception" ( exception_handler )+ )?
      	"end" 
      	;
      	
//Exception handler needs to be defined      	
exception_handler :
	"when" exception_name ("or" exception_name)* "then"
	seq_of_statements
	;       	

proc_fun_start :
	"create" ( "or replace" )?
	;
	
function_body :
      	(proc_fun_start)? "function" function_name 
      	( OPEN_PAREN! argument (COMMA argument)* CLOSE_PAREN!)? 
	"return" return_type ( "is" | "as" )
      	( "declare" ( declare_spec )* )?
       	("begin" )?
      	(seq_of_statements)?
     	( "exception" ( exception_handler )+ )?
      	"end" ( function_name )? SEMI!
	;
	
function_name :
      	( schema_name DOT )? identifier
      	;
     	
procedure_name :
      	( schema_name DOT )? identifier
      	;
      	
argument :
      	argument_name ( "in" | "out" | ( "inout" ) )? (argument_type )?
      	( ASSIGNMENT_EQ "default" value )?
	;
	
argument_name :
      	identifier
      	;
      	
argument_type :
      	type_spec
      	;
      	
value :
      	( ( PLUS | MINUS )? NUMBER ) | quoted_string
      	;
      	
return_type :
      	type_spec
      	;
      	
function_declaration :
      	function_body
      	;

function_call :
	 user_defined_function ( OPEN_PAREN! expression ( COMMA expression )* CLOSE_PAREN! ) 
	;
	
variable_name  : 
	identifier
	;

null_statement:
	"null" 
	;
	
raise_statement :
	"raise" ( exception_name )?
	;
		
return_statement :
	"return" ( plsql_expression )?
	;
	
loop_statement :
	(label_name)?
	(("while"^ plsql_condition) |("for"^ (cursor_loop_param | numeric_loop_param)))?
	"loop"^
	seq_of_statements
	"end""loop" (label_name)?
	;
	
plsql_condition :
	boolean_exp
	;

boolean_exp :
	("not")? boolean_term ("or" boolean_term)*
	;
	
boolean_term :
	boolean_factor ("and" boolean_factor)*
	;
		
boolean_factor : 
      boolean_literal 
      | variable_name 
      | ( function (OPEN_PAREN plsql_exp_list CLOSE_PAREN)? ) ( relational_op plsql_expression )?
      | ( OPEN_PAREN boolean_exp CLOSE_PAREN ) 
      | ( plsql_expression 
      ( ( relational_op plsql_expression ) 
      | ( "is" ("not")? "null" ) 
      | ( ("not")? "like" match_string ) 
      | ( ("not")? "between" plsql_expression 
      "and" plsql_expression ) 
      | ( ("not")? "in" OPEN_PAREN plsql_exp_list CLOSE_PAREN ) 
      | ( ( cursor_name | subquery )( PERCENTAGE "notfound" | PERCENTAGE "found" | PERCENTAGE "isopen" ) ) ) )
      | ( cursor_name (PERCENTAGE "notfound" | PERCENTAGE "found" | PERCENTAGE "isopen" ))?
      ;
      
boolean_literal :
	"true" | "false" | "null" 
	;
	
numeric_loop_param :
	index_name "in" ("reverse")? integer_expr DOUBLEDOT integer_expr
	;
index_name :
	identifier
	;

//Added typespec to handle packagename.variablename for loop statement
integer_expr :
	num_expression
	|type_spec
	;

cursor_name :
	identifier
	;
	
cursor_loop_param :
	record_name "in"
	(( cursor_name
	(OPEN_PAREN! plsql_exp_list CLOSE_PAREN!)?)
	|(OPEN_PAREN! select_statement CLOSE_PAREN!))
	;
	
record_name:
	identifier
	;
	
plsql_expression:
	num_expression
	|char_expression
	|date_expression
	|boolean_expression
	;

num_expression:
	(PLUS | MINUS)? num_term ((PLUS|MINUS) num_term)*
	;
	
num_term:
	num_factor ((ASTERISK | DIVIDE) num_factor)*
	;

num_factor:
	(numeric_literal
	|variable_name
	|host_variable
	|(function (OPEN_PAREN plsql_exp_list CLOSE_PAREN)?)
	|(OPEN_PAREN! num_expression CLOSE_PAREN!)
	|"null"
	|((cursor_name | subquery) "%rowcount")
	|(cursor_name "%rowcount")
	) ("**" integer_expr)?
	;
	
numeric_literal:
	NUMBER
	;
	
boolean_expression:
	identifier

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -