Fixup parse of attributes attached to statements.

This commit is contained in:
Stephen Williams 2012-04-27 18:22:25 -07:00
parent ae901f3285
commit abf8274e4b
1 changed files with 46 additions and 48 deletions

94
parse.y
View File

@ -574,7 +574,8 @@ static void current_function_set_statement(const YYLTYPE&loc, vector<Statement*>
%type <event_expr> event_expression_list
%type <event_expr> event_expression
%type <event_statement> event_control
%type <statement> statement statement_or_null compressed_statement
%type <statement> statement statement_item statement_or_null
%type <statement> compressed_statement
%type <statement> loop_statement for_step jump_statement
%type <statement_list> statement_or_null_list statement_or_null_list_opt
@ -749,7 +750,7 @@ class_item /* IEEE1800-2005: A.1.8 */
cause a conflict. */
| method_qualifier_opt K_function K_new '(' tf_port_list_opt ')' ';'
function_item_list_opt
implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
attribute_list_opt implicit_class_handle '.' K_new '(' expression_list_with_nuls ')'
statement_or_null_list_opt
K_endfunction endnew_opt
{ yyerror(@3, "sorry: Class constructors not supported yet.");
@ -1316,13 +1317,20 @@ signing /* IEEE1800-2005: A.2.2.1 */
| K_unsigned { $$ = false; }
;
statement /* IEEE1800-2005: A.6.4 */
: attribute_list_opt statement_item
{ pform_bind_attributes($2->attributes, $1);
$$ = $2;
}
;
/* Many places where statements are allowed can actually take a
statement or a null statement marked with a naked semi-colon. */
statement_or_null /* IEEE1800-2005: A.6.4 */
: statement
{ $$ = $1; }
| ';'
| attribute_list_opt ';'
{ $$ = 0; }
;
@ -1797,35 +1805,31 @@ block_item_decl
all the trappings of a general variable declaration. All of that
is implicit in the "integer" of the declaration. */
: attribute_list_opt K_integer signed_unsigned_opt register_variable_list ';'
{ pform_set_reg_integer($4);
if ($1) delete $1;
}
: K_integer signed_unsigned_opt register_variable_list ';'
{ pform_set_reg_integer($3);
}
| attribute_list_opt K_time register_variable_list ';'
{ pform_set_reg_time($3);
if ($1) delete $1;
}
| K_time register_variable_list ';'
{ pform_set_reg_time($2);
}
/* variable declarations. Note that data_type can be 0 if we are
recovering from an error. */
| attribute_list_opt data_type register_variable_list ';'
| data_type register_variable_list ';'
{ if ($1) pform_set_data_type(@1, $1, $2);
}
| K_reg data_type register_variable_list ';'
{ if ($2) pform_set_data_type(@2, $2, $3);
if ($1) delete $1;
}
| attribute_list_opt K_reg data_type register_variable_list ';'
{ if ($3) pform_set_data_type(@3, $3, $4);
if ($1) delete $1;
| K_event list_of_identifiers ';'
{ pform_make_events($2, @1.text, @1.first_line);
}
| K_event list_of_identifiers ';'
{ pform_make_events($2, @1.text, @1.first_line);
}
| K_parameter parameter_assign_decl ';'
| K_localparam localparam_assign_decl ';'
| K_parameter parameter_assign_decl ';'
| K_localparam localparam_assign_decl ';'
/* Blocks can have type declarations. */
@ -1833,15 +1837,16 @@ block_item_decl
/* Recover from errors that happen within variable lists. Use the
trailing semi-colon to resync the parser. */
| attribute_list_opt K_integer error ';'
{ yyerror(@2, "error: syntax error in integer variable list.");
yyerrok;
if ($1) delete $1;
}
| attribute_list_opt K_time error ';'
{ yyerror(@2, "error: syntax error in time variable list.");
yyerrok;
}
| K_integer error ';'
{ yyerror(@1, "error: syntax error in integer variable list.");
yyerrok;
}
| K_time error ';'
{ yyerror(@1, "error: syntax error in time variable list.");
yyerrok;
}
| K_parameter error ';'
{ yyerror(@1, "error: syntax error in parameter list.");
@ -4199,15 +4204,15 @@ module_item
/* Always and initial items are behavioral processes. */
| attribute_list_opt K_always statement
| attribute_list_opt K_always statement_item
{ PProcess*tmp = pform_make_behavior(IVL_PR_ALWAYS, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_initial statement
| attribute_list_opt K_initial statement_item
{ PProcess*tmp = pform_make_behavior(IVL_PR_INITIAL, $3, $1);
FILE_NAME(tmp, @2);
}
| attribute_list_opt K_final statement
| attribute_list_opt K_final statement_item
{ PProcess*tmp = pform_make_behavior(IVL_PR_FINAL, $3, $1);
FILE_NAME(tmp, @2);
}
@ -5445,7 +5450,7 @@ spec_notifier
;
statement /* This is roughly statement_item in the LRM */
statement_item /* This is roughly statement_item in the LRM */
/* assign and deassign statements are procedural code to do
structural assignments, and to turn that structural assignment
@ -5513,8 +5518,6 @@ statement /* This is roughly statement_item in the LRM */
delete $6;
$$ = tmp;
}
| K_begin error K_end
{ yyerrok; }
/* fork-join blocks are very similar to begin-end blocks. In fact,
from the parser's perspective there is no real difference. All we
@ -5549,8 +5552,6 @@ statement /* This is roughly statement_item in the LRM */
delete $6;
$$ = tmp;
}
| K_fork error K_join
{ yyerrok; }
| K_disable hierarchy_identifier ';'
{ PDisable*tmp = new PDisable(*$2);
@ -5630,29 +5631,26 @@ statement /* This is roughly statement_item in the LRM */
$$ = tmp;
}
| event_control attribute_list_opt statement_or_null
| event_control statement_or_null
{ PEventStatement*tmp = $1;
if (tmp == 0) {
yyerror(@1, "error: Invalid event control.");
$$ = 0;
} else {
if ($3) pform_bind_attributes($3->attributes,$2);
tmp->set_statement($3);
tmp->set_statement($2);
$$ = tmp;
}
}
| '@' '*' attribute_list_opt statement_or_null
| '@' '*' statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
if ($4) pform_bind_attributes($4->attributes,$3);
tmp->set_statement($4);
tmp->set_statement($3);
$$ = tmp;
}
| '@' '(' '*' ')' attribute_list_opt statement_or_null
| '@' '(' '*' ')' statement_or_null
{ PEventStatement*tmp = new PEventStatement;
FILE_NAME(tmp, @1);
if ($6) pform_bind_attributes($6->attributes,$5);
tmp->set_statement($6);
tmp->set_statement($5);
$$ = tmp;
}