tree-sitter-c-sharp icon indicating copy to clipboard operation
tree-sitter-c-sharp copied to clipboard

Incorrect precedence in conditional_access_expression

Open Sjord opened this issue 4 years ago • 7 comments

var a = b?.Something?.Something;

Actual:

(equals_value_clause [6, 14] - [6, 39]
    (conditional_access_expression [6, 16] - [6, 39]
        (conditional_access_expression [6, 16] - [6, 28]
            (identifier [6, 16] - [6, 17])
            (member_binding_expression [6, 18] - [6, 28]
            (identifier [6, 19] - [6, 28])))
        (member_binding_expression [6, 29] - [6, 39]
            (identifier [6, 30] - [6, 39]))))))))))))

Expected:

(equals_value_clause [6, 14] - [6, 39]
  (conditional_access_expression [6, 16] - [6, 39]
    (identifier [6, 16] - [6, 17])
    (conditional_access_expression [6, 18] - [6, 39]
      (member_binding_expression [6, 18] - [6, 28]
        (identifier [6, 19] - [6, 28]))
      (member_binding_expression [6, 29] - [6, 39]
        (identifier [6, 30] - [6, 39])))))))))))))

Sjord avatar Mar 24 '21 11:03 Sjord

Other issues related to conditional access expressions are #131, #138, #151, #173.

Sjord avatar Mar 25 '21 10:03 Sjord

Test case:

=====================================
Conditional access expression is right-associative
=====================================

var a = b?.Something?.Something;

---

(compilation_unit
  (global_statement
    (local_declaration_statement
      (variable_declaration
        (implicit_type)
        (variable_declarator
          (identifier)
          (equals_value_clause
            (conditional_access_expression
              (identifier)
              (conditional_access_expression
                (member_binding_expression
                  (identifier))
                (member_binding_expression
                  (identifier))))))))))

Sjord avatar Apr 29 '21 13:04 Sjord

I thought conditional access expressions should be right-associative because:

However, whether it is left or right associative may not make much of a functional difference. I can't think of a situation where using left-associativity would give another result to an expression. So this may not really be a big problem.

Sjord avatar Apr 30 '21 14:04 Sjord

I think the problems with conditional access are related to this issue: Adding a rule changes associativity from right to left · Issue #1301 · tree-sitter/tree-sitter

Conditional access expressions conflict with the conditional ternary operator.

a || a ? .b
a || a ? true : false

If the parser sees a || a ?, it doesn't know whether to reduce a || a into an expr or keep parsing. Currently, it reduces. This is correct for the conditional ternary operator, but incorrect for the conditional access expression.

Sjord avatar Sep 15 '22 08:09 Sjord

@maxbrunsfeld have you got any ideas how we could tackle this one?

damieng avatar Sep 15 '22 08:09 damieng

If the parser sees a || a ?, it doesn't know whether to reduce a || a into an expr or keep parsing.

I think it can't know with just one lookahead token.

In a || a · ?, the ? is one token lookahead, but that is insufficient information do determine whether to reduce a || a or not. We need to lookahead further, to find out whether the ? is part of ? expr : expr or ?. expr. This can be done with an external scanner. An external scanner can lookahead further, but it adds complexity. Particularly because it also should skip comments/extras.

Sjord avatar Aug 07 '23 12:08 Sjord