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):