summaryrefslogtreecommitdiff
path: root/Parser/pegen
diff options
context:
space:
mode:
Diffstat (limited to 'Parser/pegen')
-rw-r--r--Parser/pegen/parse.c119
-rw-r--r--Parser/pegen/pegen.c76
-rw-r--r--Parser/pegen/pegen.h4
3 files changed, 124 insertions, 75 deletions
diff --git a/Parser/pegen/parse.c b/Parser/pegen/parse.c
index b1b248187e..f4c5692212 100644
--- a/Parser/pegen/parse.c
+++ b/Parser/pegen/parse.c
@@ -199,8 +199,8 @@ static KeywordToken *reserved_keywords[] = {
#define star_targets_seq_type 1128
#define star_target_type 1129
#define star_atom_type 1130
-#define inside_paren_ann_assign_target_type 1131
-#define ann_assign_subscript_attribute_target_type 1132
+#define single_target_type 1131
+#define single_subscript_attribute_target_type 1132
#define del_targets_type 1133
#define del_target_type 1134
#define del_t_atom_type 1135
@@ -501,8 +501,8 @@ static expr_ty star_targets_rule(Parser *p);
static asdl_seq* star_targets_seq_rule(Parser *p);
static expr_ty star_target_rule(Parser *p);
static expr_ty star_atom_rule(Parser *p);
-static expr_ty inside_paren_ann_assign_target_rule(Parser *p);
-static expr_ty ann_assign_subscript_attribute_target_rule(Parser *p);
+static expr_ty single_target_rule(Parser *p);
+static expr_ty single_subscript_attribute_target_rule(Parser *p);
static asdl_seq* del_targets_rule(Parser *p);
static expr_ty del_target_rule(Parser *p);
static expr_ty del_t_atom_rule(Parser *p);
@@ -1590,9 +1590,9 @@ compound_stmt_rule(Parser *p)
// assignment:
// | NAME ':' expression ['=' annotated_rhs]
-// | ('(' inside_paren_ann_assign_target ')' | ann_assign_subscript_attribute_target) ':' expression ['=' annotated_rhs]
+// | ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]
// | ((star_targets '='))+ (yield_expr | star_expressions) TYPE_COMMENT?
-// | target augassign (yield_expr | star_expressions)
+// | single_target augassign (yield_expr | star_expressions)
// | invalid_assignment
static stmt_ty
assignment_rule(Parser *p)
@@ -1642,13 +1642,13 @@ assignment_rule(Parser *p)
}
p->mark = _mark;
}
- { // ('(' inside_paren_ann_assign_target ')' | ann_assign_subscript_attribute_target) ':' expression ['=' annotated_rhs]
+ { // ('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]
Token * _literal;
void *a;
expr_ty b;
void *c;
if (
- (a = _tmp_20_rule(p)) // '(' inside_paren_ann_assign_target ')' | ann_assign_subscript_attribute_target
+ (a = _tmp_20_rule(p)) // '(' single_target ')' | single_subscript_attribute_target
&&
(_literal = _PyPegen_expect_token(p, 11)) // token=':'
&&
@@ -1703,12 +1703,12 @@ assignment_rule(Parser *p)
}
p->mark = _mark;
}
- { // target augassign (yield_expr | star_expressions)
+ { // single_target augassign (yield_expr | star_expressions)
expr_ty a;
AugOperator* b;
void *c;
if (
- (a = target_rule(p)) // target
+ (a = single_target_rule(p)) // single_target
&&
(b = augassign_rule(p)) // augassign
&&
@@ -3350,7 +3350,7 @@ try_stmt_rule(Parser *p)
return _res;
}
-// except_block: 'except' expression ['as' target] ':' block | 'except' ':' block
+// except_block: 'except' expression ['as' NAME] ':' block | 'except' ':' block
static excepthandler_ty
except_block_rule(Parser *p)
{
@@ -3367,7 +3367,7 @@ except_block_rule(Parser *p)
UNUSED(_start_lineno); // Only used by EXTRA macro
int _start_col_offset = p->tokens[_mark]->col_offset;
UNUSED(_start_col_offset); // Only used by EXTRA macro
- { // 'except' expression ['as' target] ':' block
+ { // 'except' expression ['as' NAME] ':' block
Token * _keyword;
Token * _literal;
asdl_seq* b;
@@ -3378,7 +3378,7 @@ except_block_rule(Parser *p)
&&
(e = expression_rule(p)) // expression
&&
- (t = _tmp_48_rule(p), 1) // ['as' target]
+ (t = _tmp_48_rule(p), 1) // ['as' NAME]
&&
(_literal = _PyPegen_expect_token(p, 11)) // token=':'
&&
@@ -9605,25 +9605,22 @@ star_atom_rule(Parser *p)
return _res;
}
-// inside_paren_ann_assign_target:
-// | ann_assign_subscript_attribute_target
-// | NAME
-// | '(' inside_paren_ann_assign_target ')'
+// single_target: single_subscript_attribute_target | NAME | '(' single_target ')'
static expr_ty
-inside_paren_ann_assign_target_rule(Parser *p)
+single_target_rule(Parser *p)
{
if (p->error_indicator) {
return NULL;
}
expr_ty _res = NULL;
int _mark = p->mark;
- { // ann_assign_subscript_attribute_target
- expr_ty ann_assign_subscript_attribute_target_var;
+ { // single_subscript_attribute_target
+ expr_ty single_subscript_attribute_target_var;
if (
- (ann_assign_subscript_attribute_target_var = ann_assign_subscript_attribute_target_rule(p)) // ann_assign_subscript_attribute_target
+ (single_subscript_attribute_target_var = single_subscript_attribute_target_rule(p)) // single_subscript_attribute_target
)
{
- _res = ann_assign_subscript_attribute_target_var;
+ _res = single_subscript_attribute_target_var;
goto done;
}
p->mark = _mark;
@@ -9643,14 +9640,14 @@ inside_paren_ann_assign_target_rule(Parser *p)
}
p->mark = _mark;
}
- { // '(' inside_paren_ann_assign_target ')'
+ { // '(' single_target ')'
Token * _literal;
Token * _literal_1;
expr_ty a;
if (
(_literal = _PyPegen_expect_token(p, 7)) // token='('
&&
- (a = inside_paren_ann_assign_target_rule(p)) // inside_paren_ann_assign_target
+ (a = single_target_rule(p)) // single_target
&&
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
)
@@ -9669,11 +9666,11 @@ inside_paren_ann_assign_target_rule(Parser *p)
return _res;
}
-// ann_assign_subscript_attribute_target:
+// single_subscript_attribute_target:
// | t_primary '.' NAME !t_lookahead
// | t_primary '[' slices ']' !t_lookahead
static expr_ty
-ann_assign_subscript_attribute_target_rule(Parser *p)
+single_subscript_attribute_target_rule(Parser *p)
{
if (p->error_indicator) {
return NULL;
@@ -10750,7 +10747,8 @@ invalid_named_expression_rule(Parser *p)
// | tuple ':'
// | star_named_expression ',' star_named_expressions* ':'
// | expression ':' expression ['=' annotated_rhs]
-// | expression ('=' | augassign) (yield_expr | star_expressions)
+// | star_expressions '=' (yield_expr | star_expressions)
+// | star_expressions augassign (yield_expr | star_expressions)
static void *
invalid_assignment_rule(Parser *p)
{
@@ -10844,19 +10842,40 @@ invalid_assignment_rule(Parser *p)
}
p->mark = _mark;
}
- { // expression ('=' | augassign) (yield_expr | star_expressions)
+ { // star_expressions '=' (yield_expr | star_expressions)
+ Token * _literal;
void *_tmp_128_var;
+ expr_ty a;
+ if (
+ (a = star_expressions_rule(p)) // star_expressions
+ &&
+ (_literal = _PyPegen_expect_token(p, 22)) // token='='
+ &&
+ (_tmp_128_var = _tmp_128_rule(p)) // yield_expr | star_expressions
+ )
+ {
+ _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( _PyPegen_get_invalid_target ( a ) , "cannot assign to %s" , _PyPegen_get_expr_name ( _PyPegen_get_invalid_target ( a ) ) );
+ if (_res == NULL && PyErr_Occurred()) {
+ p->error_indicator = 1;
+ return NULL;
+ }
+ goto done;
+ }
+ p->mark = _mark;
+ }
+ { // star_expressions augassign (yield_expr | star_expressions)
void *_tmp_129_var;
expr_ty a;
+ AugOperator* augassign_var;
if (
- (a = expression_rule(p)) // expression
+ (a = star_expressions_rule(p)) // star_expressions
&&
- (_tmp_128_var = _tmp_128_rule(p)) // '=' | augassign
+ (augassign_var = augassign_rule(p)) // augassign
&&
(_tmp_129_var = _tmp_129_rule(p)) // yield_expr | star_expressions
)
{
- _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "cannot assign to %s" , _PyPegen_get_expr_name ( a ) );
+ _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "'%s' is an illegal expression for augmented assignment" , _PyPegen_get_expr_name ( a ) );
if (_res == NULL && PyErr_Occurred()) {
p->error_indicator = 1;
return NULL;
@@ -11907,7 +11926,7 @@ _tmp_19_rule(Parser *p)
return _res;
}
-// _tmp_20: '(' inside_paren_ann_assign_target ')' | ann_assign_subscript_attribute_target
+// _tmp_20: '(' single_target ')' | single_subscript_attribute_target
static void *
_tmp_20_rule(Parser *p)
{
@@ -11916,14 +11935,14 @@ _tmp_20_rule(Parser *p)
}
void * _res = NULL;
int _mark = p->mark;
- { // '(' inside_paren_ann_assign_target ')'
+ { // '(' single_target ')'
Token * _literal;
Token * _literal_1;
expr_ty b;
if (
(_literal = _PyPegen_expect_token(p, 7)) // token='('
&&
- (b = inside_paren_ann_assign_target_rule(p)) // inside_paren_ann_assign_target
+ (b = single_target_rule(p)) // single_target
&&
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
)
@@ -11937,13 +11956,13 @@ _tmp_20_rule(Parser *p)
}
p->mark = _mark;
}
- { // ann_assign_subscript_attribute_target
- expr_ty ann_assign_subscript_attribute_target_var;
+ { // single_subscript_attribute_target
+ expr_ty single_subscript_attribute_target_var;
if (
- (ann_assign_subscript_attribute_target_var = ann_assign_subscript_attribute_target_rule(p)) // ann_assign_subscript_attribute_target
+ (single_subscript_attribute_target_var = single_subscript_attribute_target_rule(p)) // single_subscript_attribute_target
)
{
- _res = ann_assign_subscript_attribute_target_var;
+ _res = single_subscript_attribute_target_var;
goto done;
}
p->mark = _mark;
@@ -13073,7 +13092,7 @@ _loop1_47_rule(Parser *p)
return _seq;
}
-// _tmp_48: 'as' target
+// _tmp_48: 'as' NAME
static void *
_tmp_48_rule(Parser *p)
{
@@ -13082,13 +13101,13 @@ _tmp_48_rule(Parser *p)
}
void * _res = NULL;
int _mark = p->mark;
- { // 'as' target
+ { // 'as' NAME
Token * _keyword;
expr_ty z;
if (
(_keyword = _PyPegen_expect_token(p, 531)) // token='as'
&&
- (z = target_rule(p)) // target
+ (z = _PyPegen_name_token(p)) // NAME
)
{
_res = z;
@@ -16678,7 +16697,7 @@ _tmp_127_rule(Parser *p)
return _res;
}
-// _tmp_128: '=' | augassign
+// _tmp_128: yield_expr | star_expressions
static void *
_tmp_128_rule(Parser *p)
{
@@ -16687,24 +16706,24 @@ _tmp_128_rule(Parser *p)
}
void * _res = NULL;
int _mark = p->mark;
- { // '='
- Token * _literal;
+ { // yield_expr
+ expr_ty yield_expr_var;
if (
- (_literal = _PyPegen_expect_token(p, 22)) // token='='
+ (yield_expr_var = yield_expr_rule(p)) // yield_expr
)
{
- _res = _literal;
+ _res = yield_expr_var;
goto done;
}
p->mark = _mark;
}
- { // augassign
- AugOperator* augassign_var;
+ { // star_expressions
+ expr_ty star_expressions_var;
if (
- (augassign_var = augassign_rule(p)) // augassign
+ (star_expressions_var = star_expressions_rule(p)) // star_expressions
)
{
- _res = augassign_var;
+ _res = star_expressions_var;
goto done;
}
p->mark = _mark;
diff --git a/Parser/pegen/pegen.c b/Parser/pegen/pegen.c
index 083088bd96..7f3e4561de 100644
--- a/Parser/pegen/pegen.c
+++ b/Parser/pegen/pegen.c
@@ -300,30 +300,6 @@ error:
Py_XDECREF(tuple);
}
-static inline PyObject *
-get_error_line(char *buffer, int is_file)
-{
- const char *newline;
- if (is_file) {
- newline = strrchr(buffer, '\n');
- } else {
- newline = strchr(buffer, '\n');
- }
-
- if (is_file) {
- while (newline > buffer && newline[-1] == '\n') {
- --newline;
- }
- }
-
- if (newline) {
- return PyUnicode_DecodeUTF8(buffer, newline - buffer, "replace");
- }
- else {
- return PyUnicode_DecodeUTF8(buffer, strlen(buffer), "replace");
- }
-}
-
static int
tokenizer_error(Parser *p)
{
@@ -422,7 +398,11 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype,
}
if (!error_line) {
- error_line = get_error_line(p->tok->buf, p->start_rule == Py_file_input);
+ Py_ssize_t size = p->tok->inp - p->tok->buf;
+ if (size && p->tok->buf[size-1] == '\n') {
+ size--;
+ }
+ error_line = PyUnicode_DecodeUTF8(p->tok->buf, size, "replace");
if (!error_line) {
goto error;
}
@@ -2074,3 +2054,49 @@ _PyPegen_make_module(Parser *p, asdl_seq *a) {
}
return Module(a, type_ignores, p->arena);
}
+
+// Error reporting helpers
+
+expr_ty
+_PyPegen_get_invalid_target(expr_ty e)
+{
+ if (e == NULL) {
+ return NULL;
+ }
+
+#define VISIT_CONTAINER(CONTAINER, TYPE) do { \
+ Py_ssize_t len = asdl_seq_LEN(CONTAINER->v.TYPE.elts);\
+ for (Py_ssize_t i = 0; i < len; i++) {\
+ expr_ty other = asdl_seq_GET(CONTAINER->v.TYPE.elts, i);\
+ expr_ty child = _PyPegen_get_invalid_target(other);\
+ if (child != NULL) {\
+ return child;\
+ }\
+ }\
+ } while (0)
+
+ // We only need to visit List and Tuple nodes recursively as those
+ // are the only ones that can contain valid names in targets when
+ // they are parsed as expressions. Any other kind of expression
+ // that is a container (like Sets or Dicts) is directly invalid and
+ // we don't need to visit it recursively.
+
+ switch (e->kind) {
+ case List_kind: {
+ VISIT_CONTAINER(e, List);
+ return NULL;
+ }
+ case Tuple_kind: {
+ VISIT_CONTAINER(e, Tuple);
+ return NULL;
+ }
+ case Starred_kind:
+ return _PyPegen_get_invalid_target(e->v.Starred.value);
+ case Name_kind:
+ case Subscript_kind:
+ case Attribute_kind:
+ return NULL;
+ default:
+ return e;
+ }
+} \ No newline at end of file
diff --git a/Parser/pegen/pegen.h b/Parser/pegen/pegen.h
index e5b1b757bd..b9d4c048bb 100644
--- a/Parser/pegen/pegen.h
+++ b/Parser/pegen/pegen.h
@@ -260,6 +260,10 @@ void *_PyPegen_arguments_parsing_error(Parser *, expr_ty);
int _PyPegen_check_barry_as_flufl(Parser *);
mod_ty _PyPegen_make_module(Parser *, asdl_seq *);
+// Error reporting helpers
+
+expr_ty _PyPegen_get_invalid_target(expr_ty e);
+
void *_PyPegen_parse(Parser *);
#endif