Factor block variable declaration grammar
Block variable declarations currently combine optional `const` and lifetime qualifiers with the data type. This requires reducing empty qualifier rules before the parser can determine which declaration form follows, making the rule difficult to use in a mixed procedural item list without conflicts. Split the declaration productions according to their leading syntax. Share required and optional variable lifetime handling and add a rule for data types following the historical leading `reg` extension. This keeps the declaration behavior unchanged while allowing the parser to distinguish each form from its leading token. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
7792b5ab8a
commit
97928cfb15
69
parse.y
69
parse.y
|
|
@ -947,6 +947,7 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type,
|
|||
%type <decl_assignments_with_type> list_of_variable_decl_assignments_with_type
|
||||
|
||||
%type <data_type> data_type data_type_opt data_type_or_implicit data_type_or_implicit_or_void
|
||||
%type <data_type> block_reg_data_type
|
||||
%type <data_type> implicit_type
|
||||
%type <data_type> reg_prefixed_atomic_type simple_type_or_string let_formal_type
|
||||
%type <data_type> packed_array_data_type atomic_type
|
||||
|
|
@ -1569,6 +1570,17 @@ atomic_type
|
|||
}
|
||||
;
|
||||
|
||||
block_reg_data_type
|
||||
: unsigned_signed_opt dimensions_opt
|
||||
{ vector_type_t *tmp = new vector_type_t(IVL_VT_LOGIC, $1, $2);
|
||||
FILE_NAME(tmp, @1);
|
||||
$$ = tmp;
|
||||
}
|
||||
| reg_prefixed_atomic_type
|
||||
{ $$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
/* Data types allowed after the historical iverilog extension that permits an
|
||||
extra leading `reg` in block declarations. Keep `reg` itself out of this
|
||||
subset so ordinary `reg` declarations continue through the normal rules. */
|
||||
|
|
@ -3056,7 +3068,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */
|
|||
}
|
||||
;
|
||||
|
||||
variable_lifetime_opt
|
||||
variable_lifetime
|
||||
: lifetime
|
||||
{ LexicalScope*scope = pform_peek_scope();
|
||||
if (dynamic_cast<PPackage*>(scope)) {
|
||||
|
|
@ -3071,6 +3083,10 @@ variable_lifetime_opt
|
|||
}
|
||||
var_lifetime = $1;
|
||||
}
|
||||
;
|
||||
|
||||
variable_lifetime_opt
|
||||
: variable_lifetime
|
||||
|
|
||||
;
|
||||
|
||||
|
|
@ -3147,14 +3163,39 @@ block_item_decl
|
|||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| K_const_opt variable_lifetime_opt data_type list_of_variable_decl_assignments ';'
|
||||
{ if ($3) pform_make_var(@3, $4, $3, attributes_in_context, $1);
|
||||
| K_const variable_lifetime_opt data_type list_of_variable_decl_assignments ';'
|
||||
{ if ($3) pform_make_var(@3, $4, $3, attributes_in_context, true);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| variable_lifetime data_type list_of_variable_decl_assignments ';'
|
||||
{ if ($2) pform_make_var(@2, $3, $2, attributes_in_context, false);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| reg_prefixed_atomic_type list_of_variable_decl_assignments ';'
|
||||
{ if ($1) pform_make_var(@1, $2, $1, attributes_in_context, false);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| K_reg block_reg_data_type list_of_variable_decl_assignments ';'
|
||||
{ if ($2) pform_make_var(@1, $3, $2, attributes_in_context, false);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| ps_type_identifier_dim list_of_variable_decl_assignments ';'
|
||||
{ if ($1) pform_make_var(@1, $2, $1, attributes_in_context, false);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
/* The extra `reg` is not valid (System)Verilog, this is an iverilog extension. */
|
||||
| K_const_opt variable_lifetime_opt K_reg reg_prefixed_atomic_type list_of_variable_decl_assignments ';'
|
||||
{ if ($4) pform_make_var(@4, $5, $4, attributes_in_context, $1);
|
||||
| K_const variable_lifetime_opt K_reg reg_prefixed_atomic_type list_of_variable_decl_assignments ';'
|
||||
{ if ($4) pform_make_var(@4, $5, $4, attributes_in_context, true);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
| variable_lifetime K_reg reg_prefixed_atomic_type list_of_variable_decl_assignments ';'
|
||||
{ if ($3) pform_make_var(@3, $4, $3, attributes_in_context, false);
|
||||
var_lifetime = LexicalScope::INHERITED;
|
||||
}
|
||||
|
||||
|
|
@ -3174,7 +3215,23 @@ block_item_decl
|
|||
|
||||
/* Recover from errors that happen within variable lists. Use the
|
||||
trailing semi-colon to resync the parser. */
|
||||
| K_const_opt variable_lifetime_opt data_type error ';'
|
||||
| K_const variable_lifetime_opt data_type error ';'
|
||||
{ yyerror(@1, "error: Syntax error in variable list.");
|
||||
yyerrok;
|
||||
}
|
||||
| variable_lifetime data_type error ';'
|
||||
{ yyerror(@1, "error: Syntax error in variable list.");
|
||||
yyerrok;
|
||||
}
|
||||
| reg_prefixed_atomic_type error ';'
|
||||
{ yyerror(@1, "error: Syntax error in variable list.");
|
||||
yyerrok;
|
||||
}
|
||||
| K_reg block_reg_data_type error ';'
|
||||
{ yyerror(@1, "error: Syntax error in variable list.");
|
||||
yyerrok;
|
||||
}
|
||||
| ps_type_identifier_dim error ';'
|
||||
{ yyerror(@1, "error: Syntax error in variable list.");
|
||||
yyerrok;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue