underscores as placeholders
This commit is contained in:
parent
ab2849da6f
commit
1c9882a2cb
1 changed files with 52 additions and 16 deletions
|
|
@ -1,4 +1,4 @@
|
|||
From d947b1d3160d8a6990f9b7bed476184271fedd9a Mon Sep 17 00:00:00 2001
|
||||
From 79b30daff39dc53c4d822250946e1667cae1798e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= <jana@donsz.nl>
|
||||
Date: Mon, 5 Jan 2026 16:14:52 +0100
|
||||
Subject: [PATCH] add to parser
|
||||
|
|
@ -6,9 +6,9 @@ Subject: [PATCH] add to parser
|
|||
---
|
||||
Grammar/Tokens | 1 +
|
||||
Grammar/python.gram | 77 ++++++++++++++++++++++++++++++-----------
|
||||
Parser/action_helpers.c | 26 ++++++++++++++
|
||||
Parser/action_helpers.c | 62 +++++++++++++++++++++++++++++++++
|
||||
Parser/pegen.h | 1 +
|
||||
4 files changed, 84 insertions(+), 21 deletions(-)
|
||||
4 files changed, 120 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/Grammar/Tokens b/Grammar/Tokens
|
||||
index 0547e6ed08f..fd0ce412f6c 100644
|
||||
|
|
@ -23,7 +23,7 @@ index 0547e6ed08f..fd0ce412f6c 100644
|
|||
OP
|
||||
TYPE_IGNORE
|
||||
diff --git a/Grammar/python.gram b/Grammar/python.gram
|
||||
index 110136af81b..7afaa1c140e 100644
|
||||
index 110136af81b..30f7950d1a9 100644
|
||||
--- a/Grammar/python.gram
|
||||
+++ b/Grammar/python.gram
|
||||
@@ -726,13 +726,13 @@ star_expressions[expr_ty]:
|
||||
|
|
@ -94,9 +94,9 @@ index 110136af81b..7afaa1c140e 100644
|
|||
+ | lhs=pipe '|>' rhs=primary_nocall b=genexp {
|
||||
+ _PyAST_Call(rhs,
|
||||
+ _PyPegen_desugar_pipe(
|
||||
+ p,
|
||||
+ CHECK(asdl_expr_seq*, (asdl_expr_seq*)_PyPegen_singleton_seq(p, b)),
|
||||
+ lhs,
|
||||
+ p->arena
|
||||
+ lhs
|
||||
+ )
|
||||
+ , NULL,
|
||||
+ EXTRA
|
||||
|
|
@ -106,9 +106,9 @@ index 110136af81b..7afaa1c140e 100644
|
|||
+ _PyAST_Call(
|
||||
+ rhs,
|
||||
+ _PyPegen_desugar_pipe(
|
||||
+ p,
|
||||
+ (arg) ? ((expr_ty) arg)->v.Call.args : NULL,
|
||||
+ lhs,
|
||||
+ p->arena
|
||||
+ lhs
|
||||
+ ),
|
||||
+ (arg) ? ((expr_ty) arg)->v.Call.keywords : NULL,
|
||||
+ EXTRA
|
||||
|
|
@ -195,16 +195,20 @@ index 110136af81b..7afaa1c140e 100644
|
|||
invalid_starred_expression_unpacking:
|
||||
| a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") }
|
||||
diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c
|
||||
index 50856686335..44d617f48cc 100644
|
||||
index 50856686335..3241c007aa8 100644
|
||||
--- a/Parser/action_helpers.c
|
||||
+++ b/Parser/action_helpers.c
|
||||
@@ -1152,6 +1152,32 @@ _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
|
||||
@@ -1152,6 +1152,68 @@ _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) {
|
||||
return PyPegen_last_item(comprehension->ifs, expr_ty);
|
||||
}
|
||||
|
||||
+asdl_expr_seq * _PyPegen_desugar_pipe(asdl_expr_seq* args, expr_ty piped_lhs, PyArena* arena) {
|
||||
+asdl_expr_seq * _PyPegen_desugar_pipe(Parser * p, asdl_expr_seq* args, expr_ty piped_lhs) {
|
||||
+ // loop index
|
||||
+ Py_ssize_t i = 0;
|
||||
+
|
||||
+ // if the list was somehow null, replace it with a list only containing the piped argument
|
||||
+ if (args == NULL) {
|
||||
+ asdl_expr_seq *new_args = _Py_asdl_expr_seq_new(1, arena);
|
||||
+ asdl_expr_seq *new_args = _Py_asdl_expr_seq_new(1, p->arena);
|
||||
+ if (new_args == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
|
@ -213,14 +217,46 @@ index 50856686335..44d617f48cc 100644
|
|||
+ return new_args;
|
||||
+ }
|
||||
+
|
||||
+ // calculate the initial length
|
||||
+ Py_ssize_t orig_args_len = asdl_seq_LEN(args);
|
||||
+ asdl_expr_seq *new_args = _Py_asdl_expr_seq_new(orig_args_len + 1, arena);
|
||||
+
|
||||
+ // look for a `_` to replace
|
||||
+ Py_ssize_t underscore_index = -1;
|
||||
+ for (i = 0; i < orig_args_len; i++) {
|
||||
+ expr_ty arg = asdl_seq_GET(args, i);
|
||||
+
|
||||
+ // if we see an underscore, count it
|
||||
+ if (
|
||||
+ arg->kind == Name_kind
|
||||
+ && PyUnicode_CompareWithASCIIString(arg->v.Name.id, "_") == 0
|
||||
+ ) {
|
||||
+ // maybe this is the 2nd underscore, raise a syntax error
|
||||
+ if (underscore_index != -1) {
|
||||
+ return RAISE_SYNTAX_ERROR_KNOWN_RANGE(arg, arg, "only one `_` is allowed when piping");
|
||||
+ }
|
||||
+
|
||||
+ underscore_index = i;
|
||||
+ }
|
||||
+
|
||||
+ assert(current_elem->kind == Constant_kind);
|
||||
+ }
|
||||
+
|
||||
+ // overwrite the `_` element if found
|
||||
+ if (underscore_index != -1) {
|
||||
+ asdl_seq_SET(args, underscore_index, piped_lhs);
|
||||
+ return args;
|
||||
+ }
|
||||
+
|
||||
+ // otherwise, allocate a new expr seq of one item longer than the original
|
||||
+ asdl_expr_seq *new_args = _Py_asdl_expr_seq_new(orig_args_len + 1, p->arena);
|
||||
+ if (new_args == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ // stick the piped element at the end (so at orig_args_len)
|
||||
+ // which is usually 1 past the end but now we allocated one more element
|
||||
+ asdl_seq_SET(new_args, orig_args_len, piped_lhs);
|
||||
+ Py_ssize_t i = 0;
|
||||
+ // and copy the rest of the elements.
|
||||
+ for (i = 0; i < orig_args_len; i++) {
|
||||
+ asdl_seq_SET(new_args, i, asdl_seq_GET(args, i));
|
||||
+ }
|
||||
|
|
@ -232,14 +268,14 @@ index 50856686335..44d617f48cc 100644
|
|||
int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena) {
|
||||
diff --git a/Parser/pegen.h b/Parser/pegen.h
|
||||
index be5333eb268..8e109999b54 100644
|
||||
index be5333eb268..d9557494e6c 100644
|
||||
--- a/Parser/pegen.h
|
||||
+++ b/Parser/pegen.h
|
||||
@@ -344,6 +344,7 @@ stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_expr_seq *, stmt_ty);
|
||||
KeywordOrStarred *_PyPegen_keyword_or_starred(Parser *, void *, int);
|
||||
asdl_expr_seq *_PyPegen_seq_extract_starred_exprs(Parser *, asdl_seq *);
|
||||
asdl_keyword_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *);
|
||||
+asdl_expr_seq * _PyPegen_desugar_pipe(asdl_expr_seq* args, expr_ty piped_lhs, PyArena* arena);
|
||||
+asdl_expr_seq * _PyPegen_desugar_pipe(Parser*, asdl_expr_seq*, expr_ty);
|
||||
expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_expr_seq *, asdl_seq *,
|
||||
int lineno, int col_offset, int end_lineno,
|
||||
int end_col_offset, PyArena *arena);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue