1.2 Rule Inlining array_type
This time we remove the left-recursion of the rule type, right at the beginning:
type : (type_name | simple_type | enum_type | class_type | interface_type | array_type | delegate_type | type_parameter | pointer_type ) INTERR* ;
Now we inline type and simplify further. I inline unmanaged_type as next and in-factor "INTERR* STAR" to each subrule, so that I can remove the left-recursion in pointer_type. Because of the assymmetric "VOID STAR" subrule I inline pointer_type instead doing some optimization, except turning the trailing into "(INTERR | STAR)*". Then we arrive at
non_array_type : (type_name | simple_type | enum_type | class_type | interface_type | array_type | delegate_type | type_parameter | (type_name INTERR* STAR | simple_type INTERR* STAR | enum_type INTERR* STAR | class_type INTERR* STAR | interface_type INTERR* STAR | array_type INTERR* STAR | delegate_type INTERR* STAR | type_parameter INTERR* STAR | VOID STAR ) (INTERR | STAR)* ) INTERR* ;
Taking the near duplicates into account, "INTERR* STAR (INTERR | STAR)" is transformable into "INTERR* STAR? (INTERR | STAR)" and this is "(INTERR | STAR)*". We then obtain
non_array_type : (type_name (INTERR | STAR)* | simple_type (INTERR | STAR)* | enum_type (INTERR | STAR)* | class_type (INTERR | STAR)* | interface_type (INTERR | STAR)* | array_type (INTERR | STAR)* | delegate_type (INTERR | STAR)* | type_parameter (INTERR | STAR)* | VOID STAR (INTERR | STAR)* ) INTERR* ;
The last INTERR* can be safely deleted. Then after some rule-inling, SLRR and simplification we arrive at
array_type : type_name (STAR | INTERR)* rank_specifier+ | simple_type (STAR | INTERR)* rank_specifier+ | enum_type (STAR | INTERR)* rank_specifier+ | class_type (STAR | INTERR)* rank_specifier+ | interface_type (STAR | INTERR)* rank_specifier+ | array_type (STAR | INTERR)* rank_specifier+ | delegate_type (STAR | INTERR)* rank_specifier+ | type_parameter (STAR | INTERR)* rank_specifier+ | VOID STAR (STAR | INTERR)* rank_specifier+ ;
Now repeat SLRR and simplify the result to
array_type : (type_name | simple_type | enum_type | class_type | interface_type | delegate_type | type_parameter | VOID STAR ) ((STAR | INTERR)* rank_specifier)+ ;
"((STAR | INTERR)* rank_specifier)" is similar to "(STAR | INTERR | rank_specifier)", if there is at least one rank_specifier. This can be checked with:
array_type : (type_name | simple_type | enum_type | class_type | interface_type | delegate_type | type_parameter | VOID STAR ) (STAR | INTERR | r+=rank_specifier)+ {$r.Count >= 1}? ;
Sections
My siblings (including me):