Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ module.exports = grammar({
[$._postfix_unary_expression, $._expression],

// ambiguity between generics and comparison operations (foo < b > c)
[$.call_expression, $.prefix_expression, $.comparison_expression],
[$.call_expression, $.range_expression, $.comparison_expression],
[$.call_expression, $.elvis_expression, $.comparison_expression],
[$.call_expression, $.check_expression, $.comparison_expression],
[$.call_expression, $.additive_expression, $.comparison_expression],
[$.call_expression, $.infix_expression, $.comparison_expression],
[$.call_expression, $.multiplicative_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.prefix_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.range_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.elvis_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.check_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.additive_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.infix_expression, $.comparison_expression],
[$.call_expression, $.navigation_expression, $.multiplicative_expression, $.comparison_expression],
[$.type_arguments, $._comparison_operator],

// ambiguity between prefix expressions and annotations before functions
Expand All @@ -113,6 +113,7 @@ module.exports = grammar({

// ambiguity between parameter modifiers in anonymous functions
[$.parameter_modifiers, $._type_modifier],

],

externals: $ => [
Expand Down Expand Up @@ -673,6 +674,8 @@ module.exports = grammar({
indexing_suffix: $ => seq("[", sep1($._expression, ","), "]"),

navigation_suffix: $ => seq(
// this introduces ambiguities with 'less than' for comparisons
optional($.type_arguments),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'm not quite sure how I feel about this workaround. While I understand that it's hard to parse, it seems to deviate quite a bit from the reference grammar and including the type arguments in the navigation suffix node (both of which are exposed), downstream consumers might have to rewrite the syntax tree quite a bit to get accurate results.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it just comes down to how much you weigh being able to parse this versus the compromises we've already made with the syntax tree. For instance, this call_suffix workaround (which basically does the same thing, by embedding the optional type arguments in a different node of the tree) was worthy enough of being included, so I see this as adding just another case.

I can keep thinking about it, but this seems like a rather pervasive parsing issue, from the things I've seen, and I'm not sure if we can make something truly faithful to the original syntax specification. At the end of the day, the Kotlin grammar is a reference for specification, but implementation may face some difficulties emulating it.

$._member_access_operator,
choice(
$.simple_identifier,
Expand Down
19 changes: 19 additions & 0 deletions src/grammar.json
Original file line number Diff line number Diff line change
Expand Up @@ -3316,6 +3316,18 @@
"navigation_suffix": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "type_arguments"
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_member_access_operator"
Expand Down Expand Up @@ -6133,36 +6145,43 @@
],
[
"call_expression",
"navigation_expression",
"prefix_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"range_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"elvis_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"check_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"additive_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"infix_expression",
"comparison_expression"
],
[
"call_expression",
"navigation_expression",
"multiplicative_expression",
"comparison_expression"
],
Expand Down
Loading