|
From: Martin W. <mai...@ma...> - 2015-01-09 20:32:50
|
Stephen Williams wrote:
> This problem has been solved in the parser for module ports.
OK, that's basically what I had in mind when I said I could solve this by
building my own mini state machine and parser within the modport_ports_list
rule (and what Niels suggested as well). It's a bit more complicated than the
module ports case, because you have modport expressions, task/function
import/export, and clocking declarations thrown into the mix. It's ugly, but
it works.
For anyone interested, the solution looks like this:
modport_ports_list
: modport_port_declaration
| modport_ports_list ',' modport_port_declaration
| modport_ports_list ',' modport_simple_port
{ if (last_modport_port != MODPORT_SIMPLE)
yyerror(@3, "syntax error");
}
| modport_ports_list ',' modport_tf_port
{ if (last_modport_port != MODPORT_TF)
yyerror(@3, "syntax error");
}
| modport_ports_list ',' IDENTIFIER
{ if (last_modport_port == MODPORT_CLOCKING)
yyerror(@3, "syntax error");
}
| modport_ports_list ','
{ yyerror(@2, "error: NULL port declarations are not allowed"); }
;
modport_port_declaration
: attribute_list_opt port_direction IDENTIFIER
{ last_modport_port = MODPORT_SIMPLE;
}
| attribute_list_opt port_direction modport_simple_port
{ last_modport_port = MODPORT_SIMPLE;
}
| attribute_list_opt import_export IDENTIFIER
{ last_modport_port = MODPORT_TF;
}
| attribute_list_opt import_export modport_tf_port
{ last_modport_port = MODPORT_TF;
}
| attribute_list_opt K_clocking IDENTIFIER
{ last_modport_port = MODPORT_CLOCKING;
}
;
modport_simple_port
: '.' IDENTIFIER '(' expression ')'
;
modport_tf_port
: K_task IDENTIFIER
| K_task IDENTIFIER '(' tf_port_list_opt ')'
| K_function data_type_or_implicit_or_void IDENTIFIER
| K_function data_type_or_implicit_or_void IDENTIFIER '(' tf_port_list_opt ')'
;
(and yes, I'll be putting in better error messages).
|