Extra optional semicolon at the end of interface_list
Proposal Details
- Who Updates: Bert de Jong
- Date Proposed: 24 Oktober 2013
- Date Last Updated: 25 Oktober 2013
- Priority:
- Complexity: very easy
- Focus:
Language Change Specification Link
LCS-2016-071a
LCS-2016-071b for related optional extra commas.
Current Situation
Throughout the standard semicolons are used as termination characters, except for generic, port, function and procedure declarations, where they are used as separation characters. Having the option to add another semicolon after the last element would make the language seem more consistent.
Requirement
Implementation details
The only syntax rule that would have to be changed is:
interface_list ::=
interface_declaration {';' interface_declaration}
To:
interface_list ::=
interface_declaration {';' interface_declaration} [;]
Code Examples
Current situation
entity someEntity is
port
(
a : std_logic;
b : integer
);
end entity;
New situation
entity someEntity is
port
(
a : std_logic;
b : integer;
);
end entity;
Use Cases
Arguments FOR
--
ErnstChristen - 2015-01-21
Since in VHDL the semicolon is a statement terminator it could be argued that current syntax is not consistent.
--
RobGaddi - 2015-02-02
I've certainly found that currently illegal trailing semicolons are one of the things that frequently give me "stupid" syntax errors; i.e. syntax errors that in no way request illegal things or create ambiguities as to my intention, but simply fall afoul of some semantic quibble. It makes programmatically generating code, re-ordering port lists for clarity, and even copying and pasting from one design to the next fractionally harder than it needs to be. Optional semicolons would be a fairly minor win, but implementationally it's a fairly minor lift as well.
Arguments AGAINST
General Comments
--
DavidKoontz - 2015-02-14 interface_list isn't a terminal production (it consumes no tokens in and of itself). Adding a superfluous semicolon
delimiter to a non-terminal has the effect of changing a parser from (theoretically) a single token look ahead to a look ahead of two (from my interface_list.c):
NEXT_INTERFACE__ELEMENT:
last_token = token;
token = get_token();
switch (token) {
case DELIM_SEMICOLON:
emit(END,""); /* INTERFACE_DECLARATION */
goto INTERFACE__LIST; /* more interface declarations */
break;
case DELIM_RIGHT_PAREN:
emit(END,""); /* INTERFACE_LIST */
goto INTERFACE__LIST_END;
break;
default:
emit(SYNTAX_ERROR,"INTERFACE ELEMENT, expected ';' or ')'");
break;
}
INTERFACE__LIST_END:
if (intf_list_class == INTF_LIST_CLASS_PARAMETER)
return; /* interface list termination for subprograms handled
externally */
/* else */
last_token = token;
token = get_token();
if (token != DELIM_SEMICOLON) {
if (intf_list_class == INTF_LIST_CLASS_PORT)
emit(SYNTAX_ERROR,"PORT_CLAUSE, expected terminating ';'");
else if (intf_list_class == INTF_LIST_CLASS_GENERIC)
emit(SYNTAX_ERROR,"GENERIC_CLAUSE, expected terminating ';'");
}
emit(END,""); /* PORT_CLAUSE or GENERIC_CLAUSE */
return; /* if not SYNTAX_ERROR */
As seen in the above code the descision to process another inteface object declaration is made when encountering a semicolon. If a right parenthesis is found instead the interface list is finished (and you subsequently require a semicolon for closing the port declaration).
With the change you now require a further token look ahead to determine whether the next token following a semicolon is a right parenthesis or something else (discounting comments which are not delivered to the parser).
Requiring the look ahead can imply either a token stack, returning the token (presumably either a reserved word or an identifier) for an entry point that fetches a new token or an additional entry point (which isn't reflected in the EBNF).
In any event there's a requirement to change parser structure to accomidate the changed syntax adding a superfluous semicolon. And yes I recognize that it's possible to use an LALR(k) parser to traverse a VHDL description. The point is that a priori (presumably, the above code is from my -1993 parser) there wasn't a requirement to change parser architecture. (And in my parser I don't have a peek or token put back I actually use predicate tests implied in the EBNF. I do have that ability peek ahead in the lexer. In this case the parser would require a new entry point (a label) because I use those evil goto statements and I'd need to go around a token fetch.)
For someone implementing a minimal LALR(1) parser you could be forcing them to change the fundamental tool used to create the parser or rewrite their parser for this one superfluous semicolon. And the point of all this is that tool vendors should be involved in these feature changes. The likelihood of feature uptake may hang in the balance.
--
GerdEhlers - 2016-08-01 Parser programmers may evaluate if other syntax variants are better to implement.
Alternative 2, change these:
port_list ::= port_interface_list
generic_list ::= generic_interface_list
formal_parameter_list ::= parameter_interface_list
to:
port_list ::= port_interface_list [;]
generic_list ::= generic_interface_list [;]
formal_parameter_list ::= parameter_interface_list [;]
Alternative 3, change these:
port_clause ::= PORT ( port_list ) ;
generic_clause ::= GENERIC ( generic_list ) ;
subprogram_specification ::= PROCEDURE designator [ ( formal_parameter_list ) ]
| [ PURE | IMPURE ] FUNCTION designator [ ( formal_parameter_list ) ]
RETURN type_mark
to:
port_clause ::= PORT ( port_list [;] ) ;
generic_clause ::= GENERIC ( generic_list [;] ) ;
subprogram_specification ::= PROCEDURE designator [ ( formal_parameter_list [;] ) ]
| [ PURE | IMPURE ] FUNCTION designator [ ( formal_parameter_list [;] ) ]
RETURN type_mark
Supporters
Add your signature here to indicate your support for the proposal
-- JimLewis - 2014-12-04
--
MortenZilmer - 2015-01-21
--
ErnstChristen - 2015-01-21
--
RobGaddi - 2015-02-02
--
LievenLemiengre - 2015-06-04
--
GerdEhlers - 2016-08-01
--
HendrikEeckhaut - 2016-10-08
--
JakkoVerhallen - 2016-12-13