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

Reply via email to