Parse function declarations in classes.

Also add support for function end names when parsing SystemVerilog.
This commit is contained in:
Stephen Williams 2012-02-26 19:16:10 -08:00
parent f33086fed4
commit 68eab8c664
1 changed files with 113 additions and 74 deletions

187
parse.y
View File

@ -632,6 +632,8 @@ class_item /* IEEE1800-2005: A.1.8 */
| task_declaration | task_declaration
| function_declaration
/* Here are some error matching rules to help recover from various /* Here are some error matching rules to help recover from various
syntax errors within a class declaration. */ syntax errors within a class declaration. */
@ -724,6 +726,116 @@ for_step /* IEEE1800-2005: A.6.8 */
; ;
/* The function declaration rule matches the function declaration
header, then pushes the function scope. This causes the
definitions in the func_body to take on the scope of the function
instead of the module. */
function_declaration /* IEEE1800-2005: A.2.6 */
: K_function K_automatic_opt function_range_or_type_opt IDENTIFIER ';'
{ assert(current_function == 0);
current_function = pform_push_function_scope(@1, $4, $2);
}
function_item_list statement_list
K_endfunction
{ current_function->set_ports($7);
current_function->set_return($3);
assert($8 && $8->size() > 0);
if ($8->size() == 1) {
current_function->set_statement((*$8)[0]);
delete $8;
} else {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @8);
tmp->set_statement( *$8 );
current_function->set_statement(tmp);
delete $8;
if (!gn_system_verilog()) {
yyerror(@8, "error: Function body with multiple statements requres SystemVerilog.");
}
}
pform_pop_scope();
current_function = 0;
}
endname_opt
{ // Last step: check any closing name.
if ($11 && (strcmp($4,$11) != 0)) {
yyerror(@11, "error: End name doesn't match function name");
}
if ($11 && !gn_system_verilog()) {
yyerror(@11, "error: Function end names require System Verilog.");
}
delete[]$4;
if ($11) delete[]$11;
}
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER
{ assert(current_function == 0);
current_function = pform_push_function_scope(@1, $4, $2);
}
'(' tf_port_list_opt ')' ';'
block_item_decls_opt
statement_list
K_endfunction
{ current_function->set_ports($7);
current_function->set_return($3);
assert($11 && $11->size() > 0);
if ($11->size() == 1) {
current_function->set_statement((*$11)[0]);
delete $11;
} else {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @11);
tmp->set_statement( *$11 );
current_function->set_statement(tmp);
delete $11;
if (!gn_system_verilog()) {
yyerror(@11, "error: Function body with multiple statements requres SystemVerilog.");
}
}
pform_pop_scope();
current_function = 0;
if ($7==0 && !gn_system_verilog()) {
yyerror(@4, "error: Empty parenthesis syntax requires SystemVerilog.");
}
}
endname_opt
{ // Last step: check any closing name.
if ($14 && (strcmp($4,$14) != 0)) {
yyerror(@14, "error: End name doesn't match function name");
}
if ($14 && !gn_system_verilog()) {
yyerror(@14, "error: Function end names require System Verilog.");
}
delete[]$4;
if ($14) delete[]$14;
}
/* Detect and recover from some errors. */
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction
{ /* */
if (current_function) {
pform_pop_scope();
current_function = 0;
}
assert(current_function == 0);
yyerror(@1, "error: Syntax error defining function.");
yyerrok;
}
endname_opt
{ // Last step: check any closing name.
if ($8 && (strcmp($4,$8) != 0)) {
yyerror(@4, "error: End name doesn't match function name");
}
if ($8 && !gn_system_verilog()) {
yyerror(@8, "error: Function end names require System Verilog.");
}
delete[]$4;
if ($8) delete[]$8;
}
;
implicit_class_handle /* IEEE1800-2005: A.8.4 */ implicit_class_handle /* IEEE1800-2005: A.8.4 */
: K_this : K_this
| K_super | K_super
@ -3643,80 +3755,7 @@ module_item
| task_declaration | task_declaration
/* The function declaration rule matches the function declaration | function_declaration
header, then pushes the function scope. This causes the
definitions in the func_body to take on the scope of the function
instead of the module. */
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER ';'
{ assert(current_function == 0);
current_function = pform_push_function_scope(@1, $4, $2);
}
function_item_list statement_list
K_endfunction
{ current_function->set_ports($7);
current_function->set_return($3);
assert($8 && $8->size() > 0);
if ($8->size() == 1) {
current_function->set_statement((*$8)[0]);
delete $8;
} else {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @8);
tmp->set_statement( *$8 );
current_function->set_statement(tmp);
delete $8;
if (!gn_system_verilog()) {
yyerror(@8, "error: Function body with multiple statements requres SystemVerilog.");
}
}
pform_pop_scope();
current_function = 0;
delete[]$4;
}
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER
{ assert(current_function == 0);
current_function = pform_push_function_scope(@1, $4, $2);
}
'(' tf_port_list_opt ')' ';'
block_item_decls_opt
statement_list
K_endfunction
{ current_function->set_ports($7);
current_function->set_return($3);
assert($11 && $11->size() > 0);
if ($11->size() == 1) {
current_function->set_statement((*$11)[0]);
delete $11;
} else {
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
FILE_NAME(tmp, @11);
tmp->set_statement( *$11 );
current_function->set_statement(tmp);
delete $11;
if (!gn_system_verilog()) {
yyerror(@11, "error: Function body with multiple statements requres SystemVerilog.");
}
}
pform_pop_scope();
current_function = 0;
delete[]$4;
if ($7==0 && !gn_system_verilog()) {
yyerror(@4, "error: Empty parenthesis syntax requires SystemVerilog.");
}
}
| K_function K_automatic_opt function_range_or_type_opt IDENTIFIER error K_endfunction
{ /* */
if (current_function) {
pform_pop_scope();
current_function = 0;
}
assert(current_function == 0);
yyerror(@1, "error: Syntax error defining function.");
yyerrok;
delete[]$4;
}
/* A generate region can contain further module items. Actually, it /* A generate region can contain further module items. Actually, it
is supposed to be limited to certain kinds of module items, but is supposed to be limited to certain kinds of module items, but