summaryrefslogtreecommitdiffstats
path: root/Grammar/python.gram
diff options
context:
space:
mode:
authorBrandt Bucher <brandt@python.org>2021-04-30 00:19:28 (GMT)
committerGitHub <noreply@github.com>2021-04-30 00:19:28 (GMT)
commitdbe60ee09dc5a624cfb78dff61ecf050a5b3f105 (patch)
treecb0850e50916b666879770be4fb42b473db357e8 /Grammar/python.gram
parent87655e2cf58c543914ea05ebe5a0377441da1ef2 (diff)
downloadcpython-dbe60ee09dc5a624cfb78dff61ecf050a5b3f105.zip
cpython-dbe60ee09dc5a624cfb78dff61ecf050a5b3f105.tar.gz
cpython-dbe60ee09dc5a624cfb78dff61ecf050a5b3f105.tar.bz2
bpo-43892: Validate the first term of complex literal value patterns (GH-25735)
Diffstat (limited to 'Grammar/python.gram')
-rw-r--r--Grammar/python.gram21
1 files changed, 15 insertions, 6 deletions
diff --git a/Grammar/python.gram b/Grammar/python.gram
index c8d765b..2f553c6 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -276,13 +276,22 @@ literal_expr[expr_ty]:
| 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) }
complex_number[expr_ty]:
- | real=signed_number '+' imag=imaginary_number { _PyAST_BinOp(real, Add, imag, EXTRA) }
- | real=signed_number '-' imag=imaginary_number { _PyAST_BinOp(real, Sub, imag, EXTRA) }
+ | real=signed_real_number '+' imag=imaginary_number {
+ _PyAST_BinOp(real, Add, imag, EXTRA) }
+ | real=signed_real_number '-' imag=imaginary_number {
+ _PyAST_BinOp(real, Sub, imag, EXTRA) }
signed_number[expr_ty]:
| NUMBER
| '-' number=NUMBER { _PyAST_UnaryOp(USub, number, EXTRA) }
+signed_real_number[expr_ty]:
+ | real_number
+ | '-' real=real_number { _PyAST_UnaryOp(USub, real, EXTRA) }
+
+real_number[expr_ty]:
+ | real=NUMBER { _PyPegen_ensure_real(p, real) }
+
imaginary_number[expr_ty]:
| imag=NUMBER { _PyPegen_ensure_imaginary(p, imag) }
@@ -343,7 +352,7 @@ mapping_pattern[pattern_ty]:
NULL,
EXTRA) }
items_pattern[asdl_seq*]:
- | items=','.key_value_pattern+ { items }
+ | ','.key_value_pattern+
key_value_pattern[KeyPatternPair*]:
| key=(literal_expr | attr) ':' pattern=pattern {
_PyPegen_key_pattern_pair(p, key, pattern) }
@@ -373,7 +382,7 @@ class_pattern[pattern_ty]:
positional_patterns[asdl_pattern_seq*]:
| args[asdl_pattern_seq*]=','.pattern+ { args }
keyword_patterns[asdl_seq*]:
- | keywords[asdl_seq*]=','.keyword_pattern+ { keywords }
+ | ','.keyword_pattern+
keyword_pattern[KeyPatternPair*]:
| arg=NAME '=' value=pattern { _PyPegen_key_pattern_pair(p, arg, value) }
@@ -954,12 +963,12 @@ invalid_finally_stmt:
| a='finally' ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'finally' statement on line %d", a->lineno) }
invalid_except_stmt_indent:
- | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT {
+ | a='except' expression ['as' NAME ] ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'except' statement on line %d", a->lineno) }
| a='except' ':' NEWLINE !INDENT { RAISE_SYNTAX_ERROR("expected an indented block after except statement on line %d", a->lineno) }
invalid_match_stmt:
| "match" subject_expr !':' { CHECK_VERSION(void*, 10, "Pattern matching is", RAISE_SYNTAX_ERROR("expected ':'") ) }
- | a="match" subject=subject_expr ':' NEWLINE !INDENT {
+ | a="match" subject=subject_expr ':' NEWLINE !INDENT {
RAISE_INDENTATION_ERROR("expected an indented block after 'match' statement on line %d", a->lineno) }
invalid_case_block:
| "case" patterns guard? !':' { RAISE_SYNTAX_ERROR("expected ':'") }