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().
This commit is contained in:
Cary R 2011-11-22 20:33:19 -08:00
parent cc5efa45ba
commit 9fbeb78d5f
1 changed files with 40 additions and 34 deletions

74
parse.y
View File

@ -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<Statement*>*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<Statement*>*s)
%type <event_statement> event_control
%type <statement> statement statement_or_null compressed_statement
%type <statement_list> statement_list statement_or_null_list
%type <statement_list> statement_list_or_null
%type <statement> 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<Statement*>*tmp = $1;
if (tmp) {
tmp->push_back($2);
} else {
tmp = new vector<Statement*>(1);
tmp->at(0) = $2;
}
$$ = tmp;
}
|
{ $$ = 0; }
;
statement_list
: statement_list statement
{ vector<Statement*>*tmp = $1;