Skip to content

bug: template method calls parsed as two comparison operators #346

@Oded-Livneh-JFrog

Description

@Oded-Livneh-JFrog

Did you check existing issues?

  • I have read all the tree-sitter docs if it relates to using the parser
  • I have searched the existing issues of tree-sitter-cpp

Tree-Sitter CLI Version, if relevant (output of tree-sitter --version)

No response

Describe the bug

Description

TreeSitter incorrectly parses calls to template member functions as comparison operators when the template arguments are specified with angle brackets.

Minimal Reproduction

struct S {
    template<int N>
    void parse(char* x) {}
};

int main() {
    S doc;
    doc.parse<0>(nullptr);
}

Expected Behavior

The line doc.parse<0>(nullptr); should be parsed as a single expression:

  • A member function call to parse
  • With template argument <0>
  • With function argument (nullptr)

Actual Behavior

TreeSitter appears to parse doc.parse<0>(nullptr); as two separate comparison operations:

tmp_1 = doc.parse < 0;
tmp_2 = tmp_1 > (nullptr);

the actual parsing

the part of the tree for the last line of code, doc.parse<0>(nullptr);, is:

expression_statement [7, 4] - [7, 26]
        binary_expression [7, 4] - [7, 25]
          left: binary_expression [7, 4] - [7, 15]
            left: field_expression [7, 4] - [7, 13]
              argument: identifier [7, 4] - [7, 7]
              field: field_identifier [7, 8] - [7, 13]
            right: number_literal [7, 14] - [7, 15]
          right: parenthesized_expression [7, 16] - [7, 25]
            null [7, 17] - [7, 24]

Root Cause

The < token after a member function name is syntactically ambiguous in C++:

  1. It could start a template argument list (correct interpretation in this case)
  2. It could be a less-than comparison operator

Steps To Reproduce/Bad Parse Tree

paste the code snippet I suggested into the tree-sitter playground, setting language to C++

Expected Behavior/Parse Tree

it should be a template, not a binary operation

Repro

struct S {
    template<int N>
    void parse(char* x) {}
};

int main() {
    S doc;
    doc.parse<0>(nullptr);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions