On 23 Dec 2013, at 8:40 pm, [email protected] wrote:
> I think that ghdl is compliant with VHDL 1993 and 2002. That's modulo
> bugs, but I think that all features are implemented. If not, do not
> hesitate to raise issues.
entity label_test is
generic (MODE: natural range 0 to 1 := 1);
end entity;
architecture fum of label_test is
begin
if_label:
if MODE = 1 then
end if;
end architecture;
david_koontz@Macbook: ghdl -a label_test.vhdl
label_test.vhdl:8:16: 'generate' is expected instead of 'then'
ghdl: compilation error
However:
entity no_label_test is
generic (MODE: natural range 0 to 1 := 1);
end entity;
architecture fum of no_label_test is
begin
if MODE = 1 then
end if;
end architecture;
david_koontz@Macbook: ghdl -a no_label_test.vhdl
no_label_test.vhdl:7:4: a generate statement must have a label
no_label_test.vhdl:7:16: 'generate' is expected instead of 'then'
ghdl: compilation error
Normative BNF is described with a left-recursive rule.
0.2.1 Syntactic description
The form of a VHDL description is described by means of context-free syntax,
using a simple variant of backus naur form; in particular:
...
f. Braces enclose a repeated item or items on the right-hand side of a
production. The items may appear zero or more times; the repetitions occur from
left to right as with an equivalent left-recursive rule.
1.2.2 Architecture statement part
The architecture statement part contains statements that describe the internal
organization and/or operation of the block defined by the design entity.
architecture_statement_part ::=
{ concurrent_statement }
...
9.7 Generate statements
A generate statement provides a mechanism for iterative or conditional
elaboration of a portion of a description.
generate_statement ::=
generate_label :
generation_scheme generate
[ { block_declarative_item }
begin]
{ concurrent_statement }
end generate [ generate_label ] ;
generation_scheme ::=
for generate_parameter_specification
| if condition
label ::= identifier
...
-------
And here you'll note that a generate_label is not optional. In left recursive
described BNF a lookahead of one is sufficient to tell this is not a generate
statement.
If we look at Section 9, Concurrent statements, the normative BNF:
concurrent_statement ::=
block_statement
| process_statement
| concurrent_procedure_call_statement
| concurrent_assertion_statement
| concurrent_signal_assignment_statement
| component_instantiation_statement
| generate_statement
We see that generate is the last choice (alternative rule). Finding the
keyword if instead of a label is sufficient to distinguish the current
statement is not a concurrent statement, and it is not a generate statement in
particular.
(And you can expand all the rules to demonstrate this, believe me it has been
done before).
The error messages for no_label_test are in error.
While the parser for ghdl has the appearance of being handwritten this can be
an issue in older versions of Bison, where the ability to specify an error
associated with a non-terminal rule (concurrent_statement) wasn't available,
effectively complaining about the last production (generate_statement). That
isn't the case here.
The error here is in Parse_Generate_Statement in parse.adb, not rejecting the
rule generate_statement when the first production (label) does not match.
Instead of Error_Msg_Parse ("a generate statement must have a label");
generate_statement should be rejected.
The actual error is in procedure Parse_Concurrent_Statements in parse.adb, the
structure, treating a label as an attribute of a named object (and a generate
statement is no (5.1, Attribute specification the rule for entity_class).
Line 5185:
when Tok_If
| Tok_For =>
if Postponed then
Error_Msg_Parse
("'postponed' not allowed before a generate statement");
Postponed := False;
end if;
Stmt := Parse_Generate_Statement (Label, Loc);
A label is a named entity. (See 5.1 entity_class again).
A label is only required for generate statements (9.7 above, also see 12.4.2
Generate statements (elaboration of generate statements) for why.
Treating a label as an attribute is benign every where but here because a
generate statement is not a named entity, saying the fix should be in
Parse_Generate_Statement. (And ghdl isn't the only VHDL tool that parses
labels as prefix attributes in all cases).
You could also note that without the required label the bit about postponed is
in error as well. Also a case of inventing a problem not in evidence.
(And about now this feels reminiscent of Il Duce's six hour 1934 radio
broadcast going on about the relative merits of staples versu paperclips, in
that case intended to make metal available for military uses. The broad cast
in Italian, partially recorded by the BBC, the recording at one time available
on the web.)
Think of this one as being provided for the entertainment value. An unexpected
keyword normally used for a generate scheme in a place valid for a concurrent
statement isn't going to be made any clearer by something along the lines of
"unexpected keyword if, does not signify a concurrent statement".
The particular case leading to no_label_test comes from a VHDL neophyte asking
what was wrong with his code, attempting to use a sequential (if) statement in
a place appropriate for a concurrent statement, then noticing significant
disparity in how the error was reported by various VHDL tools.
And it does represent non-compliant behavior.
To paraphrase Steve Martin - 'Compliance, isn't pretty.'
Meri Kirihimete, y'all.
_______________________________________________
Ghdl-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/ghdl-discuss