1

我正在尝试为 DB2 DDL 语句 (CREATE TABLE) 构建 ANTLR 3 语法,我发现决策可以使用多种替代方法匹配诸如“DATA”之类的输入:1、2。我正在关注 DB2 DDL 文档文档。

我已经将语法图准确地映射到语法。但问题是有一些可选子句和路径可以到达同一点,因此有多种选择。我使用了回溯选项,但我想要其他一些解决方案。任何人都可以在这方面帮助我。

请看我的语法:

unit:
create_table_statement
;

create_table_statement:
create_table_statement_rest
;

create_table_statement_rest:
  CREATE TABLE ID create_table_opts
  organize_by_items?
  DATA CAPTURE (NONE|CHANGES) in_tbspc_cyc
  tablespace_opts? distribution_clause?
  partitioning_clause? compress_ny_val_compression
  with_restrict_on_drop? not_logged_init?
  ccsid_ascii_unicode? (SECURITY POLICY name)?
  (OPTIONS LPAREN ADD name name (COMMA name name)* RPAREN)?
;

with_restrict_on_drop:
WITH RESTRICT ON DROP
;

not_logged_init:
  NOT LOGGED INITIALLY
;

ccsid_ascii_unicode:
  CCSID (ASCII|UNICODE)
;

create_table_opts:
  element_list
  |OF name typed_table_opts?
  |materialized_query_definition
  |staging_table_definition
  |LIKE name copy_opts? 
;

organize_by_items:
  ORGANIZE BY (dimensions_item|key_sequence_items)
;

dimensions_item:
  DIMENSIONS? LPAREN ID (COMMA ID)* RPAREN
;

key_sequence_items:
  KEY SEQUENCE sequence_key_spec
;

sequence_key_spec:
  LPAREN seq_key_spec_one (COMMA seq_key_spec_one) RPAREN (ALLOW|DISALLOW) OVERFLOW (PCTFREE DIGIT)?
;

seq_key_spec_one:
  ID (STARTING FROM? CONSTANT)? ENDING AT? DIGIT
;

in_tbspc_cyc:
  IN (name (COMMA name)*) NO? CYCLE?
;

tablespace_opts:
  //tablespace_opt_one? 
  (INDEX IN name)? (LOG IN name (COMMA name)*)?
;

distribution_clause:
  DISTRIBUTE BY distribute_by_opts
;

distribute_by_opts:
  distribution_item_one
  |distribution_item_two
;

distribute_by:
  DISTRIBUTE BY
;

distribution_item_one:
  HASH LPAREN ID (COMMA ID)* RPAREN
;

distribution_item_two:
  REPLICATION
;

tablespace_opt_one:
  INDEX IN name LOG IN name
;

element_list:
  LPAREN
     element_list_items (COMMA element_list_items)*
  RPAREN
;

materialized_query_definition:
  (ID (COMMA ID)*)? AS LPAREN fullselect RPAREN materialized_query_table_opts
;

staging_table_definition:
  (LPAREN name (COMMA name)* RPAREN) FOR name PROPAGATE IMMEDIATE
;

fullselect:

;

materialized_query_table_opts:
  WITH NO DATA copy_opts? | refreshable_table_opts
;

element_list_items:
  column_definition|referential_constraint|check_constraint
;

column_definition:
  name data_type? column_opts?
;

copy_opts:
  ((INCLUDING|EXCLUDING) COLUMN? DEFAULTS)? (EXCLUDING|INCLUDING) IDENTITY (COLUMN ATTRIBUTES)?
;

refreshable_table_opts:
  DATA INITIALLY DEFERRED REFRESH (DEFERRED|IMMEDIATE) (ENABLE|DISABLE) QUERY OPTIMIZATION (MAINTAINED BY (SYSTEM|USER|FEDERATED_TOOL))?
;

data_type:
  SMALLINT
  |INTEGER|INT
  |BIGINT
  |FLOAT (LPAREN DIGIT RPAREN)?
  |REAL
  |DOUBLE PRECISION?
  |(DECIMAL|DEC|NUMERIC|NUM) (LPAREN DIGIT (COMMA INTEGER)? RPAREN)?
  |(dt_char|dt_vchar|LONG VARCHAR) (FOR BIT DATA)?
  |((BLOB|BINARY LARGE OBJECT)|(CLOB|(CHARACTER|CHAR) LARGE OBJECT|DBCLOB) (LPAREN DIGIT (K|M|G) RPAREN)?)
  |GRAPHIC (LPAREN DIGIT RPAREN)
  |VARGRAPHIC (LPAREN DIGIT RPAREN)
  |LONG VARGRAPHIC
  |DATE
  |TIME
  |TIMESTAMP
  |XML
  //|name
  //added name instead of the two below but it would be replaced
  //|distinct_type_name
  //|structured_type_name
  |REF name
  |(LPAREN SYSPROC DOT RPAREN)? DB2SECURITYLABEL
;

dt_char :   (CHARACTER|CHAR)(LPAREN DIGIT RPAREN)?
    ;
dt_vchar    :
    (VARCHAR|((CHAR|CHARACTER) VARYING))LPAREN DIGIT RPAREN 
    ;
distinct_type_name
:   
name
;
structured_type_name
:
name    
;

column_opts:
  column_options_items+
; 

column_options_items:
  NOT NULL
  |lob_opts
  |SCOPE name
  |((CONSTRAINT name)? ((PRIMARY KEY|UNIQUE)| references_clause|(check_condition constraint_attributes)))
  |generated_column_spec
  |(INLINE LENGTH DIGIT)
  |(COMPRESS SYSTEM DEFAULT)
  |(COLUMN SECURED WITH ID)
;

lob_opts:
  NOT? LOGGED NOT? COMPACT
;

generated_column_spec:
  default_clause|generated_by_identity|generated_by_exp
;

default_clause:
  WITH? DEFAULT default_values?
;

default_values:
  default_values_items
  |cast_function LPAREN default_values_items RPAREN
  |NULL
;

default_values_items
:
constant
|datetime_special_register
|user_special_register
|CURRENT SCHEMA 
;

datetime_special_register:
  CURRENT DATE
  |CURRENT TIME
  |CURRENT TIMESTAMP
;

user_special_register:
  CURRENT USER
  |SESSION_USER
  |SYSTEM_USER
;

cast_function:
  //needs to be figured out
;

generated_by_identity:
  GENERATED (ALWAYS|(BY DEFAULT)) identity_opts?
;

identity_opts:
  AS IDENTITY LPAREN identity_options_items (identity_options_items)* RPAREN
;

identity_options_items:
  START WITH DIGIT
  |INCREMENT BY DIGIT
  |NO MINVALUE
  |MINVALUE DIGIT
  |NO MAXVALUE
  |MAXVALUE DIGIT
  |NO CYCLE
  |CYCLE
  | (NO CACHE | CACHE DIGIT)//cache 20 needs to be seen
  |NO ORDER
  |ORDER
;

generated_by_exp:
  GENERATED ALWAYS? AS generation_expression
;

generation_expression:
  //needs to be figured out
;

unique_constraint:
  (CONSTRAINT name)? (UNIQUE|PRIMARY KEY) LPAREN name (COMMA name)* RPAREN
;

referential_constraint:
  (CONSTRAINT ID)? FOREIGN KEY LPAREN ID (COMMA ID)* RPAREN references_clause
;

references_clause:
  REFERENCES  name (LPAREN ID (COMMA ID)* RPAREN)? rule_clause constraint_attributes
;

rule_clause:
  ON DELETE (NO ACTION | RESTRICT|CASCADE|SET NULL) ON UPDATE (NO ACTION|RESTRICT)
;

check_constraint:
  (CONSTRAINT name) CHECK check_condition constraint_attributes
;

check_condition:
  search_condition|functional_dependency
;

constraint_attributes:
  NOT? ENFORCED (ENABLE|DISABLE) QUERY OPTIMIZATION 
;

search_condition:
  //needs to be done
;

functional_dependency:
  (ID | (LPAREN ID (COMMA ID)* RPAREN)) DETERMINED BY (ID | (LPAREN ID (COMMA ID)* RPAREN))
;

typed_table_opts:
  (HIERARCHY name|under_clause)? typed_element_list?
;

typed_table_options_item2:
  under_clause
;

under_clause:
  UNDER name INHERIT SELECT PRIVILEGES
;

typed_element_list:
  LPAREN typed_element_list_items (COMMA typed_element_list_items)* RPAREN
;

typed_element_list_items:
  oid_column_definition | with_opts | unique_constraint | check_constraint
;

oid_column_definition:
  REF IS name USER GENERATED
;

with_opts:
  name WITH OPTIONS column_opts
;

partitioning_clause:
  part_by_range range_partition_spec 
;

part_by_range:
  PARTITION BY RANGE?
;
compress_ny_val_compression:
COMPRESS (NO|YES) (VALUE COMPRESSION)?
;

range_partition_spec:
  LPAREN partition_expression (COMMA partition_expression)* RPAREN LPAREN partition_element (COMMA partition_element)* RPAREN
;

partition_element:
  partition_boundry_element
  |start_with_boundry_spec
;

partition_boundry_element:
  (PARTITION name)? boundary_spec (IN name)?
;

start_with_boundry_spec:
  boundary_spec EVERY (duration_with_paren|duration_without_paren)
;

duration_with_paren:
  LPAREN constant duration_label RPAREN
;

duration_without_paren:
  constant duration_label
;

partition_expression:
  NULLS (LAST|FIRST)
;

boundary_spec:
  boundary_spec_path_one|boundary_spec_path_two
;

boundary_spec_path_one:
  starting_clause ending_clause
;

boundary_spec_path_two:
  ending_clause
;

starting_clause:
  STARTING FROM? (starting_ending_with_repeat|starting_ending_without_repeat) (INCLUSIVE|EXCLUSIVE)
;

ending_clause:
  ENDING AT? (starting_ending_with_repeat|starting_ending_without_repeat) (INCLUSIVE|EXCLUSIVE)
;

starting_ending_with_repeat:
  LPAREN starting_ending_clause_values (COMMA starting_ending_clause_values)* RPAREN
;

starting_ending_without_repeat:
  starting_ending_clause_values
;

duration_label:
  YEAR|YEARS|MONTH|MONTHS|DAY|DAYS|HOUR|HOURS|MINUTE|MINUTES|SECOND|SECONDS|MICROSECOND|MICROSECONDS
;

starting_ending_clause_values:
  constant|MINVALUE|MAXVALUE
;

constant:
  DIGIT
;

name    :   ID;

///////////////////////////////////////////////END PARSER RULES///////////////////////////////////////////////////

///////////////////////////////////////////////LEXER RULES///////////////////////////////////////////////////////

WS      :   ( '\t' | ' ' | '\r' | '\n' )+   { $channel = HIDDEN; } ;

COMMA   
  :  ','  
  ;  

EQUAL:
       '=';
STRING_LITERAL

: ('n'|'u')?'\''( ~('\'') | '\'\'' )* '\'' ;

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
DIGIT : '0'..'9'+
;

在这方面的任何帮助将不胜感激。

4

0 回答 0