We repeat the known procedure, where non_array_type won't have its left-recursion removal until the last step. We then get
non_array_type
: (type_name
| simple_type
| enum_type
| class_type
| interface_type
| non_array_type rank_specifier+
| delegate_type
| type_parameter
| pointer_type
) INTERR*
;
pointer_type
: type_name INTERR* STAR
| simple_type INTERR* STAR
| enum_type INTERR* STAR
| class_type INTERR* STAR
| interface_type INTERR* STAR
| non_array_type rank_specifier+ INTERR* STAR
| delegate_type INTERR* STAR
| type_parameter INTERR* STAR
| pointer_type INTERR* STAR
| VOID STAR
;
pointer_type is turned into
pointer_type
: (type_name INTERR* STAR
| simple_type INTERR* STAR
| enum_type INTERR* STAR
| class_type INTERR* STAR
| interface_type INTERR* STAR
| non_array_type rank_specifier+ INTERR* STAR
| delegate_type INTERR* STAR
| type_parameter INTERR* STAR
| VOID STAR
) (INTERR | STAR)*
;
Inlining pointer_type leads with some simplification to
non_array_type
: (type_name
| simple_type
| enum_type
| class_type
| interface_type
| non_array_type rank_specifier+
| delegate_type
| type_parameter
| type_name INTERR* STAR (INTERR | STAR)*
| simple_type INTERR* STAR (INTERR | STAR)*
| enum_type INTERR* STAR (INTERR | STAR)*
| class_type INTERR* STAR (INTERR | STAR)*
| interface_type INTERR* STAR (INTERR | STAR)*
| non_array_type rank_specifier+ INTERR* STAR (INTERR | STAR)*
| delegate_type INTERR* STAR (INTERR | STAR)*
| type_parameter INTERR* STAR (INTERR | STAR)*
| VOID STAR (INTERR | STAR)*
) INTERR*
;
Following the next few steps as done when inlining array_type results in:
non_array_type
: (type_name
| simple_type
| enum_type
| class_type
| interface_type
| delegate_type
| type_parameter
| VOID STAR
) (rank_specifier | INTERR | STAR)*
;
Sections
My siblings (including me):