Merge pull request #604 from larsclausen/parser-end-label-unnamed
Let the parser recover from end label on unnamed block
This commit is contained in:
commit
bb36a16704
|
|
@ -1,15 +1,15 @@
|
||||||
./ivltests/sv_end_label_fail.v:4: error: End label doesn't match begin name
|
./ivltests/sv_end_label_fail.v:4: error: block end label `b_label_f` doesn't match block name `b_label`.
|
||||||
./ivltests/sv_end_label_fail.v:7: error: End label doesn't match fork name
|
./ivltests/sv_end_label_fail.v:7: error: fork end label `fj_label_f` doesn't match fork name `fj_label`.
|
||||||
./ivltests/sv_end_label_fail.v:10: error: End label doesn't match fork name
|
./ivltests/sv_end_label_fail.v:10: error: fork end label `fja_label_f` doesn't match fork name `fja_label`.
|
||||||
./ivltests/sv_end_label_fail.v:13: error: End label doesn't match fork name
|
./ivltests/sv_end_label_fail.v:13: error: fork end label `fjn_label_f` doesn't match fork name `fjn_label`.
|
||||||
./ivltests/sv_end_label_fail.v:16: error: End label doesn't match task name
|
./ivltests/sv_end_label_fail.v:16: error: task end label `t_label_f` doesn't match task name `t_label`.
|
||||||
./ivltests/sv_end_label_fail.v:19: error: End label doesn't match task name
|
./ivltests/sv_end_label_fail.v:19: error: task end label `twa_label_f` doesn't match task name `twa_label`.
|
||||||
./ivltests/sv_end_label_fail.v:23: error: End label doesn't match function name
|
./ivltests/sv_end_label_fail.v:23: error: function end label `fn_label_f` doesn't match function name `fn_label`.
|
||||||
./ivltests/sv_end_label_fail.v:26: error: End label doesn't match function name
|
./ivltests/sv_end_label_fail.v:26: error: function end label `fa_label_f` doesn't match function name `fa_label`.
|
||||||
./ivltests/sv_end_label_fail.v:28: error: End label doesn't match module name.
|
./ivltests/sv_end_label_fail.v:28: error: module end label `top_f` doesn't match module name `top`.
|
||||||
./ivltests/sv_end_label_fail.v:38: error: End label doesn't match begin name
|
./ivltests/sv_end_label_fail.v:38: error: block end label `g_label_f` doesn't match block name `g_label`.
|
||||||
./ivltests/sv_end_label_fail.v:40: error: End label doesn't match module name.
|
./ivltests/sv_end_label_fail.v:40: error: module end label `extra_f` doesn't match module name `extra`.
|
||||||
./ivltests/sv_end_label_fail.v:43: error: End label doesn't match package name
|
./ivltests/sv_end_label_fail.v:43: error: package end label `pkg_f` doesn't match package name `pkg`.
|
||||||
./ivltests/sv_end_label_fail.v:47: error: Class end label doesn't match class name.
|
./ivltests/sv_end_label_fail.v:47: error: class end label `foo_f` doesn't match class name `foo`.
|
||||||
./ivltests/sv_end_label_fail.v:48: error: End label doesn't match program name.
|
./ivltests/sv_end_label_fail.v:48: error: program end label `pgm_f` doesn't match program name `pgm`.
|
||||||
./ivltests/sv_end_label_fail.v:64: error: End label doesn't match primitive name
|
./ivltests/sv_end_label_fail.v:64: error: primitive end label `pinv_f` doesn't match primitive name `pinv`.
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
./ivltests/sv_end_labels_bad.v:14: error: End label doesn't match begin name
|
./ivltests/sv_end_labels_bad.v:14: error: block end label `dummy_label_bad` doesn't match block name `dummy_label`.
|
||||||
./ivltests/sv_end_labels_bad.v:16: error: End label doesn't match module name.
|
./ivltests/sv_end_labels_bad.v:16: error: module end label `test_bad` doesn't match module name `test`.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
./ivltests/sv_end_labels_unnamed.v:7: error: unnamed block must not have end label.
|
||||||
|
./ivltests/sv_end_labels_unnamed.v:11: error: unnamed block must not have end label.
|
||||||
|
./ivltests/sv_end_labels_unnamed.v:14: error: unnamed fork must not have end label.
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Check that end labels on unnamed blocks generate an error
|
||||||
|
|
||||||
|
module test;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (1) begin
|
||||||
|
end : label
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
end : label
|
||||||
|
|
||||||
|
initial fork
|
||||||
|
join : label
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -452,6 +452,7 @@ sv_end_label normal,-g2005-sv ivltests
|
||||||
sv_end_label_fail CE,-g2009 ivltests gold=sv_end_label_fail.gold
|
sv_end_label_fail CE,-g2009 ivltests gold=sv_end_label_fail.gold
|
||||||
sv_end_labels normal,-g2009 ivltests
|
sv_end_labels normal,-g2009 ivltests
|
||||||
sv_end_labels_bad CE,-g2009 ivltests gold=sv_end_labels_bad.gold
|
sv_end_labels_bad CE,-g2009 ivltests gold=sv_end_labels_bad.gold
|
||||||
|
sv_end_labels_unnamed CE,-g2009 ivltests gold=sv_end_labels_unnamed.gold
|
||||||
sv_enum1 normal,-g2009 ivltests
|
sv_enum1 normal,-g2009 ivltests
|
||||||
sv_for_variable normal,-g2009 ivltests
|
sv_for_variable normal,-g2009 ivltests
|
||||||
sv_foreach1 normal,-g2009 ivltests
|
sv_foreach1 normal,-g2009 ivltests
|
||||||
|
|
|
||||||
281
parse.y
281
parse.y
|
|
@ -284,6 +284,24 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_end_label(const struct vlltype&loc, const char *type,
|
||||||
|
const char *begin, const char *end)
|
||||||
|
{
|
||||||
|
if (!end)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!begin)
|
||||||
|
yyerror(loc, "error: unnamed %s must not have end label.", type);
|
||||||
|
else if (strcmp(begin, end) != 0)
|
||||||
|
yyerror(loc, "error: %s end label `%s` doesn't match %s name"
|
||||||
|
" `%s`.", type, end, type, begin);
|
||||||
|
|
||||||
|
if (!gn_system_verilog())
|
||||||
|
yyerror(loc, "error: %s end label requires SystemVerilog.", type);
|
||||||
|
|
||||||
|
delete[] end;
|
||||||
|
}
|
||||||
|
|
||||||
static void current_task_set_statement(const YYLTYPE&loc, std::vector<Statement*>*s)
|
static void current_task_set_statement(const YYLTYPE&loc, std::vector<Statement*>*s)
|
||||||
{
|
{
|
||||||
if (s == 0) {
|
if (s == 0) {
|
||||||
|
|
@ -590,7 +608,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vector<Statem
|
||||||
%type <statement> udp_initial udp_init_opt
|
%type <statement> udp_initial udp_init_opt
|
||||||
%type <expr> udp_initial_expr_opt
|
%type <expr> udp_initial_expr_opt
|
||||||
|
|
||||||
%type <text> register_variable net_variable event_variable endlabel_opt class_declaration_endlabel_opt
|
%type <text> register_variable net_variable event_variable label_opt class_declaration_endlabel_opt
|
||||||
%type <text> block_identifier_opt
|
%type <text> block_identifier_opt
|
||||||
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
%type <perm_strings> register_variable_list net_variable_list event_variable_list
|
||||||
%type <perm_strings> list_of_identifiers loop_variables
|
%type <perm_strings> list_of_identifiers loop_variables
|
||||||
|
|
@ -789,10 +807,7 @@ class_declaration /* IEEE1800-2005: A.1.2 */
|
||||||
}
|
}
|
||||||
class_declaration_endlabel_opt
|
class_declaration_endlabel_opt
|
||||||
{ // Wrap up the class.
|
{ // Wrap up the class.
|
||||||
if ($11 && $4 && $4->name != $11) {
|
check_end_label(@11, "class", $4->name, $11);
|
||||||
yyerror(@11, "error: Class end label doesn't match class name.");
|
|
||||||
delete[]$11;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -1454,19 +1469,9 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
current_function = 0;
|
current_function = 0;
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name.
|
{ // Last step: check any closing name.
|
||||||
if ($11) {
|
check_end_label(@11, "function", $4, $11);
|
||||||
if (strcmp($4,$11) != 0) {
|
|
||||||
yyerror(@11, "error: End label doesn't match "
|
|
||||||
"function name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@11, "error: Function end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$11;
|
|
||||||
}
|
|
||||||
delete[]$4;
|
delete[]$4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1488,19 +1493,9 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
yyerror(@4, "error: Empty parenthesis syntax requires SystemVerilog.");
|
yyerror(@4, "error: Empty parenthesis syntax requires SystemVerilog.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name.
|
{ // Last step: check any closing name.
|
||||||
if ($14) {
|
check_end_label(@14, "function", $4, $14);
|
||||||
if (strcmp($4,$14) != 0) {
|
|
||||||
yyerror(@14, "error: End label doesn't match "
|
|
||||||
"function name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@14, "error: Function end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$14;
|
|
||||||
}
|
|
||||||
delete[]$4;
|
delete[]$4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1516,18 +1511,9 @@ function_declaration /* IEEE1800-2005: A.2.6 */
|
||||||
yyerror(@1, "error: Syntax error defining function.");
|
yyerror(@1, "error: Syntax error defining function.");
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name.
|
{ // Last step: check any closing name.
|
||||||
if ($8) {
|
check_end_label(@8, "function", $4, $8);
|
||||||
if (strcmp($4,$8) != 0) {
|
|
||||||
yyerror(@8, "error: End label doesn't match function name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@8, "error: Function end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$8;
|
|
||||||
}
|
|
||||||
delete[]$4;
|
delete[]$4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1996,15 +1982,9 @@ package_declaration /* IEEE1800-2005 A.1.2 */
|
||||||
timeunits_declaration_opt
|
timeunits_declaration_opt
|
||||||
{ pform_set_scope_timescale(@1); }
|
{ pform_set_scope_timescale(@1); }
|
||||||
package_item_list_opt
|
package_item_list_opt
|
||||||
K_endpackage endlabel_opt
|
K_endpackage label_opt
|
||||||
{ pform_end_package_declaration(@1);
|
{ pform_end_package_declaration(@1);
|
||||||
// If an end label is present make sure it match the package name.
|
check_end_label(@10, "package", $3, $10);
|
||||||
if ($10) {
|
|
||||||
if (strcmp($3,$10) != 0) {
|
|
||||||
yyerror(@10, "error: End label doesn't match package name");
|
|
||||||
}
|
|
||||||
delete[]$10;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -2319,22 +2299,13 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
||||||
}
|
}
|
||||||
delete $7;
|
delete $7;
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name. This is done late so
|
{ // Last step: check any closing name. This is done late so
|
||||||
// that the parser can look ahead to detect the present
|
// that the parser can look ahead to detect the present
|
||||||
// endlabel_opt but still have the pform_endmodule() called
|
// label_opt but still have the pform_endmodule() called
|
||||||
// early enough that the lexor can know we are outside the
|
// early enough that the lexor can know we are outside the
|
||||||
// module.
|
// module.
|
||||||
if ($10) {
|
check_end_label(@10, "task", $3, $10);
|
||||||
if (strcmp($3,$10) != 0) {
|
|
||||||
yyerror(@10, "error: End label doesn't match task name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@10, "error: Task end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$10;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2357,22 +2328,13 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
||||||
current_task = 0;
|
current_task = 0;
|
||||||
if ($10) delete $10;
|
if ($10) delete $10;
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name. This is done late so
|
{ // Last step: check any closing name. This is done late so
|
||||||
// that the parser can look ahead to detect the present
|
// that the parser can look ahead to detect the present
|
||||||
// endlabel_opt but still have the pform_endmodule() called
|
// label_opt but still have the pform_endmodule() called
|
||||||
// early enough that the lexor can know we are outside the
|
// early enough that the lexor can know we are outside the
|
||||||
// module.
|
// module.
|
||||||
if ($13) {
|
check_end_label(@13, "task", $3, $13);
|
||||||
if (strcmp($3,$13) != 0) {
|
|
||||||
yyerror(@13, "error: End label doesn't match task name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@13, "error: Task end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$13;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2383,22 +2345,13 @@ task_declaration /* IEEE1800-2005: A.2.7 */
|
||||||
current_task = 0;
|
current_task = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name. This is done late so
|
{ // Last step: check any closing name. This is done late so
|
||||||
// that the parser can look ahead to detect the present
|
// that the parser can look ahead to detect the present
|
||||||
// endlabel_opt but still have the pform_endmodule() called
|
// label_opt but still have the pform_endmodule() called
|
||||||
// early enough that the lexor can know we are outside the
|
// early enough that the lexor can know we are outside the
|
||||||
// module.
|
// module.
|
||||||
if ($7) {
|
check_end_label(@7, "task", $3, $7);
|
||||||
if (strcmp($3,$7) != 0) {
|
|
||||||
yyerror(@7, "error: End label doesn't match task name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@7, "error: Task end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$7;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
delete[]$3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4910,37 +4863,25 @@ module
|
||||||
}
|
}
|
||||||
pform_endmodule($4, in_celldefine, ucd);
|
pform_endmodule($4, in_celldefine, ucd);
|
||||||
}
|
}
|
||||||
endlabel_opt
|
label_opt
|
||||||
{ // Last step: check any closing name. This is done late so
|
{ // Last step: check any closing name. This is done late so
|
||||||
// that the parser can look ahead to detect the present
|
// that the parser can look ahead to detect the present
|
||||||
// endlabel_opt but still have the pform_endmodule() called
|
// label_opt but still have the pform_endmodule() called
|
||||||
// early enough that the lexor can know we are outside the
|
// early enough that the lexor can know we are outside the
|
||||||
// module.
|
// module.
|
||||||
if ($17) {
|
|
||||||
if (strcmp($4,$17) != 0) {
|
|
||||||
switch ($2) {
|
switch ($2) {
|
||||||
case K_module:
|
case K_module:
|
||||||
yyerror(@17, "error: End label doesn't match "
|
check_end_label(@17, "module", $4, $17);
|
||||||
"module name.");
|
|
||||||
break;
|
break;
|
||||||
case K_program:
|
case K_program:
|
||||||
yyerror(@17, "error: End label doesn't match "
|
check_end_label(@17, "program", $4, $17);
|
||||||
"program name.");
|
|
||||||
break;
|
break;
|
||||||
case K_interface:
|
case K_interface:
|
||||||
yyerror(@17, "error: End label doesn't match "
|
check_end_label(@17, "interface", $4, $17);
|
||||||
"interface name.");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (($2 == K_module) && (! gn_system_verilog())) {
|
|
||||||
yyerror(@8, "error: Module end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$17;
|
|
||||||
}
|
|
||||||
delete[]$4;
|
delete[]$4;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -4962,7 +4903,7 @@ module_end
|
||||||
| K_endinterface { $$ = K_interface; }
|
| K_endinterface { $$ = K_interface; }
|
||||||
;
|
;
|
||||||
|
|
||||||
endlabel_opt
|
label_opt
|
||||||
: ':' IDENTIFIER { $$ = $2; }
|
: ':' IDENTIFIER { $$ = $2; }
|
||||||
| { $$ = 0; }
|
| { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
@ -5435,7 +5376,7 @@ module_item
|
||||||
yyerrok;
|
yyerrok;
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_function error K_endfunction endlabel_opt
|
| K_function error K_endfunction label_opt
|
||||||
{ yyerror(@1, "error: I give up on this function definition.");
|
{ yyerror(@1, "error: I give up on this function definition.");
|
||||||
if ($4) {
|
if ($4) {
|
||||||
if (!gn_system_verilog()) {
|
if (!gn_system_verilog()) {
|
||||||
|
|
@ -5575,21 +5516,11 @@ generate_block
|
||||||
: { pform_generate_single_item = true; }
|
: { pform_generate_single_item = true; }
|
||||||
module_item
|
module_item
|
||||||
{ pform_generate_single_item = false; }
|
{ pform_generate_single_item = false; }
|
||||||
| K_begin generate_item_list_opt K_end
|
| K_begin label_opt generate_item_list_opt K_end label_opt
|
||||||
| K_begin ':' IDENTIFIER generate_item_list_opt K_end endlabel_opt
|
{ if ($2)
|
||||||
{ pform_generate_block_name($3);
|
pform_generate_block_name($2);
|
||||||
if ($6) {
|
check_end_label(@5, "block", $2, $5);
|
||||||
if (strcmp($3,$6) != 0) {
|
delete[]$2;
|
||||||
yyerror(@6, "error: End label doesn't match "
|
|
||||||
"begin name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@6, "error: Begin end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$6;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -6576,12 +6507,13 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
the declarations. The scope is popped at the end of the block. */
|
the declarations. The scope is popped at the end of the block. */
|
||||||
|
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_begin
|
| K_begin label_opt
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, 0, PBlock::BL_SEQ);
|
{ PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_SEQ);
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
{ if ($3) {
|
{ if (!$2) {
|
||||||
|
if ($4) {
|
||||||
if (! gn_system_verilog()) {
|
if (! gn_system_verilog()) {
|
||||||
yyerror("error: Variable declaration in unnamed block "
|
yyerror("error: Variable declaration in unnamed block "
|
||||||
"requires SystemVerilog.");
|
"requires SystemVerilog.");
|
||||||
|
|
@ -6595,9 +6527,10 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statement_or_null_list_opt K_end
|
}
|
||||||
|
statement_or_null_list_opt K_end label_opt
|
||||||
{ PBlock*tmp;
|
{ PBlock*tmp;
|
||||||
if ($3) {
|
if ($2 || $4) {
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
assert(! current_block_stack.empty());
|
assert(! current_block_stack.empty());
|
||||||
tmp = current_block_stack.top();
|
tmp = current_block_stack.top();
|
||||||
|
|
@ -6606,33 +6539,10 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
tmp = new PBlock(PBlock::BL_SEQ);
|
tmp = new PBlock(PBlock::BL_SEQ);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
}
|
}
|
||||||
if ($5) tmp->set_statement(*$5);
|
|
||||||
delete $5;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_begin ':' IDENTIFIER
|
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, $3, PBlock::BL_SEQ);
|
|
||||||
current_block_stack.push(tmp);
|
|
||||||
}
|
|
||||||
block_item_decls_opt
|
|
||||||
statement_or_null_list_opt K_end endlabel_opt
|
|
||||||
{ pform_pop_scope();
|
|
||||||
assert(! current_block_stack.empty());
|
|
||||||
PBlock*tmp = current_block_stack.top();
|
|
||||||
current_block_stack.pop();
|
|
||||||
if ($6) tmp->set_statement(*$6);
|
if ($6) tmp->set_statement(*$6);
|
||||||
delete $6;
|
delete $6;
|
||||||
if ($8) {
|
check_end_label(@8, "block", $2, $8);
|
||||||
if (strcmp($3,$8) != 0) {
|
delete[]$2;
|
||||||
yyerror(@8, "error: End label doesn't match begin name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@8, "error: Begin end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$8;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6642,12 +6552,14 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
code generator can do the right thing. */
|
code generator can do the right thing. */
|
||||||
|
|
||||||
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
/* In SystemVerilog an unnamed block can contain variable declarations. */
|
||||||
| K_fork
|
| K_fork label_opt
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, 0, PBlock::BL_PAR);
|
{ PBlock*tmp = pform_push_block_scope(@1, $2, PBlock::BL_PAR);
|
||||||
current_block_stack.push(tmp);
|
current_block_stack.push(tmp);
|
||||||
}
|
}
|
||||||
block_item_decls_opt
|
block_item_decls_opt
|
||||||
{ if ($3) {
|
{
|
||||||
|
if (!$2) {
|
||||||
|
if ($4) {
|
||||||
if (! gn_system_verilog()) {
|
if (! gn_system_verilog()) {
|
||||||
yyerror("error: Variable declaration in unnamed block "
|
yyerror("error: Variable declaration in unnamed block "
|
||||||
"requires SystemVerilog.");
|
"requires SystemVerilog.");
|
||||||
|
|
@ -6661,46 +6573,23 @@ statement_item /* This is roughly statement_item in the LRM */
|
||||||
delete tmp;
|
delete tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statement_or_null_list_opt join_keyword
|
}
|
||||||
|
statement_or_null_list_opt join_keyword label_opt
|
||||||
{ PBlock*tmp;
|
{ PBlock*tmp;
|
||||||
if ($3) {
|
if ($2 || $4) {
|
||||||
pform_pop_scope();
|
pform_pop_scope();
|
||||||
assert(! current_block_stack.empty());
|
assert(! current_block_stack.empty());
|
||||||
tmp = current_block_stack.top();
|
tmp = current_block_stack.top();
|
||||||
current_block_stack.pop();
|
current_block_stack.pop();
|
||||||
tmp->set_join_type($6);
|
tmp->set_join_type($7);
|
||||||
} else {
|
} else {
|
||||||
tmp = new PBlock($6);
|
tmp = new PBlock($7);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
}
|
}
|
||||||
if ($5) tmp->set_statement(*$5);
|
|
||||||
delete $5;
|
|
||||||
$$ = tmp;
|
|
||||||
}
|
|
||||||
| K_fork ':' IDENTIFIER
|
|
||||||
{ PBlock*tmp = pform_push_block_scope(@1, $3, PBlock::BL_PAR);
|
|
||||||
current_block_stack.push(tmp);
|
|
||||||
}
|
|
||||||
block_item_decls_opt
|
|
||||||
statement_or_null_list_opt join_keyword endlabel_opt
|
|
||||||
{ pform_pop_scope();
|
|
||||||
assert(! current_block_stack.empty());
|
|
||||||
PBlock*tmp = current_block_stack.top();
|
|
||||||
current_block_stack.pop();
|
|
||||||
tmp->set_join_type($7);
|
|
||||||
if ($6) tmp->set_statement(*$6);
|
if ($6) tmp->set_statement(*$6);
|
||||||
delete $6;
|
delete $6;
|
||||||
if ($8) {
|
check_end_label(@8, "fork", $2, $8);
|
||||||
if (strcmp($3,$8) != 0) {
|
delete[]$2;
|
||||||
yyerror(@8, "error: End label doesn't match fork name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@8, "error: Fork end labels require "
|
|
||||||
"SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$8;
|
|
||||||
}
|
|
||||||
delete[]$3;
|
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7387,22 +7276,13 @@ udp_primitive
|
||||||
udp_port_decls
|
udp_port_decls
|
||||||
udp_init_opt
|
udp_init_opt
|
||||||
udp_body
|
udp_body
|
||||||
K_endprimitive endlabel_opt
|
K_endprimitive label_opt
|
||||||
|
|
||||||
{ perm_string tmp2 = lex_strings.make($2);
|
{ perm_string tmp2 = lex_strings.make($2);
|
||||||
pform_make_udp(tmp2, $4, $7, $9, $8,
|
pform_make_udp(tmp2, $4, $7, $9, $8,
|
||||||
@2.text, @2.first_line);
|
@2.text, @2.first_line);
|
||||||
if ($11) {
|
|
||||||
if (strcmp($2,$11) != 0) {
|
check_end_label(@11, "primitive", $2, $11);
|
||||||
yyerror(@11, "error: End label doesn't match "
|
|
||||||
"primitive name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@11, "error: Primitive end labels "
|
|
||||||
"require SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$11;
|
|
||||||
}
|
|
||||||
delete[]$2;
|
delete[]$2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7413,23 +7293,14 @@ udp_primitive
|
||||||
'(' K_output udp_reg_opt IDENTIFIER udp_initial_expr_opt ','
|
'(' K_output udp_reg_opt IDENTIFIER udp_initial_expr_opt ','
|
||||||
udp_input_declaration_list ')' ';'
|
udp_input_declaration_list ')' ';'
|
||||||
udp_body
|
udp_body
|
||||||
K_endprimitive endlabel_opt
|
K_endprimitive label_opt
|
||||||
|
|
||||||
{ perm_string tmp2 = lex_strings.make($2);
|
{ perm_string tmp2 = lex_strings.make($2);
|
||||||
perm_string tmp6 = lex_strings.make($6);
|
perm_string tmp6 = lex_strings.make($6);
|
||||||
pform_make_udp(tmp2, $5, tmp6, $7, $9, $12,
|
pform_make_udp(tmp2, $5, tmp6, $7, $9, $12,
|
||||||
@2.text, @2.first_line);
|
@2.text, @2.first_line);
|
||||||
if ($14) {
|
|
||||||
if (strcmp($2,$14) != 0) {
|
check_end_label(@14, "primitive", $2, $14);
|
||||||
yyerror(@14, "error: End label doesn't match "
|
|
||||||
"primitive name");
|
|
||||||
}
|
|
||||||
if (! gn_system_verilog()) {
|
|
||||||
yyerror(@14, "error: Primitive end labels "
|
|
||||||
"require SystemVerilog.");
|
|
||||||
}
|
|
||||||
delete[]$14;
|
|
||||||
}
|
|
||||||
delete[]$2;
|
delete[]$2;
|
||||||
delete[]$6;
|
delete[]$6;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue