From 34d8eb27c7ec8e5698cf026a6c40ff54a5916e85 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 22 Nov 2011 20:47:48 -0800 Subject: [PATCH] V0.9: Add support for a named block to only have variable definitions. It is legal for a named block to contain variable definitions and no statements. This patch fixes this for both style of blocks. It also organizes the block parsing code to be a bit more clear, adds an error case for fork/join and changes on check for size() > 0 for the more efficient ! empty(). --- parse.y | 73 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/parse.y b/parse.y index 487f1ae9b..076c5788e 100644 --- a/parse.y +++ b/parse.y @@ -354,6 +354,7 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2) %type event_control %type statement statement_or_null %type statement_list +%type statement_list_or_null %type analog_statement @@ -3638,6 +3639,11 @@ statement name. These are handled by pushing the scope name then matching the declarations. The scope is popped at the end of the block. */ + | K_begin K_end + { PBlock*tmp = new PBlock(PBlock::BL_SEQ); + FILE_NAME(tmp, @1); + $$ = tmp; + } | K_begin statement_list K_end { PBlock*tmp = new PBlock(PBlock::BL_SEQ); FILE_NAME(tmp, @1); @@ -3651,27 +3657,16 @@ statement current_block_stack.push(tmp); } block_item_decls_opt - statement_list K_end + statement_list_or_null K_end { pform_pop_scope(); assert(! current_block_stack.empty()); PBlock*tmp = current_block_stack.top(); current_block_stack.pop(); - tmp->set_statement(*$6); + if ($6) tmp->set_statement(*$6); delete[]$3; delete $6; $$ = tmp; } - | K_begin K_end - { PBlock*tmp = new PBlock(PBlock::BL_SEQ); - FILE_NAME(tmp, @1); - $$ = tmp; - } - | K_begin ':' IDENTIFIER K_end - { PBlock*tmp = new PBlock(PBlock::BL_SEQ); - FILE_NAME(tmp, @1); - delete[]$3; - $$ = tmp; - } | K_begin error K_end { yyerrok; } @@ -3680,33 +3675,36 @@ statement need to do is remember that this is a parallel block so that the code generator can do the right thing. */ + | K_fork K_join + { PBlock*tmp = new PBlock(PBlock::BL_PAR); + FILE_NAME(tmp, @1); + $$ = tmp; + } + | K_fork statement_list K_join + { PBlock*tmp = new PBlock(PBlock::BL_PAR); + FILE_NAME(tmp, @1); + tmp->set_statement(*$2); + delete $2; + $$ = tmp; + } | K_fork ':' IDENTIFIER { PBlock*tmp = pform_push_block_scope($3, PBlock::BL_PAR); FILE_NAME(tmp, @1); current_block_stack.push(tmp); } block_item_decls_opt - statement_list K_join + statement_list_or_null K_join { pform_pop_scope(); assert(! current_block_stack.empty()); PBlock*tmp = current_block_stack.top(); current_block_stack.pop(); - tmp->set_statement(*$6); + if ($6) tmp->set_statement(*$6); delete[]$3; delete $6; $$ = tmp; } - | K_fork K_join - { PBlock*tmp = new PBlock(PBlock::BL_PAR); - FILE_NAME(tmp, @1); - $$ = tmp; - } - | K_fork ':' IDENTIFIER K_join - { PBlock*tmp = new PBlock(PBlock::BL_PAR); - FILE_NAME(tmp, @1); - delete[]$3; - $$ = tmp; - } + | K_fork error K_join + { yyerrok; } | K_disable hierarchy_identifier ';' { PDisable*tmp = new PDisable(*$2); @@ -3725,13 +3723,6 @@ statement FILE_NAME(tmp, @1); $$ = tmp; } - | K_fork statement_list K_join - { PBlock*tmp = new PBlock(PBlock::BL_PAR); - FILE_NAME(tmp, @1); - tmp->set_statement(*$2); - delete $2; - $$ = tmp; - } | K_repeat '(' expression ')' statement { PRepeat*tmp = new PRepeat($3, $5); FILE_NAME(tmp, @1); @@ -3947,6 +3938,22 @@ statement } ; +statement_list_or_null + : statement_list_or_null statement + { svector*tmp = $1; + if (tmp) { + tmp = new svector(*$1, $2); + delete $1; + } else { + tmp = new svector(1); + (*tmp)[0] = $2; + } + $$ = tmp; + } + | + { $$ = 0; } + ; + statement_list : statement_list statement { svector*tmp = new svector(*$1, $2);