diff --git a/parser/internal/pratt_parser_test.cc b/parser/internal/pratt_parser_test.cc index 6c85dd1d7..908690bc8 100644 --- a/parser/internal/pratt_parser_test.cc +++ b/parser/internal/pratt_parser_test.cc @@ -482,6 +482,72 @@ std::vector GetParserTestCases() { )^#1:Expr.Call# )", }, + TestCase{ + .source = "-.2.V", + .expected_ast = R"( + -0.2^#1:double#.V^#2:Expr.Select# + )", + }, + TestCase{ + .source = "!-.2.V", + .expected_ast = R"( + !_( + -0.2^#2:double#.V^#3:Expr.Select# + )^#1:Expr.Call# + )", + }, + TestCase{ + .source = "!-2.V", + .expected_ast = R"( + !_( + -2^#2:int64#.V^#3:Expr.Select# + )^#1:Expr.Call# + )", + }, + TestCase{ + .source = "!-.2[0]", + .expected_ast = R"( + !_( + _[_]( + -0.2^#2:double#, + 0^#4:int64# + )^#3:Expr.Call# + )^#1:Expr.Call# + )", + }, + TestCase{ + .source = "-x.foo[0]", + .expected_ast = R"( + -_( + _[_]( + x^#2:Expr.Ident#.foo^#3:Expr.Select#, + 0^#5:int64# + )^#4:Expr.Call# + )^#1:Expr.Call# + )", + }, + TestCase{ + .source = "-x[0].foo", + .expected_ast = R"( + -_( + _[_]( + x^#2:Expr.Ident#, + 0^#4:int64# + )^#3:Expr.Call#.foo^#5:Expr.Select# + )^#1:Expr.Call# + )", + }, + TestCase{ + .source = "!x[0].foo", + .expected_ast = R"( + !_( + _[_]( + x^#2:Expr.Ident#, + 0^#4:int64# + )^#3:Expr.Call#.foo^#5:Expr.Select# + )^#1:Expr.Call# + )", + }, TestCase{ .source = "a + b", .expected_ast = R"( diff --git a/parser/internal/pratt_parser_worker.h b/parser/internal/pratt_parser_worker.h index f4886aa90..1f99984c5 100644 --- a/parser/internal/pratt_parser_worker.h +++ b/parser/internal/pratt_parser_worker.h @@ -556,10 +556,12 @@ ExprNode PrattParserWorker::ParseUnaryOpsChain(Token first_op) { int64_t op_id = ops.back().id; ops.pop_back(); operand = ParseNegativeIntLiteral(op_id); + ParseSelectorChainTail(operand); } else if (peek_token_.type == TokenType::kFloat) { int64_t op_id = ops.back().id; ops.pop_back(); operand = ParseNegativeDoubleLiteral(op_id); + ParseSelectorChainTail(operand); } else { operand = ParseSelectorChain(); } diff --git a/parser/parser_test.cc b/parser/parser_test.cc index e47557e6b..dbac2b02f 100644 --- a/parser/parser_test.cc +++ b/parser/parser_test.cc @@ -137,6 +137,27 @@ std::vector test_cases = { " a^#1:Expr.Ident#,\n" " 3^#3:int64#\n" ")^#2:Expr.Call#"}, + {"-x.foo[0]", + "-_(\n" + " _[_](\n" + " x^#2:Expr.Ident#.foo^#3:Expr.Select#,\n" + " 0^#5:int64#\n" + " )^#4:Expr.Call#\n" + ")^#1:Expr.Call#"}, + {"-x[0].foo", + "-_(\n" + " _[_](\n" + " x^#2:Expr.Ident#,\n" + " 0^#4:int64#\n" + " )^#3:Expr.Call#.foo^#5:Expr.Select#\n" + ")^#1:Expr.Call#"}, + {"!x[0].foo", + "!_(\n" + " _[_](\n" + " x^#2:Expr.Ident#,\n" + " 0^#4:int64#\n" + " )^#3:Expr.Call#.foo^#5:Expr.Select#\n" + ")^#1:Expr.Call#"}, {"SomeMessage{foo: 5, bar: \"xyz\"}", "SomeMessage{\n" " foo:5^#3:int64#^#2:Expr.CreateStruct.Entry#,\n"