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:
parent
cc5efa45ba
commit
9fbeb78d5f
74
parse.y
74
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<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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue