anchor.diff:  unsigned_number : number ;
   
   identifier
  -	: simple_identifier
  -	// TODO escaped_identifier disabled for now because it isn't used much and causes an ambiguity
  -	// escaped_identifier
  -	;
  +  : simple_identifier
  +  // TODO escaped_identifier disabled for now because it isn't used much and causes an ambiguity
  +  // escaped_identifier
  +  ;
   
   identifier_list
  -	: identifier (COMMA identifier)*
  -	;
  +  : identifier (COMMA identifier)*
  +  ;
   
   escaped_identifier
  -	: simple_identifier // TODO
  -	;
  +  : simple_identifier // TODO
  +  ;
   
   simple_identifier
  -	: ID
  -	// Special tokens that are not really keywords but tokenized to avoid semantic predicates in the grammar.
  -	| KW_STD
  -	| KW_NEW
  -	| KW_OPTION
  -	| KW_FIND
  -	| KW_FIND_INDEX
  -	| KW_FIND_FIRST
  -	| KW_FIND_FIRST_INDEX
  -	| KW_FIND_LAST
  -	| KW_FIND_LAST_INDEX
  -	| KW_MIN
  -	| KW_MAX
  -	| KW_UNIQUE_INDEX
  -	| KW_REVERSE
  -	| KW_SORT
  -	| KW_RSORT
  -	| KW_SHUFFLE
  -	| KW_SUM
  -	| KW_PRODUCT
  -	;
  +  : ID
  +  // Special tokens that are not really keywords but tokenized to avoid semantic predicates in the grammar.
  +  | KW_STD
  +  | KW_NEW
  +  | KW_OPTION
  +  | KW_FIND
  +  | KW_FIND_INDEX
  +  | KW_FIND_FIRST
  +  | KW_FIND_FIRST_INDEX
  +  | KW_FIND_LAST
  +  | KW_FIND_LAST_INDEX
  +  | KW_MIN
  +  | KW_MAX
  +  | KW_UNIQUE_INDEX
  +  | KW_REVERSE
  +  | KW_SORT
  +  | KW_RSORT
  +  | KW_SHUFFLE
  +  | KW_SUM
  +  | KW_PRODUCT
  +  ;
   
   system_tf_identifier
  -	: SYSTEM_ID | DOLLAR_FATAL | DOLLAR_ERROR | DOLLAR_WARNING | DOLLAR_INFO
  -	;
  +  : SYSTEM_ID | DOLLAR_FATAL | DOLLAR_ERROR | DOLLAR_WARNING | DOLLAR_INFO
  +  ;
   
   arrayed_identifier : simple_arrayed_identifier | escaped_arrayed_identifier ;
   block_identifier : identifier ;
  
