From 2d4e7a2a3d8caaa6a4b17288d2d7f3f646ec7b9e Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Mon, 31 Aug 2026 15:40:24 -0700 Subject: [PATCH] [Pratt parser] Align Pratt parser AST node ID generation with the standard parser. PiperOrigin-RevId: 974116830 --- parser/internal/pratt_parser_test.cc | 16 ++-- parser/internal/pratt_parser_worker.cc | 8 ++ parser/internal/pratt_parser_worker.h | 93 ++++++++++--------- parser/parser_test.cc | 120 +++++++++---------------- 4 files changed, 108 insertions(+), 129 deletions(-) diff --git a/parser/internal/pratt_parser_test.cc b/parser/internal/pratt_parser_test.cc index 422a5d19f..4fd2b02ec 100644 --- a/parser/internal/pratt_parser_test.cc +++ b/parser/internal/pratt_parser_test.cc @@ -434,7 +434,7 @@ std::vector GetParserTestCases() { TestCase{ .source = "- -1", .expected_ast = R"( - 1^#3:int64# + 1^#1:int64# )", }, TestCase{ @@ -452,7 +452,7 @@ std::vector GetParserTestCases() { .source = "---a", .expected_ast = R"( -_( - a^#4:Expr.Ident# + a^#2:Expr.Ident# )^#1:Expr.Call# )", }, @@ -1082,8 +1082,8 @@ std::vector GetParserTestCases() { .source = "{'key': 'value', 'num': 42}", .expected_ast = R"( { - "key"^#2:string#:"value"^#4:string#^#3:Expr.CreateStruct.Entry#, - "num"^#5:string#:42^#7:int64#^#6:Expr.CreateStruct.Entry# + "key"^#3:string#:"value"^#4:string#^#2:Expr.CreateStruct.Entry#, + "num"^#6:string#:42^#7:int64#^#5:Expr.CreateStruct.Entry# }^#1:Expr.CreateMap# )", }, @@ -1091,8 +1091,8 @@ std::vector GetParserTestCases() { .source = "{?'key': 'value', 'num': 42}", .expected_ast = R"( { - ?"key"^#2:string#:"value"^#4:string#^#3:Expr.CreateStruct.Entry#, - "num"^#5:string#:42^#7:int64#^#6:Expr.CreateStruct.Entry# + ?"key"^#3:string#:"value"^#4:string#^#2:Expr.CreateStruct.Entry#, + "num"^#6:string#:42^#7:int64#^#5:Expr.CreateStruct.Entry# }^#1:Expr.CreateMap# )", .enable_optional_syntax = true, @@ -1101,8 +1101,8 @@ std::vector GetParserTestCases() { .source = "{foo: 5, bar: \"xyz\"}", .expected_ast = R"( { - foo^#2:Expr.Ident#:5^#4:int64#^#3:Expr.CreateStruct.Entry#, - bar^#5:Expr.Ident#:"xyz"^#7:string#^#6:Expr.CreateStruct.Entry# + foo^#3:Expr.Ident#:5^#4:int64#^#2:Expr.CreateStruct.Entry#, + bar^#6:Expr.Ident#:"xyz"^#7:string#^#5:Expr.CreateStruct.Entry# }^#1:Expr.CreateMap# )", }, diff --git a/parser/internal/pratt_parser_worker.cc b/parser/internal/pratt_parser_worker.cc index 198a70c4f..b01408774 100644 --- a/parser/internal/pratt_parser_worker.cc +++ b/parser/internal/pratt_parser_worker.cc @@ -216,6 +216,14 @@ int64_t ParserWorker::NextId(int32_t position) { int64_t ParserWorker::NextId() { return NextId(-1); } +void ParserWorker::SetPosition(int64_t id, const Token& token) { + if (token.start >= 0) { + positions_[id] = token.start; + SetNodeRange(id, token.start, + token.end > token.start ? token.end - 1 : token.start); + } +} + int64_t ParserWorker::CopyId(int64_t id) { if (id == 0) { return 0; diff --git a/parser/internal/pratt_parser_worker.h b/parser/internal/pratt_parser_worker.h index 966717af1..e1608a3a2 100644 --- a/parser/internal/pratt_parser_worker.h +++ b/parser/internal/pratt_parser_worker.h @@ -16,6 +16,7 @@ #define THIRD_PARTY_CEL_CPP_PARSER_INTERNAL_PRATT_PARSER_WORKER_H_ #include +#include #include #include #include @@ -83,14 +84,12 @@ class ParserWorker { int64_t NextId(int32_t position); int64_t NextId(const Token& token) { int64_t id = NextId(token.start); - if (ABSL_PREDICT_FALSE(track_node_ranges_)) { - if (token.start >= 0 && token.end > token.start) { - node_ranges_[id] = {token.start, token.end - 1}; - } - } + SetNodeRange(id, token.start, + token.end > token.start ? token.end - 1 : token.start); return id; } int64_t NextId(); + void SetPosition(int64_t id, const Token& token); int64_t CopyId(int64_t id); void EraseId(int64_t id); void SetNodeRange(int64_t id, int32_t begin, int32_t end) { @@ -150,6 +149,7 @@ template class PrattParserWorker : public ParserWorker { public: using ParserWorker::NextId; + using ParserWorker::SetPosition; explicit PrattParserWorker( const cel::Source& source, const cel::ParserOptions& options, @@ -530,57 +530,61 @@ void PrattParserWorker::ParseSelectorChainTail(ExprNode& lhs) { template ExprNode PrattParserWorker::ParseUnaryOpsChain(Token first_op) { - struct UnaryOpInfo { - TokenType type; - int64_t id; + struct UnaryOp { + Token token; + int64_t id = 0; }; - std::vector ops; - ops.push_back({first_op.type, NextId(first_op)}); - + std::vector ops; + ops.push_back({first_op}); while (peek_token_.type == TokenType::kExclamation || peek_token_.type == TokenType::kMinus) { - Token op = NextToken(); - ops.push_back({op.type, NextId(op)}); + ops.push_back({NextToken()}); } - ExprNode operand; - if (!ops.empty() && ops.back().type == TokenType::kMinus) { - if (options_.fold_unary_operators && ops.size() > 1 && - ops[ops.size() - 2].type == TokenType::kMinus) { - // Match the ANTLR parser behavior where `-(-)+` prefers to match as - // repeated negate operators instead of a negation of an int literal. - // ---9223372036854775808 will fail to parse. - ops.pop_back(); - ops.pop_back(); - operand = ParseSelectorChain(); - } else if (peek_token_.type == TokenType::kInt) { - 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(); + const bool has_solitary_trailing_minus = + !ops.empty() && ops.back().token.type == TokenType::kMinus && + (ops.size() == 1 || ops[ops.size() - 2].token.type != TokenType::kMinus); + + if (options_.fold_unary_operators) { + size_t write = 0; + for (size_t read = 0; read < ops.size();) { + size_t next = read; + while (next < ops.size() && + ops[next].token.type == ops[read].token.type) { + next++; + } + if ((next - read) % 2 != 0) { + ops[write++] = ops[read]; + } + read = next; } + ops.resize(write); + } + + for (auto& op : ops) { + op.id = NextId(op.token); + } + + ExprNode operand; + // Match the ANTLR parser behavior where `-(-)+` prefers to match as + // repeated negate operators instead of a negation of an int literal. + // ---9223372036854775808 will fail to parse. + if (has_solitary_trailing_minus && (peek_token_.type == TokenType::kInt || + peek_token_.type == TokenType::kFloat)) { + int64_t op_id = ops.back().id; + ops.pop_back(); + operand = (peek_token_.type == TokenType::kInt) + ? ParseNegativeIntLiteral(op_id) + : ParseNegativeDoubleLiteral(op_id); + ParseSelectorChainTail(operand); } else { operand = ParseSelectorChain(); } for (int i = static_cast(ops.size()) - 1; i >= 0; --i) { std::vector args; - if (options_.fold_unary_operators && i > 0) { - if (ops[i - 1].type == ops[i].type) { - i--; - continue; - } - } - args.push_back(std::move(operand)); - absl::string_view op_name = (ops[i].type == TokenType::kExclamation) + absl::string_view op_name = (ops[i].token.type == TokenType::kExclamation) ? CelOperator::LOGICAL_NOT : CelOperator::NEGATE; operand = @@ -777,12 +781,13 @@ ExprNode PrattParserWorker::ParseMap() { } key_start = peek_token_; } + int64_t entry_id = NextId(); ExprNode key = ParseExpr(); Token colon = peek_token_; if (!Expect(TokenType::kColon, "expected ':' in map entry")) { break; } - int64_t entry_id = NextId(colon); + SetPosition(entry_id, colon); builder.Add(entry_id, std::move(key), ParseExpr(), optional); if (peek_token_.type == TokenType::kComma) { NextToken(); diff --git a/parser/parser_test.cc b/parser/parser_test.cc index cc9fbc5fe..d51339796 100644 --- a/parser/parser_test.cc +++ b/parser/parser_test.cc @@ -65,15 +65,8 @@ struct TestInfo { TestInfo(const std::string& I, const std::string& P, const std::string& E = "", const std::string& L = "", const std::string& R = "", const std::string& M = "", - const std::string& P_PRATT = "", const std::string& E_PRATT = "") - : I(I), - P(P), - E(E), - L(L), - R(R), - M(M), - P_PRATT(P_PRATT), - E_PRATT(E_PRATT) {} + const std::string& E_PRATT = "") + : I(I), P(P), E(E), L(L), R(R), M(M), E_PRATT(E_PRATT) {} // I contains the input expression to be parsed. std::string I; @@ -94,9 +87,6 @@ struct TestInfo { // M contains the expected macro call output of hte expression tree. std::string M; - // P_PRATT contains alternative adorned AST string when using pratt parser. - std::string P_PRATT; - // E_PRATT contains alternative error output when using pratt parser. std::string E_PRATT; }; @@ -173,12 +163,16 @@ std::vector test_cases = { "{\n" " foo^#3:Expr.Ident#:5^#4:int64#^#2:Expr.CreateStruct.Entry#,\n" " bar^#6:Expr.Ident#:\"xyz\"^#7:string#^#5:Expr.CreateStruct.Entry#\n" - "}^#1:Expr.CreateStruct#", - "", "", "", "", - // PRATT PARSER AST + "}^#1:Expr.CreateStruct#"}, + {"{\"foo\": 5, \"bar\": \"xyz\"}", + "{\n" + " \"foo\"^#3:string#:5^#4:int64#^#2:Expr.CreateStruct.Entry#,\n" + " \"bar\"^#6:string#:\"xyz\"^#7:string#^#5:Expr.CreateStruct.Entry#\n" + "}^#1:Expr.CreateStruct#"}, + {"{'a': 1, 'b': 2}", "{\n" - " foo^#2:Expr.Ident#:5^#4:int64#^#3:Expr.CreateStruct.Entry#,\n" - " bar^#5:Expr.Ident#:\"xyz\"^#7:string#^#6:Expr.CreateStruct.Entry#\n" + " \"a\"^#3:string#:1^#4:int64#^#2:Expr.CreateStruct.Entry#,\n" + " \"b\"^#6:string#:2^#7:int64#^#5:Expr.CreateStruct.Entry#\n" "}^#1:Expr.CreateStruct#"}, {"a > 5 && a < 10", "_&&_(\n" @@ -210,7 +204,7 @@ std::vector test_cases = { "NUM_INT, " "NUM_UINT, STRING, BYTES, IDENTIFIER}\n | {\n" " | .^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:2: Syntax error: expected '}'\n" " | {\n" @@ -407,12 +401,6 @@ std::vector test_cases = { "{\n" " a^#3:Expr.Ident#:b^#4:Expr.Ident#^#2:Expr.CreateStruct.Entry#,\n" " c^#6:Expr.Ident#:d^#7:Expr.Ident#^#5:Expr.CreateStruct.Entry#\n" - "}^#1:Expr.CreateStruct#", - "", "", "", "", - // PRATT PARSER AST - "{\n" - " a^#2:Expr.Ident#:b^#4:Expr.Ident#^#3:Expr.CreateStruct.Entry#,\n" - " c^#5:Expr.Ident#:d^#7:Expr.Ident#^#6:Expr.CreateStruct.Entry#\n" "}^#1:Expr.CreateStruct#"}, {"[]", "[]^#1:Expr.CreateList#"}, {"[a]", @@ -478,7 +466,7 @@ std::vector test_cases = { "ERROR: :1:7: Syntax error: extraneous input 'b' expecting \n" " | *@a | b\n" " | ......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: Syntax error: unexpected token\n" " | *@a | b\n" @@ -493,7 +481,7 @@ std::vector test_cases = { "ERROR: :1:5: Syntax error: extraneous input 'b' expecting \n" " | a | b\n" " | ....^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:3: Syntax error: unexpected single '|', expected '||'\n" " | a | b\n" @@ -506,7 +494,7 @@ std::vector test_cases = { "{'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, " "NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n | ?\n | .^\n" "ERROR: :4294967295:0: <> parsetree", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: Syntax error: unexpected token\n" " | ?\n" @@ -517,7 +505,7 @@ std::vector test_cases = { ":1:5: " "Syntax error: " "mismatched input '}' expecting ':'\n | t{>C}\n | ....^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:3: Syntax error: expected struct field name\n" " | t{>C}\n" @@ -528,7 +516,7 @@ std::vector test_cases = { "NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | foo(a,b,)\n" " | ........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:9: unexpected token\n" " | foo(a,b,)\n" @@ -678,12 +666,6 @@ std::vector test_cases = { "{\n" " 1^#3:int64#:2u^#4:uint64#^#2:Expr.CreateStruct.Entry#,\n" " 2^#6:int64#:3u^#7:uint64#^#5:Expr.CreateStruct.Entry#\n" - "}^#1:Expr.CreateStruct#", - "", "", "", "", - // PRATT PARSER AST - "{\n" - " 1^#2:int64#:2u^#4:uint64#^#3:Expr.CreateStruct.Entry#,\n" - " 2^#5:int64#:3u^#7:uint64#^#6:Expr.CreateStruct.Entry#\n" "}^#1:Expr.CreateStruct#"}, {"TestAllTypes{single_int32: 1, single_int64: 2}", "TestAllTypes{\n" @@ -694,7 +676,7 @@ std::vector test_cases = { "ERROR: :1:15: Syntax error: mismatched input '{' expecting \n" " | TestAllTypes(){single_int32: 1, single_int64: 2}\n" " | ..............^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:15: Syntax error: unexpected token after expression\n" " | TestAllTypes(){single_int32: 1, single_int64: 2}\n" @@ -716,7 +698,7 @@ std::vector test_cases = { "NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | 1 + $\n" " | .....^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:5: Syntax error: unexpected character\n" " | 1 + $\n" @@ -727,7 +709,7 @@ std::vector test_cases = { "ERROR: :2:1: Syntax error: mismatched input '3' expecting \n" " | 3 +\n" " | ^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :2:1: Syntax error: unexpected token after expression\n" " | 3 +\n" @@ -750,7 +732,7 @@ std::vector test_cases = { "ERROR: :1:9: all() variable name must be a simple identifier\n" " | [].all(.x, x)\n" " | ........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:8: all() variable name must be a simple identifier\n" " | [].all(.x, x)\n" @@ -759,7 +741,7 @@ std::vector test_cases = { "ERROR: :1:12: exists() variable name must be a simple identifier\n" " | [].exists(.x, x)\n" " | ...........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:11: exists() variable name must be a simple identifier\n" " | [].exists(.x, x)\n" @@ -769,7 +751,7 @@ std::vector test_cases = { "identifier\n" " | [].exists_one(.x, x)\n" " | ...............^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:15: exists_one() variable name must be a simple " "identifier\n" @@ -779,7 +761,7 @@ std::vector test_cases = { "ERROR: :1:9: map() variable name must be a simple identifier\n" " | [].map(.x, x, x)\n" " | ........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:8: map() variable name must be a simple identifier\n" " | [].map(.x, x, x)\n" @@ -788,7 +770,7 @@ std::vector test_cases = { "ERROR: :1:12: filter() variable name must be a simple identifier\n" " | [].filter(.x, x)\n" " | ...........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:11: filter() variable name must be a simple identifier\n" " | [].filter(.x, x)\n" @@ -848,11 +830,6 @@ std::vector test_cases = { {"---a", "-_(\n" " a^#2:Expr.Ident#\n" - ")^#1:Expr.Call#", - "", "", "", "", - // PRATT PARSER AST - "-_(\n" - " a^#4:Expr.Ident#\n" ")^#1:Expr.Call#"}, {"1 + +", "", "ERROR: :1:5: Syntax error: mismatched input '+' expecting {'[', " @@ -868,7 +845,7 @@ std::vector test_cases = { "NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | 1 + +\n" " | .....^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:5: Syntax error: unexpected token\n" " | 1 + +\n" @@ -883,7 +860,7 @@ std::vector test_cases = { "'.\"a\"'\n" " | {\"a\": 1}.\"a\"\n" " | .........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:10: Syntax error: expected identifier after '.'\n" " | {\"a\": 1}.\"a\"\n" @@ -907,7 +884,7 @@ std::vector test_cases = { "NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | \"\\xFh\"\n" " | ......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: Invalid string literal: Illegal escape sequence: Hex " "escape must be followed by 2 hex digits but saw: \\xFh\n" @@ -927,7 +904,7 @@ std::vector test_cases = { "NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | \"\\a\\b\\f\\n\\r\\t\\v\\'\\\"\\\\\\? Illegal escape \\>\"\n" " | ..........................................^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: Invalid string literal: Illegal escape sequence: " "\\>\n" @@ -983,7 +960,7 @@ std::vector test_cases = { "ERROR: :2:11: Syntax error: no viable alternative at input '.'\n" " | && in.😁\n" " | ..........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :2:7: Syntax error: unexpected token\n" " | && in.😁\n" @@ -1039,7 +1016,7 @@ std::vector test_cases = { "NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | in\n" " | ..^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: Syntax error: unexpected token\n" " | in\n" @@ -1089,7 +1066,7 @@ std::vector test_cases = { "ERROR: :1:26: reserved identifier: var\n" " | [1, 2, 3].map(var, var * var)\n" " | .........................^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:15: reserved identifier: var\n" " | [1, 2, 3].map(var, var * var)\n" @@ -1127,7 +1104,7 @@ std::vector test_cases = { "{']', ','}\n" " | \r\n" " | ..^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :6:3: Syntax error: expected ']'\n" " | \r\n" @@ -1173,7 +1150,7 @@ std::vector test_cases = { "ERROR: :1:7: Syntax error: token recognition error at: '`'\n" " | a.`b c`\n" " | ......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:3: unexpected quoted identifier\n" " | a.`b c`\n" @@ -1185,7 +1162,7 @@ std::vector test_cases = { "ERROR: :1:8: Syntax error: token recognition error at: '`'\n" " | a.`@foo`\n" " | .......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:3: unexpected quoted identifier\n" " | a.`@foo`\n" @@ -1197,7 +1174,7 @@ std::vector test_cases = { "ERROR: :1:8: Syntax error: token recognition error at: '`'\n" " | a.`$foo`\n" " | .......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:3: unexpected quoted identifier\n" " | a.`$foo`\n" @@ -1210,7 +1187,7 @@ std::vector test_cases = { "BYTES, IDENTIFIER}\n" " | `a.b`\n" " | ^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: unexpected quoted identifier\n" " | `a.b`\n" @@ -1226,7 +1203,7 @@ std::vector test_cases = { "_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n" " | `a.b`()\n" " | ......^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:1: unexpected quoted identifier\n" " | `a.b`()\n" @@ -1235,7 +1212,7 @@ std::vector test_cases = { "ERROR: :1:10: Syntax error: mismatched input '(' expecting \n" " | foo.`a.b`()\n" " | .........^", - "", "", "", "", + "", "", "", // PRATT PARSER ERROR MESSAGE "ERROR: :1:5: unexpected quoted identifier\n" " | foo.`a.b`()\n" @@ -1292,8 +1269,7 @@ std::vector test_cases = { " @result^#24:Expr.Ident#\n" " )^#25:Expr.Call#,\n" " // Result\n" - " @result^#26:Expr.Ident#)^#27:Expr.Comprehension#" - "", + " @result^#26:Expr.Ident#)^#27:Expr.Comprehension#", "", "", "", "x^#1:Expr.Ident#.filter(\n" " y^#3:Expr.Ident#,\n" @@ -1515,12 +1491,7 @@ std::vector test_cases = { {"{?'key': value}", "{\n " "?\"key\"^#3:string#:value^#4:Expr.Ident#^#2:Expr.CreateStruct.Entry#\n}^#" - "1:Expr.CreateStruct#", - "", "", "", "", - // PRATT PARSER AST - "{\n" - " ?\"key\"^#2:string#:value^#4:Expr.Ident#^#3:Expr.CreateStruct.Entry#\n" - "}^#1:Expr.CreateStruct#"}, + "1:Expr.CreateStruct#"}, {"[?a, ?b]", "[\n ?a^#2:Expr.Ident#,\n ?b^#3:Expr.Ident#\n]^#1:Expr.CreateList#"}, {"[?a[?b]]", @@ -1759,13 +1730,8 @@ TEST_P(ExpressionTest, Parse) { KindAndIdAdorner kind_and_id_adorner; ExprPrinter w(kind_and_id_adorner); std::string adorned_string = w.PrintProto(result->parsed_expr().expr()); - if (options_.enable_pratt_parser && !test_info.P_PRATT.empty()) { - EXPECT_EQ(test_info.P_PRATT, adorned_string) - << result->parsed_expr().ShortDebugString(); - } else { - EXPECT_EQ(test_info.P, adorned_string) - << result->parsed_expr().ShortDebugString(); - } + EXPECT_EQ(test_info.P, adorned_string) + << result->parsed_expr().ShortDebugString(); } if (!options_.enable_pratt_parser && !test_info.L.empty()) {