From 9fbeb78d5fc0ea04300caafa6b650c39f4389f33 Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 22 Nov 2011 20:33:19 -0800 Subject: [PATCH] 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 | 74 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/parse.y b/parse.y index 22157b25a..d78f8ee6c 100644 --- a/parse.y +++ b/parse.y @@ -255,7 +255,7 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok) static void current_task_set_statement(vector*s) { - assert(s && s->size() > 0); + assert(s && !s->empty()); if (s->size() == 1) { current_task->set_statement((*s)[0]); return; @@ -505,6 +505,7 @@ static void current_task_set_statement(vector*s) %type event_control %type statement statement_or_null compressed_statement %type statement_list statement_or_null_list +%type statement_list_or_null %type analog_statement @@ -4285,6 +4286,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); @@ -4298,27 +4304,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; } @@ -4327,33 +4322,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); @@ -4372,13 +4370,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); @@ -4677,6 +4668,21 @@ compressed_statement } ; +statement_list_or_null + : statement_list_or_null statement + { vector*tmp = $1; + if (tmp) { + tmp->push_back($2); + } else { + tmp = new vector(1); + tmp->at(0) = $2; + } + $$ = tmp; + } + | + { $$ = 0; } + ; + statement_list : statement_list statement { vector*tmp = $1;