positive.code: stream_expression : expression (KW_WITH LSQUARE array_range_expression RSQUARE)? ;
  
  array_range_expression
  	: expression
  	| expression COLON expression
  	| expression ADD_COLON expression
  	| expression SUB_COLON expression
  	;
  
  empty_queue : LCURLY RCURLY ;
  
  net_concatenation : LCURLY net_concatenation_value ( COMMA net_concatenation_value )* RCURLY ;
  
  net_concatenation_value
  	: hierarchical_net_identifier
  	| hierarchical_net_identifier LSQUARE expression RSQUARE ( LSQUARE expression RSQUARE )*
  	| hierarchical_net_identifier LSQUARE expression RSQUARE ( LSQUARE expression RSQUARE )* LSQUARE range_expression RSQUARE
  	| hierarchical_net_identifier LSQUARE range_expression RSQUARE
  	| net_concatenation
  	;
  
  variable_concatenation
  	: LCURLY variable_concatenation_value ( COMMA variable_concatenation_value )* RCURLY
  	;
  
  variable_concatenation_value
  	: hierarchical_variable_identifier
  	| hierarchical_variable_identifier LSQUARE expression RSQUARE ( LSQUARE expression RSQUARE )*
  	| hierarchical_variable_identifier LSQUARE expression RSQUARE ( LSQUARE expression RSQUARE )* LSQUARE range_expression RSQUARE
  	| hierarchical_variable_identifier LSQUARE range_expression RSQUARE
  	| variable_concatenation
  	;
  
  base_expression
  	: expression
  	;
  
  constant_base_expression
  	: constant_expression
  	;
  
  // NOTE: this causes hierarchical_id to match "foo[i].bar".
  constant_expression
  	: expression
  	;
  
  constant_mintypmax_expression
  	: constant_expression
  	| constant_expression QUE constant_expression QUE constant_expression
  	;
  
  constant_range_expression
  	: constant_expression
  	| msb_constant_expression QUE lsb_constant_expression
  	| constant_base_expression ADD_COLON width_constant_expression
  	| constant_base_expression SUB_COLON width_constant_expression
  	;
  
  dimension_constant_expression
  	: constant_expression
  	;
  
  param_expression
  	: mintypmax_expression
  	| data_type
  	;
  
  expression
  	: term (
  	      binary_operator attribute_instances term
  	    | QUE attribute_instances expression COLON term
  	  )*
  	;
  
  term
  	: (primary
  	| unary_operator attribute_instances primary
  	| inc_or_dec_expression
  	) inside_expression?
  	;
  
  inside_expression
  	: KW_INSIDE LCURLY open_range_list RCURLY
  	;
  
  lsb_constant_expression
  	: constant_expression
  	;
  
  mintypmax_expression
  	: expression (QUE expression QUE expression)?
  	;
  
  module_path_conditional_expression
  	: module_path_expression QUE attribute_instances module_path_expression
  	  QUE module_path_expression
  	;
  
  module_path_expression
  	: ( module_path_primary
  	  | unary_module_path_operator attribute_instances module_path_primary
  	  )
  	  ( binary_module_path_operator attribute_instances module_path_expression
  	  | QUE attribute_instances module_path_expression QUE module_path_expression
  	  )*
  	;
  
  module_path_mintypmax_expression
  	: module_path_expression (QUE module_path_expression QUE module_path_expression)?
  	;
  
  msb_constant_expression
  	: constant_expression
  	;
  
  range_expression
  	: expression
  	| msb_constant_expression QUE lsb_constant_expression
  	| base_expression ADD_COLON width_constant_expression
  	| base_expression SUB_COLON width_constant_expression
  	;
  
  width_constant_expression
  	: constant_expression
  	;
  
  constant_primary
  	: constant_concatenation
  	| constant_function_call
  	| LPAREN constant_mintypmax_expression RPAREN
  	| constant_multiple_concatenation
  	| genvar_identifier
  	| number
  	| parameter_identifier
  	| specparam_identifier
  	;
  
  module_path_primary
  	: number
  	| identifier
  	| module_path_concatenation
  	| module_path_multiple_concatenation
  	| function_subroutine_call
  	| LPAREN module_path_mintypmax_expression RPAREN
  	;
  
  // TODO
  primary
  	: primary_literal
  	| primary_identifier_or_call
  	| randomize_call
  	| system_tf_call
  	| empty_queue
  	| concatenation (LSQUARE range_expression RSQUARE)?
  	| multiple_concatenation (LSQUARE range_expression RSQUARE)?
  	| LPAREN mintypmax_expression RPAREN
  	| cast
  	| assignment_pattern_expression
  	| streaming_concatenation
  	| sequence_method_call
  	| KW_THIS
  	| DOLLAR
  	| KW_NULL
  	;
  
  primary_literal
  	: number | LIT_TIME | LIT_UNBASED_UNSIZED | string_literal
  	;
  
  string_literal
  	: LIT_STRING
  	| LIT_STRING_DPI_C
  	| LIT_STRING_DPI
  	;
  
  cast
  	: casting_type APOSTROPHE LPAREN expression RPAREN
  	;
  
  casting_type
  	: simple_type | constant_primary | signing | KW_STRING | KW_CONST
  	;
  
  primary_identifier_or_call
  	: primary_identifier (LPAREN list_of_arguments RPAREN)?
  	;
  
  primary_identifier
  	: class_qualifier? hierarchical_identifier select
  	| DOLLAR_UNIT COLON2 hierarchical_identifier select
  	;
  
  select
  	: ( ( DOT member_identifier bit_select )* DOT member_identifier )? bit_select
  	  ( LSQUARE part_select_range RSQUARE )?
  	;
  
  bit_select
  	: (LSQUARE expression RSQUARE)*
  	;
  
  nonrange_select
  	: ( (DOT member_identifier bit_select)* DOT member_identifier )? bit_select
  	;
  
  part_select_range
  	: constant_range | indexed_range
  	;
  
  indexed_range
  	: expression ADD_COLON constant_expression
  	| expression SUB_COLON constant_expression
  	;
  
  class_qualifier
  	: (KW_LOCAL COLON2)? (implicit_class_handle DOT | class_scope)
  	;
  
  // TODO bug #16, primary and method_call_root are mutually left-recursive in spec grammar.
  // method call root can be an expression
  // See also: http://www.eda.org/svdb/view.php?id=1480
  primary_call_root
  	: (class_qualifier | package_scope)? hierarchical_identifier select attribute_instances (LPAREN list_of_arguments RPAREN)?
  	;
  
  method_call_root
  	: primary_call_root | implicit_class_handle
  	;
  
  method_call
  	: method_call_root DOT method_call_body
  	;
  
  method_call_body
  	: method_identifier attribute_instances (LPAREN list_of_arguments RPAREN)?
  	| array_manipulation_call
  	| randomize_call
  	;
  
  // TODO static method call root can be a primary
  // TODO generic calls need to be fixed.
  static_method_call
  	: (package_identifier COLON2)?
  	  (class_identifier parameter_value_assignment? COLON2)+
  	  method_identifier
  	  (LPAREN list_of_arguments RPAREN)?
  	;
  
  class_scope
  	: class_type COLON2
  	;
  
  class_type
  	: ps_class_identifier parameter_value_assignment? (COLON2 class_identifier parameter_value_assignment?)* packed_dimension*
  	;
  
  ps_class_identifier
  	: package_scope? class_identifier
  	;
  
  package_scope
  	: (package_identifier | DOLLAR_UNIT) COLON2
  	;
  
  unary_operator
  	: ADD | SUB | NOT | INV | AND | INV_AND | OR | INV_OR | XOR | INV_XOR | XOR_INV
  	;
  
  binary_operator
  	: ADD | SUB | MUL | DIV | MOD | EQ2 | NOT_EQ | EQ3 | NOT_EQ2
  	| AND2 | OR2 | MUL2 | LT | LT_EQ | GT | GT_EQ | AND | OR | XOR
  	| XOR_INV | INV_XOR | GT2 | LT2 | GT3 | LT3
  	;
  
  unary_module_path_operator
  	: NOT | INV | AND | INV_AND | OR | INV_OR | XOR | INV_XOR | XOR_INV
  	;
  
  binary_module_path_operator
  	: EQ2 | NOT_EQ | AND2 | OR2 | AND | OR | XOR | XOR_INV | INV_XOR
  	;
  
  // TODO
  number : LIT_NUM ;
  
