From c0ebb0614f4f5c82c769cba6111c6b65abde92e9 Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Fri, 28 Aug 2026 12:25:58 -0700 Subject: [PATCH] [C++] Disallow trailing commas in function call argument lists in Pratt parser According to the CEL grammar specification, trailing commas are only permitted in collection literals (lists, maps, structs), not in function call argument lists (`exprList`). Disallows trailing commas in `PrattParserWorker::ParseArguments` and adds test cases to verify syntax error reporting. PiperOrigin-RevId: 972728668 --- parser/internal/pratt_parser_test.cc | 6 ++++++ parser/internal/pratt_parser_worker.h | 1 + parser/parser_test.cc | 11 +++++++++++ 3 files changed, 18 insertions(+) diff --git a/parser/internal/pratt_parser_test.cc b/parser/internal/pratt_parser_test.cc index 116ae607b..6c85dd1d7 100644 --- a/parser/internal/pratt_parser_test.cc +++ b/parser/internal/pratt_parser_test.cc @@ -1283,6 +1283,12 @@ std::vector GetErrorTestCases() { " | f(1, 2\n" " | ......^", }, + ErrorTestCase{ + .source = "foo(a,b,)", + .expected_error = "ERROR: :1:9: unexpected token\n" + " | foo(a,b,)\n" + " | ........^", + }, ErrorTestCase{ .source = "999999999999999999999999999999999999999", .expected_error = "ERROR: :1:1: invalid int literal\n" diff --git a/parser/internal/pratt_parser_worker.h b/parser/internal/pratt_parser_worker.h index dc17f27d6..f4886aa90 100644 --- a/parser/internal/pratt_parser_worker.h +++ b/parser/internal/pratt_parser_worker.h @@ -852,6 +852,7 @@ std::vector PrattParserWorker::ParseArguments( if (peek_token_.type == TokenType::kComma) { NextToken(); if (peek_token_.type == close_token) { + ReportError(peek_token_, "unexpected token"); break; } continue; diff --git a/parser/parser_test.cc b/parser/parser_test.cc index d4a3294c3..e47557e6b 100644 --- a/parser/parser_test.cc +++ b/parser/parser_test.cc @@ -501,6 +501,17 @@ std::vector test_cases = { "ERROR: :1:3: expected struct field name\n" " | t{>C}\n" " | ..^"}, + {"foo(a,b,)", "", + "ERROR: :1:9: Syntax error: mismatched input ')' expecting " + "{'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, " + "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" + " | ........^"}, // Macro tests {"has(m.f)", "m^#2:Expr.Ident#.f~test-only~^#4:Expr.Select#", "",