Skip to content

This shows how to parse a tuple #834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 59 additions & 64 deletions src/lpython/parser/parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
%type <ast> id
%type <ast> expr
%type <vec_ast> expr_list
%type <vec_ast> expr_for_list
%type <vec_ast> expr_list_opt
%type <ast> tuple_list
%type <ast> statement
Expand All @@ -199,8 +198,6 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
%type <ast> nonlocal_statement
%type <ast> assignment_statement
%type <vec_ast> target_list
%type <ast> tuple_item
%type <ast> for_tuple_item
%type <ast> ann_assignment_statement
%type <ast> delete_statement
%type <ast> return_statement
Expand All @@ -211,6 +208,7 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
%type <ast> if_statement
%type <ast> elif_statement
%type <ast> for_statement
%type <ast> for_target_list
%type <ast> except_statement
%type <vec_ast> except_list
%type <ast> try_statement
Expand All @@ -227,8 +225,8 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
%type <ast> slice_item
%type <vec_ast> slice_item_list
%type <ast> with_statement
%type <withitem> with_item
%type <vec_withitem> with_item_list
%type <vec_withitem> with_as_items
%type <vec_withitem> with_as_items_list
%type <ast> async_func_def
%type <ast> async_for_stmt
%type <ast> async_with_stmt
Expand Down Expand Up @@ -258,8 +256,8 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg)
%left "and"
%precedence "not"
%left "==" "!=" ">=" ">" "<=" "<" "is not" "is" "not in" "in"
%precedence FOR
%left KW_IF KW_ELSE
%precedence FOR
%left "|"
%left "^"
%left "&"
Expand Down Expand Up @@ -368,28 +366,22 @@ assert_statement
| KW_ASSERT expr "," expr { $$ = ASSERT_02($2, $4, @$); }
;

tuple_item
: expr_list { $$ = TUPLE_01($1, @$); }
| expr_list "," { $$ = TUPLE_03($1, @$); }
| "(" expr_list "," ")" { $$ = TUPLE_03($2, @$); }
| "(" expr_list "," expr ")" { $$ = TUPLE_01(TUPLE_($2, $4), @$); }
;

for_tuple_item
: expr_for_list { $$ = TUPLE_01($1, @$); }
| expr_for_list "," { $$ = TUPLE_03($1, @$); }
| "(" expr_for_list "," ")" { $$ = TUPLE_03($2, @$); }
| "(" expr_for_list "," expr ")" { $$ = TUPLE_01(TUPLE_($2, $4), @$); }
;

target_list
: target_list tuple_item "=" { $$ = $1; LIST_ADD($$, $2); }
| tuple_item "=" { LIST_NEW($$); LIST_ADD($$, $1); }
: target_list expr "=" { $$ = $1; LIST_ADD($$, $2); }
| expr "=" { LIST_NEW($$); LIST_ADD($$, $1); }
| target_list expr_list "," expr "=" {
$$ = $1; LIST_ADD($$, TUPLE_01(TUPLE_($2, $4), @$)); }
| expr_list "," expr "=" {
LIST_NEW($$); LIST_ADD($$, TUPLE_01(TUPLE_($1, $3), @$)); }
| target_list expr_list "," "=" { $$ = $1; LIST_ADD($$, TUPLE_03($2, @$)); }
| expr_list "," "=" { LIST_NEW($$); LIST_ADD($$, TUPLE_03($1, @$)); }
;

assignment_statement
: target_list tuple_item { $$ = ASSIGNMENT($1, $2, @$); }
| target_list tuple_item TK_TYPE_COMMENT { $$ = ASSIGNMENT2($1, $2, $3, @$); }
: target_list expr { $$ = ASSIGNMENT($1, $2, @$); }
| target_list expr_list "," expr {
$$ = ASSIGNMENT($1, TUPLE_01(TUPLE_($2, $4), @$), @$); }
| target_list expr TK_TYPE_COMMENT { $$ = ASSIGNMENT2($1, $2, $3, @$); }
;

augassign_statement
Expand Down Expand Up @@ -419,15 +411,14 @@ ann_assignment_statement
delete_statement
: KW_DEL expr_list { $$ = DELETE_01($2, @$); }
| KW_DEL expr_list "," { $$ = DELETE_01($2, @$); }
| KW_DEL "(" expr_list "," ")" {
$$ = DELETE_02(SET_EXPR_CTX_02($3, Del), @$); }
| KW_DEL "(" expr_list "," expr ")" {
$$ = DELETE_02(SET_EXPR_CTX_02(TUPLE_($3, $5), Del), @$); }
;

return_statement
: KW_RETURN { $$ = RETURN_01(@$); }
| KW_RETURN tuple_item { $$ = RETURN_02($2, @$); }
| KW_RETURN expr { $$ = RETURN_02($2, @$); }
| KW_RETURN expr_list "," expr {
$$ = RETURN_02(TUPLE_01(TUPLE_($2, $4), @$), @$); }
| KW_RETURN expr_list "," { $$ = RETURN_02(TUPLE_03($2, @$), @$); }
;

module
Expand Down Expand Up @@ -501,17 +492,23 @@ if_statement
$$ = IF_STMT_03($2, $5, $6, @$); }
;

for_target_list
: expr %prec FOR { $$ = $1; }
| expr_list "," expr %prec FOR { $$ = TUPLE_01(TUPLE_($1, $3), @$); }
;

for_statement
: KW_FOR for_tuple_item KW_IN tuple_item ":" sep statements {
: KW_FOR for_target_list KW_IN expr ":" sep statements {
$$ = FOR_01($2, $4, $7, @$); }
| KW_FOR for_tuple_item KW_IN tuple_item ":" sep statements KW_ELSE ":"
| KW_FOR for_target_list KW_IN expr "," ":" sep statements {
$$ = FOR_01($2, TUPLE_03(A2LIST(p.m_a, $4), @$), $8, @$); }
| KW_FOR for_target_list KW_IN expr ":" sep statements KW_ELSE ":"
sep statements { $$ = FOR_02($2, $4, $7, $11, @$); }
| KW_FOR for_tuple_item KW_IN tuple_item ":"
TK_TYPE_COMMENT TK_NEWLINE statements {
$$ = FOR_03($2, $4, $6, $8, @$); }
| KW_FOR for_tuple_item KW_IN tuple_item ":"
TK_TYPE_COMMENT TK_NEWLINE statements
KW_ELSE ":" sep statements { $$ = FOR_04($2, $4, $8, $12, $6, @$); }
| KW_FOR for_target_list KW_IN expr ":" TK_TYPE_COMMENT TK_NEWLINE
statements { $$ = FOR_03($2, $4, $6, $8, @$); }
| KW_FOR for_target_list KW_IN expr ":" TK_TYPE_COMMENT TK_NEWLINE
statements KW_ELSE ":" sep statements {
$$ = FOR_04($2, $4, $8, $12, $6, @$); }
;

except_statement
Expand All @@ -535,24 +532,25 @@ try_statement
| KW_TRY ":" sep statements KW_FINALLY ":" sep statements { $$ = TRY_05($4, $8, @$); }
;

with_item
: expr { $$ = WITH_ITEM_01($1, @$); }
| expr KW_AS expr { $$ = WITH_ITEM_02($1, $3, @$); }
with_as_items_list
: with_as_items_list "," expr KW_AS expr {
$$ = $1; PLIST_ADD($$, WITH_ITEM_01($3, $5, @$)); }
| expr KW_AS expr { LIST_NEW($$); PLIST_ADD($$, WITH_ITEM_01($1, $3, @$)); }
;

with_item_list
: with_item_list "," with_item { $$ = $1; PLIST_ADD($$, $3); }
| with_item { LIST_NEW($$); PLIST_ADD($$, $1); }
with_as_items
: with_as_items_list { $$ = $1; }
| "(" with_as_items_list ")" { $$ = $2; }
| "(" with_as_items_list "," ")" { $$ = $2; }
;

with_statement
: KW_WITH with_item_list ":" sep statements { $$ = WITH($2, $5, @$); }
| KW_WITH "(" with_item_list "," ")" ":" sep statements {
$$ = WITH($3, $8, @$); }
| KW_WITH with_item_list ":" TK_TYPE_COMMENT TK_NEWLINE
: KW_WITH expr_list ":" sep statements { $$ = WITH($2, $5, @$); }
| KW_WITH with_as_items ":" sep statements { $$ = WITH_02($2, $5, @$); }
| KW_WITH expr_list ":" TK_TYPE_COMMENT TK_NEWLINE
statements { $$ = WITH_01($2, $6, $4, @$); }
| KW_WITH "(" with_item_list "," ")" ":" TK_TYPE_COMMENT
TK_NEWLINE statements { $$ = WITH_01($3, $9, $7, @$); }
| KW_WITH with_as_items ":" TK_TYPE_COMMENT TK_NEWLINE
statements { $$ = WITH_03($2, $6, $4, @$); }
;

decorators_opt
Expand Down Expand Up @@ -679,28 +677,28 @@ async_func_def
;

async_for_stmt
: KW_ASYNC KW_FOR for_tuple_item KW_IN tuple_item ":" sep statements {
: KW_ASYNC KW_FOR expr KW_IN expr ":" sep statements {
$$ = ASYNC_FOR_01($3, $5, $8, @$); }
| KW_ASYNC KW_FOR for_tuple_item KW_IN tuple_item ":" sep
| KW_ASYNC KW_FOR expr KW_IN expr ":" sep
statements KW_ELSE ":" sep statements {
$$ = ASYNC_FOR_02($3, $5, $8, $12, @$); }
| KW_ASYNC KW_FOR for_tuple_item KW_IN tuple_item ":"
| KW_ASYNC KW_FOR expr KW_IN expr ":"
TK_TYPE_COMMENT TK_NEWLINE statements {
$$ = ASYNC_FOR_03($3, $5, $9, $7, @$); }
| KW_ASYNC KW_FOR for_tuple_item KW_IN tuple_item ":"
| KW_ASYNC KW_FOR expr KW_IN expr ":"
TK_TYPE_COMMENT TK_NEWLINE statements KW_ELSE ":" sep statements {
$$ = ASYNC_FOR_04($3, $5, $9, $13, $7, @$); }
;

async_with_stmt
: KW_ASYNC KW_WITH with_item_list ":" sep statements {
: KW_ASYNC KW_WITH expr_list ":" sep statements {
$$ = ASYNC_WITH($3, $6, @$); }
| KW_ASYNC KW_WITH "(" with_item_list "," ")" ":" sep statements {
$$ = ASYNC_WITH($4, $9, @$); }
| KW_ASYNC KW_WITH with_item_list ":" TK_TYPE_COMMENT
| KW_ASYNC KW_WITH with_as_items ":" sep statements {
$$ = ASYNC_WITH_02($3, $6, @$); }
| KW_ASYNC KW_WITH expr_list ":" TK_TYPE_COMMENT
TK_NEWLINE statements { $$ = ASYNC_WITH_01($3, $7, $5, @$); }
| KW_ASYNC KW_WITH "(" with_item_list "," ")" ":" TK_TYPE_COMMENT
TK_NEWLINE statements { $$ = ASYNC_WITH_01($4, $10, $8, @$); }
| KW_ASYNC KW_WITH with_as_items ":" TK_TYPE_COMMENT
TK_NEWLINE statements { $$ = ASYNC_WITH_03($3, $7, $5, @$); }
;

while_statement
Expand Down Expand Up @@ -739,11 +737,6 @@ expr_list
| expr %prec "not" { LIST_NEW($$); LIST_ADD($$, $1); }
;

expr_for_list
: expr_for_list "," expr %prec FOR { $$ = $1; LIST_ADD($$, $3); }
| expr %prec FOR { LIST_NEW($$); LIST_ADD($$, $1); }
;

dict
: expr ":" expr { $$ = DICT_EXPR($1, $3, @$); }
;
Expand Down Expand Up @@ -861,6 +854,8 @@ expr
| TK_ELLIPSIS { $$ = ELLIPSIS(@$); }
| "(" expr ")" { $$ = $2; }
| "(" ")" { $$ = TUPLE_EMPTY(@$); }
| "(" expr_list "," ")" { $$ = TUPLE_03($2, @$); }
| "(" expr_list "," expr ")" { $$ = TUPLE_01(TUPLE_($2, $4), @$); }
| function_call { $$ = $1; }
| subscription { $$ = $1; }
| "[" expr_list_opt "]" { $$ = LIST($2, @$); }
Expand Down
72 changes: 47 additions & 25 deletions src/lpython/parser/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,7 @@ static inline Vec<ast_t*> SET_EXPR_CTX_02(Vec<ast_t*> x, expr_contextType ctx) {
EXPR(SET_EXPR_CTX_01(x, Store)), EXPR(y), EXPR(val), 1)

#define DELETE_01(e, l) make_Delete_t(p.m_a, l, \
EXPRS(SET_EXPR_CTX_02(e, Del)), e.size())
#define DELETE_02(e, l) make_Delete_t(p.m_a, l, \
EXPRS(A2LIST(p.m_a, SET_EXPR_CTX_01(TUPLE_01(e, l), Del))), 1)
EXPRS(SET_EXPR_CTX_02(SET_CTX_02(e, Del), Del)), e.size())