negative.code: function_identifier : identifier ;
  
  hierarchical_identifier
    : (DOLLAR_ROOT DOT)? identifier (constant_bit_select DOT identifier)*
    ;
  
  hierarchical_parameter_identifier
    : hierarchical_identifier
    ;
  
  ps_identifier
    : package_scope? identifier
    ;
  
  ps_checker_identifier
    : package_scope? checker_identifier
    ;
  
  ps_or_hierarchical_array_identifier
    : (implicit_class_handle DOT | class_scope | package_scope)? hierarchical_array_identifier
    ;
  
  ps_or_hierarchical_sequence_identifier
    : package_scope? sequence_identifier
    | hierarchical_sequence_identifier
    ;
  
  ps_or_hierarchical_tf_identifier
    : package_scope tf_identifier
    | hierarchical_tf_identifier
    ;
  
  ps_or_hierarchical_net_identifier
    : package_scope? net_identifier
    | hierarchical_net_identifier
    ;
  
  ps_or_hierarchical_property_identifier
    : package_scope? property_identifier
    | hierarchical_property_identifier
    ;
  
  ps_parameter_identifier
    : (package_scope | class_scope)? parameter_identifier
    | (generate_block_identifier (LSQUARE constant_expression RSQUARE)? DOT )* parameter_identifier
    ;
  
  ps_type_identifier
    : (KW_LOCAL COLON2 | package_scope)? type_identifier
    ;
  
  attribute_instances
    : attribute_instance*
    ;
  
  attribute_instance
    : LPAREN MUL attr_spec ( COMMA attr_spec )* MUL RPAREN
    ;
  
  attr_spec
    : attr_name EQ constant_expression
    | attr_name
    ;
  
  attr_name
    : identifier
    ;
  