PLSQL.g


/* ANTLR Parser Generator  Version 3.4 */
grammar PLSQL;
 
options
{
  language     = C;
  output       = AST;
  ASTLabelType = pANTLR3_BASE_TREE;
}
/* 虚拟记号,用于构造语法树 */
tokens {
    STATEMENT_DDL;
   
    STATEMENT_Create_TABLE;
    STATEMENT_Create_VIEW;
    STATEMENT_Create_INDEX;
    STATEMENT_ADD_PRIMARY_KEY;
    STATEMENT_ADD_CONSTRAINT;
    STATEMENT_COMMENT;
    OBJECT_FIELD_LIST;
    OBJECT_FIELD;
    OBJECT_FUNC;
    OBJECT_VIEW;
    OBJECT_TABLE;
    OBJECT_COMMENT;
    OBJECT_INDEX;
    NAME_CONSTRAINT;
    NAME_INDEX;
    NAME_VIEW;
    NAME_FIELD;
    NAME_FIELD_LIST;
    NAME_TABLE;
    NAME_SCHEMA;
    COMMENT_TYPE;
    COMMENT_CONTENT;
    FIELD_CONSTRAINT;
    FIELD_TYPE;
    FIELD_DEFAULT_VALUE;
    FIELD_LENGTH;
   
    INDEX_TYPE;
}
@header
{
}
ddl_statement
  :
  tmp_ddl_statement
  -> ^(STATEMENT_DDL tmp_ddl_statement)
  ;
//--statements define--------------------------------------------------------------------
/* 使用"-> ^",则不需要"!" */
statement_create_table
  :
  'create' ('global' 'temporary')? 'table' object_table '(' object_field_list ')'
  ('partition' 'by' 'range' '(' name_field ')''(' tmp_object_partition_list ')')?
  ('on' 'commit' ('preserve'|'delete') 'rows')? tmp_tablespace? ';'
  -> ^(STATEMENT_Create_TABLE object_table object_field_list tmp_tablespace?)
  ;
statement_create_view
  :
  'create' 'or' 'replace' 'view' object_view 'as' '/'?
  -> ^(STATEMENT_Create_VIEW object_view)
  ;
statement_create_index
  :
  'create' index_type 'index' object_index
  'on' object_table name_field_list tmp_tablespace? ';'
  -> ^(STATEMENT_Create_INDEX index_type object_index object_table name_field_list tmp_tablespace)
  ;
statement_add_primary_key
  :
  'alter' 'table' object_table
  'add' 'primary' 'key' name_field_list ('using' 'index')? (tmp_tablespace)? ';'
  -> ^(STATEMENT_ADD_PRIMARY_KEY object_table name_field_list )
  ;
statement_add_constraint
  :
  'alter' 'table' object_table
  'add' 'constraint' name_constraint
  'primary' 'key' name_field_list
  'using' 'index' (tmp_tablespace)? ';'
   -> ^(STATEMENT_ADD_CONSTRAINT object_table name_constraint name_field_list tmp_tablespace)
  ;
statement_comment
  :
  'comment' comment_type object_comment 'is' comment_content ';'
   -> ^(STATEMENT_COMMENT comment_type object_comment comment_content)
  ;
 
index_type
  :
  'unique'?
  -> ^(INDEX_TYPE 'unique'?)
  ;
 
//----------------------------------------------------------------
object_table
  :
  name_schema '.' name_table
  -> ^(OBJECT_TABLE name_schema name_table )
  ;
object_comment
  :
  name_schema '.' name_table ('.' name_field)?
  -> ^(OBJECT_COMMENT name_schema  name_table ( name_field)?)
  ;
object_index
  :
  name_schema '.' name_index
  -> ^(OBJECT_INDEX name_schema name_index )
  ;
object_view
  :
  name_schema '.' name_view
  -> ^(OBJECT_VIEW name_schema name_view)
  ;
object_field_list
  :
  object_field (',' object_field )*
  -> ^(OBJECT_FIELD_LIST object_field ( object_field )* )
  ;
object_field
  :
  name_field field_type field_length field_default_value field_constraint
  -> ^(OBJECT_FIELD name_field field_type field_length field_default_value field_constraint)
  ;
 
object_func
  :
  ID '(' (tmp_func_param (',' tmp_func_param)*)? ')'
  -> ^(OBJECT_FUNC (tmp_func_param (tmp_func_param)*)? )
  ;
field_type
  :
  tmp_data_type_string?
  -> ^( FIELD_TYPE tmp_data_type_string?)
  ;
field_length
  :
  ('(' INT (',' INT)? ')')?
  -> ^(FIELD_LENGTH (INT INT?)?)
  ;
field_default_value
  :
  tmp_default_data
  -> ^( FIELD_DEFAULT_VALUE tmp_default_data)
  ;

field_constraint
  :
  ('not null')?
  -> ^(FIELD_CONSTRAINT ('not null')?)
  ;
name_field
  :
  tmp_name_field
  -> ^(NAME_FIELD tmp_name_field)
  ;

name_field_list
  :
  '(' name_field (',' name_field )* ')'
  -> ^(NAME_FIELD_LIST name_field ( name_field )*)
  ;
name_table
  :
  ID
  -> ^(NAME_TABLE ID)
  ;
name_schema
  :
  ID
  -> ^(NAME_SCHEMA ID)
  ;
name_view
  :
  ID
  -> ^(NAME_VIEW ID)
  ;
name_index
  :
  ID
  -> ^(NAME_INDEX ID)
  ;
name_constraint
  :
  ID
  -> ^(NAME_CONSTRAINT ID)
  ;
comment_content
  :
  STRING
  -> ^(COMMENT_CONTENT STRING)
  ;
 
comment_type
  :
  tmp_comment_type_string
  -> ^(COMMENT_TYPE tmp_comment_type_string)
  ;
//--------------------------------------------------------------------
tmp_ddl_statement
  :
  ( statement_create_table
  | statement_create_view
  | statement_create_index
  | statement_add_constraint
  | statement_add_primary_key
  | statement_comment
  )*
  ;
tmp_comment_type_string
  :
  'on'! 'table' | 'on'! 'column'
  ;
tmp_data_type_string
  :
  'VARCHAR2' | 'NUMBER' | 'DATE' | 'INTEGER' |'RAW' |'CHAR' | 'CLOB' |'TIMESTAMP' | 'BLOB' | 'FLOAT'
  ;
tmp_func_param
  :
  STRING | INT | FLOAT
  ;
tmp_default_data
  :
  ('default'! tmp_default_value )?
  ;
 
tmp_default_value
  :
  '('!? (STRING | INT | FLOAT | object_func | 'sysdate' | 'SYSDATE') ')'!?
  ;
tmp_name_field
 :
 ID | 'TIMESTAMP'
 ;
 
tmp_object_partition_list
  :
  tmp_object_partition (',' tmp_object_partition)*
  ;
tmp_object_partition
  :
  'partition' ID 'values' 'less' 'than' '(' (INT | STRING) ')' tmp_tablespace
  ; 
tmp_tablespace
  :
  'tablespace'^
  ID
  'pctfree' INT
  'initrans' INT
  'maxtrans' INT
  tmp_storage
  ;
tmp_storage
  :
  'storage'^
  '('!
  'initial' INT ('K'| 'M')
  'next' INT ('K'| 'M')
  'minextents' INT
  'maxextents' 'unlimited'
  ')'!
  ;
//--lexer define--------------------------------------------------------------------------------
ID
  :
  ( 'a'..'z' | 'A'..'Z' | '$' | '_' ) ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' )*
  ;
INT
  :
  ('+'|'-' )? '0'..'9'+
  ;
FLOAT
  :
  ('0'..'9')+ '.' ('0'..'9')* EXPONENT? | '.' ('0'..'9')+ EXPONENT? | ('0'..'9')+ EXPONENT
  ;
COMMENT_CONTENT
  :
  ('--'|'grant'|'spool'|'prompt') ~( '\n' | '\r' )*'\r'? '\n'
  {
    $channel = HIDDEN;
  }
  ;
WS
  :
  ( ' '| '\t' | '\r'| '\n')
  {
     $channel = HIDDEN;
  }
  ;
STRING
  :
  '\'' ( ESC_SEQ | ~( '\\' | '\'') | '\'\'' )* '\''
  {
    SETTEXT(GETTEXT()->subString(GETTEXT(),1,GETTEXT()->len-1));
  }
  ;
fragment
EXPONENT
  :
  ('e' | 'E') ( '+'| '-')? ('0'..'9')+
  ;
fragment
HEX_DIGIT
  :
  ( '0'..'9' | 'a'..'f' | 'A'..'F' )
  ;
fragment
ESC_SEQ
  :
  '\\'('b'| 't'| 'n'| 'f' | 'r' | '\"' | '\'' | '\\') | UNICODE_ESC | OCTAL_ESC
  ;
fragment
OCTAL_ESC
  :
  '\\' ('0'..'3') ('0'..'7') ('0'..'7') | '\\' ('0'..'7') ('0'..'7') | '\\' ('0'..'7')
  ;
fragment
UNICODE_ESC
  :
  '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
  ;


在控制台输出语法树

void DebugPrintSyntaxTree(pANTLR3_BASE_TREE tree)
{
 static int Level=0;
 Level++;
  int k = Level;
 while ((--k) > 0)
 {
  cout<<" │";
 }
 cout<<" ├"<< tree->getText(tree)->chars << endl;
 for (unsigned int i = 0; i < tree->getChildCount(tree); i++)
 {
  pANTLR3_BASE_TREE tmp_tree = (pANTLR3_BASE_TREE)tree->getChild(tree,i);
  DebugPrintSyntaxTree(tmp_tree);
 }
 Level--;
}

有了语法树,就可以做自己的任意操作了,我的这个应用是将PL/SQL的Create table,comment等语句转换为数据字典文档。
 
 

本文链接地址: Antlr.2 用Antlr解析PL/SQL的基本DDL语句
https://blog.qingfengju.com/index.asp?id=257

分类:Win32/C++ 查看次数:10763 发布时间:2011/10/10 14:54:47