#define EXPR_01(e, l) make_Expr_t(p.m_a, l, EXPR(e))

Expand All @@ -140,27 +138,26 @@ static inline Vec<ast_t*> SET_EXPR_CTX_02(Vec<ast_t*> x, expr_contextType ctx) {
#define NON_LOCAL(names, l) make_Nonlocal_t(p.m_a, l, \
REDUCE_ARGS(p.m_a, names), names.size())

static inline ast_t *SET_STORE_01(ast_t *x) {
static inline ast_t *SET_CTX_01(ast_t *x, expr_contextType ctx) {
if(is_a<Tuple_t>(*EXPR(x))) {
size_t n_elts = down_cast2<Tuple_t>(x)->n_elts;
for(size_t i=0; i < n_elts; i++) {
SET_EXPR_CTX_01(
(ast_t *) down_cast2<Tuple_t>(x)->m_elts[i], Store);
SET_EXPR_CTX_01((ast_t *) down_cast2<Tuple_t>(x)->m_elts[i], ctx);
}
}
return x;
}
static inline Vec<ast_t*> SET_STORE_02(Vec<ast_t*> x) {
static inline Vec<ast_t*> SET_CTX_02(Vec<ast_t*> x, expr_contextType ctx) {
for (size_t i=0; i < x.size(); i++) {
SET_STORE_01(x[i]);
SET_CTX_01(x[i], ctx);
}
return x;
}
#define ASSIGNMENT(targets, val, l) make_Assign_t(p.m_a, l, \
EXPRS(SET_EXPR_CTX_02(SET_STORE_02(targets), Store)), targets.size(), \
EXPRS(SET_EXPR_CTX_02(SET_CTX_02(targets, Store), Store)), targets.size(), \
EXPR(val), nullptr)
#define ASSIGNMENT2(targets, val, type_comment, l) make_Assign_t(p.m_a, l, \
EXPRS(SET_EXPR_CTX_02(SET_STORE_02(targets), Store)), targets.size(), \
EXPRS(SET_EXPR_CTX_02(SET_CTX_02(targets, Store), Store)), targets.size(), \
EXPR(val), extract_type_comment(p, l, type_comment))

