diff --git a/grammar.js b/grammar.js index b5c8e97..4cb788b 100644 --- a/grammar.js +++ b/grammar.js @@ -547,7 +547,8 @@ module.exports = grammar(CPP1, { choice($.cpp2_non_template_identifier, $._cpp2_template_identifier), _cpp2_template_identifier: ($) => - seq($.cpp2_non_template_identifier, $.cpp2_template_call_arguments), + // dynamic precedence for preferring this to _cpp2_no_namespace_identifier + prec.dynamic(1, seq($.cpp2_non_template_identifier, $.cpp2_template_call_arguments)), cpp2_non_template_identifier: ($) => choice($.cpp2_operator_keyword, $.cpp2_ordinary_identifier), diff --git a/src/grammar.json b/src/grammar.json index be42243..1400368 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -19276,17 +19276,21 @@ ] }, "_cpp2_template_identifier": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "cpp2_non_template_identifier" - }, - { - "type": "SYMBOL", - "name": "cpp2_template_call_arguments" - } - ] + "type": "PREC_DYNAMIC", + "value": 1, + "content": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "cpp2_non_template_identifier" + }, + { + "type": "SYMBOL", + "name": "cpp2_template_call_arguments" + } + ] + } }, "cpp2_non_template_identifier": { "type": "CHOICE", diff --git a/src/parser.c b/src/parser.c index 77a0790..8065707 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1231338,8 +1231338,8 @@ static const TSParseActionEntry ts_parse_actions[] = { [8819] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_cpp2_operator_keyword, 3, 0, 0), [8821] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_cpp2_operator_keyword, 3, 0, 0), [8823] = {.entry = {.count = 1, .reusable = true}}, SHIFT(1442), - [8825] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym__cpp2_template_identifier, 2, 0, 0), - [8827] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym__cpp2_template_identifier, 2, 0, 0), + [8825] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym__cpp2_template_identifier, 2, 1, 0), + [8827] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym__cpp2_template_identifier, 2, 1, 0), [8829] = {.entry = {.count = 1, .reusable = true}}, SHIFT(1460), [8831] = {.entry = {.count = 1, .reusable = false}}, REDUCE(sym_cpp2_user_defined_literal, 2, 0, 0), [8833] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_cpp2_user_defined_literal, 2, 0, 0), diff --git a/test/corpus/template_precedence.txt b/test/corpus/template_precedence.txt new file mode 100644 index 0000000..bc0ddab --- /dev/null +++ b/test/corpus/template_precedence.txt @@ -0,0 +1,257 @@ +=========================================================== +unary operator +=========================================================== + +a: () = -a(x); +a: () = a(x); + +----------------------------------------------------------- + +(translation_unit + (cpp2_expression_declaration + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_expression_definition + (cpp2_left_side_of_definition + (cpp2_expression + (cpp2_type + (cpp2_function_type + (cpp2_function_type_without_return_type))))) + (cpp2_expression + (cpp2_unary_expression + (cpp2_unary_prefix_expression + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier)))))))))))))) + (cpp2_expression_declaration + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_expression_definition + (cpp2_left_side_of_definition + (cpp2_expression + (cpp2_type + (cpp2_function_type + (cpp2_function_type_without_return_type))))) + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier)))))))))))) + +=========================================================== +binary operator +=========================================================== + +a: () = a(piece) - a(Piece::pawn); +a: () = a(piece) - (a(Piece::pawn)); +a: () = (a(piece)) - a(Piece::pawn); + + +----------------------------------------------------------- + +(translation_unit + (cpp2_expression_declaration + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_expression_definition + (cpp2_left_side_of_definition + (cpp2_expression + (cpp2_type + (cpp2_function_type + (cpp2_function_type_without_return_type))))) + (cpp2_expression + (cpp2_binary_expression + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))))))))) + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))))))))))))) + (cpp2_expression_declaration + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_expression_definition + (cpp2_left_side_of_definition + (cpp2_expression + (cpp2_type + (cpp2_function_type + (cpp2_function_type_without_return_type))))) + (cpp2_expression + (cpp2_binary_expression + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))))))))) + (cpp2_expression + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier)))))))))))))))) + (cpp2_expression_declaration + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_expression_definition + (cpp2_left_side_of_definition + (cpp2_expression + (cpp2_type + (cpp2_function_type + (cpp2_function_type_without_return_type))))) + (cpp2_expression + (cpp2_binary_expression + (cpp2_expression + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier)))))))))))) + (cpp2_expression + (cpp2_function_call + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_template_call_arguments + (cpp2_comma_expressions + (cpp2_expression + (cpp2_keyword + (cpp2_primitive_type + (primitive_type)))))))) + (cpp2_parentheses_expression + (cpp2_comma_expressions + (cpp2_expression + (cpp2_any_identifier + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))) + (cpp2_non_template_identifier + (cpp2_ordinary_identifier + (identifier))))))))))))))