2.3 Rule Inlining member_access
We inline primary_expression and in-factor all rules before we save a new copy of the grammar:
primary_no_array_creation_expression : literal | simple_name | parenthesized_expression | member_access | invocation_expression | primary_no_array_creation_expression OPEN_BRACKET expression_list CLOSE_BRACKET | this_access | base_access | post_increment_expression | post_decrement_expression | object_creation_expression | delegate_creation_expression | anonymous_object_creation_expression | typeof_expression | checked_expression | unchecked_expression | default_value_expression | anonymous_method_expression | sizeof_expression | array_creation_expression OP_PTR IDENTIFIER | primary_no_array_creation_expression OP_PTR IDENTIFIER | primary_no_array_creation_expression OPEN_BRACKET expression CLOSE_BRACKET ; member_access : array_creation_expression DOT IDENTIFIER type_argument_list? | primary_no_array_creation_expression DOT IDENTIFIER type_argument_list? | predefined_type DOT IDENTIFIER type_argument_list? | qualified_alias_member DOT IDENTIFIER type_argument_list? ; invocation_expression : array_creation_expression OPEN_PARENS argument_list? CLOSE_PARENS | primary_no_array_creation_expression OPEN_PARENS argument_list? CLOSE_PARENS ; post_increment_expression : array_creation_expression OP_INC | primary_no_array_creation_expression OP_INC ; post_decrement_expression : array_creation_expression OP_DEC | primary_no_array_creation_expression OP_DEC ;
We postpone the SLRR on primary_no_array_creation_expression and its inlining until the last moment as this rule is referenced by other to-be-inlined rules. We inline now invocation_expression, post_increment_expression and post_decrement_expression and remove SLRR on primary_no_array_creation_expression to get:
primary_no_array_creation_expression : (literal | simple_name | parenthesized_expression | member_access | this_access | base_access | array_creation_expression OPEN_PARENS argument_list? CLOSE_PARENS | array_creation_expression OP_INC | array_creation_expression OP_DEC | array_creation_expression OP_PTR IDENTIFIER | object_creation_expression | delegate_creation_expression | anonymous_object_creation_expression | typeof_expression | checked_expression | unchecked_expression | default_value_expression | anonymous_method_expression | sizeof_expression ) (OPEN_PARENS argument_list? CLOSE_PARENS | OPEN_BRACKET (expression_list | expression) CLOSE_BRACKET | OP_INC | OP_DEC | OP_PTR IDENTIFIER )* ;
Now after inlining member_access, it has to be in-factored to allow SLRR. Due to the size of the trailing it was out-factored into a separate rule temporarily:
member_access : (array_creation_expression DOT IDENTIFIER type_argument_list? | predefined_type DOT IDENTIFIER type_argument_list? | qualified_alias_member DOT IDENTIFIER type_argument_list? | literal member_access_trailing | simple_name member_access_trailing | parenthesized_expression member_access_trailing | this_access member_access_trailing | base_access member_access_trailing | array_creation_expression OPEN_PARENS argument_list? CLOSE_PARENS member_access_trailing | array_creation_expression OP_INC member_access_trailing | array_creation_expression OP_DEC member_access_trailing | array_creation_expression OP_PTR IDENTIFIER member_access_trailing | object_creation_expression member_access_trailing | delegate_creation_expression member_access_trailing | anonymous_object_creation_expression member_access_trailing | typeof_expression member_access_trailing | checked_expression member_access_trailing | unchecked_expression member_access_trailing | default_value_expression member_access_trailing | anonymous_method_expression member_access_trailing | sizeof_expression member_access_trailing ) member_access_trailing* ; member_access_trailing : (OPEN_PARENS argument_list? CLOSE_PARENS | OPEN_BRACKET (expression_list | expression) CLOSE_BRACKET | OP_INC | OP_DEC | OP_PTR IDENTIFIER )* DOT IDENTIFIER type_argument_list? ;
As one can easily see, most alternatives of member_access include member_access_trailing. Looking more closely, the only three alternatives, which don't include the member_access_trailing, use only the zero-or-more-closure of member_access_trailing.
The simplification is complicated by the fact that there are four other array_creation_expression-s. Taking all five alternatives into account, we can actually combine all array_creation_expression-s into one. Using our "we check it in the next pass"-trick we can simplify member_access to:
member_access : (array_creation_expression | predefined_type | qualified_alias_member | literal | simple_name | parenthesized_expression | this_access | base_access | object_creation_expression | delegate_creation_expression | anonymous_object_creation_expression | typeof_expression | checked_expression | unchecked_expression | default_value_expression | anonymous_method_expression | sizeof_expression ) (OPEN_PARENS argument_list? CLOSE_PARENS | OPEN_BRACKET (expression_list | expression) CLOSE_BRACKET | OP_INC | OP_DEC | OP_PTR IDENTIFIER | DOT IDENTIFIER type_argument_list? )+ ;
The second pass has to check for the alternatives predefined_type and qualified_alias_member, that they are directly followed by a DOT. array_creation_expression may not be followed by OPEN_BRACKET. It has to be also checked that DOT IDENTIFIER type_argument_list? is the last matched sequence.
Sections
My siblings (including me):