static inline ast_t* TUPLE_02(Allocator &al, Location &l, Vec<ast_t*> elts) {
Expand All @@ -171,7 +168,7 @@ static inline ast_t* TUPLE_02(Allocator &al, Location &l, Vec<ast_t*> elts) {
}
#define TUPLE_01(elts, l) TUPLE_02(p.m_a, l, elts)
#define TUPLE_03(elts, l) make_Tuple_t(p.m_a, l, \
EXPRS(elts), elts.size(), expr_contextType::Load);
EXPRS(elts), elts.size(), expr_contextType::Load)
#define TUPLE_EMPTY(l) make_Tuple_t(p.m_a, l, \
nullptr, 0, expr_contextType::Load)

Expand Down Expand Up @@ -280,17 +277,17 @@ static inline char *extract_type_comment(LFortran::Parser &p,
}

#define FOR_01(target, iter, stmts, l) make_For_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), nullptr, 0, nullptr)
#define FOR_02(target, iter, stmts, orelse, l) make_For_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), nullptr)
#define FOR_03(target, iter, type_comment, stmts, l) make_For_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), nullptr, 0, \
extract_type_comment(p, l, type_comment))
#define FOR_04(target, iter, stmts, orelse, type_comment, l) make_For_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), \
extract_type_comment(p, l, type_comment))

Expand Down Expand Up @@ -328,12 +325,31 @@ static inline withitem_t *WITH_ITEM(Allocator &al, Location &l,
return r;
}

#define WITH_ITEM_01(expr, l) WITH_ITEM(p.m_a, l, EXPR(expr), nullptr)
#define WITH_ITEM_02(expr, vars, l) WITH_ITEM(p.m_a, l, \
static inline Vec<withitem_t> convert_exprlist_to_withitem(Allocator &al,
Location &l, Vec<ast_t*> &expr_list) {
Vec<withitem_t> v;
v.reserve(al, expr_list.size());
for (size_t i=0; i<expr_list.size(); i++) {
withitem_t r;
r.loc = l;
r.m_context_expr = EXPR(expr_list[i]);
r.m_optional_vars = nullptr;
v.push_back(al, r);
}
return v;
}

#define WITH_ITEM_01(expr, vars, l) WITH_ITEM(p.m_a, l, \
EXPR(expr), EXPR(SET_EXPR_CTX_01(vars, Store)))
#define WITH(items, body, l) make_With_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), nullptr)
convert_exprlist_to_withitem(p.m_a, l, items).p, items.size(), \
STMTS(body), body.size(), nullptr)
#define WITH_01(items, body, type_comment, l) make_With_t(p.m_a, l, \
convert_exprlist_to_withitem(p.m_a, l, items).p, items.size(), \
STMTS(body), body.size(), extract_type_comment(p, l, type_comment))
#define WITH_02(items, body, l) make_With_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), nullptr)
#define WITH_03(items, body, type_comment, l) make_With_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), \
extract_type_comment(p, l, type_comment))

Expand Down Expand Up @@ -549,24 +565,30 @@ static inline Args *FUNC_ARGS(Allocator &al, Location &l,
extract_type_comment(p, l, type_comment))

#define ASYNC_FOR_01(target, iter, stmts, l) make_AsyncFor_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), nullptr, 0, nullptr)
#define ASYNC_FOR_02(target, iter, stmts, orelse, l) make_AsyncFor_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), nullptr)
#define ASYNC_FOR_03(target, iter, stmts, type_comment, l) make_AsyncFor_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), nullptr, 0, \
extract_type_comment(p, l, type_comment))
#define ASYNC_FOR_04(target, iter, stmts, orelse, type_comment, l) make_AsyncFor_t(p.m_a, l, \
EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \
EXPR(SET_EXPR_CTX_01(SET_CTX_01(target, Store), Store)), EXPR(iter), \
STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), \
extract_type_comment(p, l, type_comment))

#define ASYNC_WITH(items, body, l) make_AsyncWith_t(p.m_a, l, \
convert_exprlist_to_withitem(p.m_a, l, items).p, items.size(), \
STMTS(body), body.size(), nullptr)
#define ASYNC_WITH_02(items, body, l) make_AsyncWith_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), nullptr)
#define ASYNC_WITH_01(items, body, type_comment, l) make_AsyncWith_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), \
convert_exprlist_to_withitem(p.m_a, l, items).p, items.size(), \
STMTS(body), body.size(), extract_type_comment(p, l, type_comment))
#define ASYNC_WITH_03(items, body, type_comment, l) make_AsyncWith_t(p.m_a, l, \
items.p, items.size(), STMTS(body), body.size(), \
extract_type_comment(p, l, type_comment))

#define WHILE_01(e, stmts, l) make_While_t(p.m_a, l, \
Expand Down Expand Up @@ -752,12 +774,12 @@ static inline ast_t* ID_TUPLE_02(Allocator &al, Location &l, Vec<ast_t*> elts) {
if(is_a<expr_t>(*elts[0]) && elts.size() == 1) {
return (ast_t*) SET_EXPR_CTX_01(elts[0], Store);
}
return make_Tuple_t(al, l, EXPRS(SET_EXPR_CTX_02(SET_STORE_02(elts), Store)),
return make_Tuple_t(al, l, EXPRS(SET_EXPR_CTX_02(SET_CTX_02(elts, Store), Store)),
elts.size(), expr_contextType::Store);
}
#define ID_TUPLE_01(elts, l) ID_TUPLE_02(p.m_a, l, elts)
#define ID_TUPLE_03(elts, l) make_Tuple_t(p.m_a, l, \
EXPRS(SET_EXPR_CTX_02(SET_STORE_02(elts), Store)), elts.size(), \
EXPRS(SET_EXPR_CTX_02(SET_CTX_02(elts, Store), Store)), elts.size(), \
expr_contextType::Store);

#define LIST_COMP_1(expr, generators, l) make_ListComp_t(p.m_a, l, \
Expand Down
Loading