I am in the trying to translate a VHDL BNF defined here to a labeled BNF to use with BNFC
After running bnfc vhdl93-bnf.cf
the result is:
bnfc: user error (syntax error at line 22 before { , element_association })
I am not sure what the error is. I have been through the docs for BNFC and LBNF-report but I must have missed something.
Here is what I have so far:
rules abstract_literal ::= decimal_literal | based_literal ;
rules access_type_definition ::= "ACCESS" subtype_indication ;
rules actual_designator ::=
expression
| signal_name
| variable_name
| file_name
| "OPEN" ;
rules actual_parameter_part ::= parameter_association_list ;
rules actual_part ::=
actual_designator
| function_name "(" actual_designator ")"
| type_mark "(" actual_designator ")" ;
rules adding_operator ::= "+" | "-" | "&" ;
rules aggregate ::=
"(" element_association { "," element_association } ")"
rules alias_declaration ::=
"ALIAS" alias_designator [ ":" subtype_indication ] "IS" name [ signature ] ";" ;
rules alias_designator ::= identifier | character_literal | operator_symbol ;
rules allocator ::=
"NEW" subtype_indication
| "NEW" qualified_expression ;
rules architecture_body ::=
"ARCHITECTURE" identifier "OF" entity_name "IS"
architecture_declarative_part
"BEGIN"
architecture_statement_part
"END" [ "ARCHITECTURE" ] [ architecture_simple_name ] ";"
rules architecture_declarative_part ::=
{ block_declarative_item }
rules architecture_statement_part ::=
{ concurrent_statement }
rules array_type_definition ::=
unconstrained_array_definition | constrained_array_definition
rules assertion ::=
"ASSERT" condition
[ "REPORT" expression ]
[ "SEVERITY" expression ]
rules assertion_statement ::= [ label ":" ] assertion ";"
rules association_element ::=
[ formal_part "=>" ] actual_part
rules association_list ::=
association_element { "," association_element }
rules attribute_declaration ::=
"ATTRIBUTE" identifier ":" type_mark ";"
rules attribute_designator ::= attribute_simple_name
rules attribute_name ::=
prefix [ signature ] ' attribute_designator [ "(" expression ")" ]
rules attribute_specification ::=
"ATTRIBUTE" attribute_designator "OF" entity_specification "IS" expression ";"
rules base ::= integer
rules base_specifier ::= "B" | "O" | "X"
rules base_unit_declaration ::= identifier ";"
rules based_integer ::=
extended_digit { [ underline ] extended_digit }
rules based_literal ::=
base "#" based_integer [ . based_integer ] "#" [ exponent ]
rules basic_character ::=
basic_graphic_character | format_effector
rules basic_graphic_character ::=
upper_case_letter | digit | special_character| space_character
rules basic_identifier ::=
letter { [ underline ] letter_or_digit }
rules binding_indication ::=
[ "USE" entity_aspect ]
[ generic_map_aspect ]
[ port_map_aspect ]
rules bit_string_literal ::= base_specifier " bit_value "
rules bit_value ::= extended_digit { [ underline ] extended_digit }
rules block_configuration ::=
"FOR" block_specification
{ use_clause }
{ configuration_item }
"END" "FOR" ";"
rules block_declarative_item ::=
subprogram_declaration
| subprogram_body
| type_declaration
| subtype_declaration
| constant_declaration
| signal_declaration
| shared_variable_declaration
| file_declaration
| alias_declaration
| component_declaration
| attribute_declaration
| attribute_specification
| configuration_specification
| disconnection_specification
| use_clause
| group_template_declaration
| group_declaration
rules block_declarative_part ::=
{ block_declarative_item }
rules block_header ::=
[ generic_clause
[ generic_map_aspect ";" ] ]
[ port_clause
[ port_map_aspect ";" ] ]
rules block_specification ::=
architecture_name
| block_statement_label
| generate_statement_label [ "(" index_specification ")" ]
rules block_statement ::=
block_label :
"BLOCK" [ "(" guard_expression ")" ] [ "IS" ]
block_header
block_declarative_part
"BEGIN"
block_statement_part
"END" "BLOCK" [ block_label ] ";"
rules block_statement_part ::=
{ concurrent_statement }
rules case_statement ::=
[ case_label ":" ]
"CASE" expression "IS"
case_statement_alternative
{ case_statement_alternative }
"END" "CASE" [ case_label ] ";"
rules case_statement_alternative ::=
"WHEN" choices "=>"
sequence_of_statements
rules character_literal ::= ' graphic_character '
rules choice ::=
simple_expression
| discrete_range
| element_simple_name
| "OTHERS"
rules choices ::= choice { | choice }
rules component_configuration ::=
"FOR" component_specification
[ binding_indication ";" ]
[ block_configuration ]
"END" "FOR" ";"
rules component_declaration ::=
"COMPONENT" identifier [ "IS" ]
[ local_generic_clause ]
[ local_port_clause ]
"END" "COMPONENT" [ component_simple_name ] ";"
rules component_instantiation_statement ::=
instantiation_label :
instantiated_unit
[ generic_map_aspect ]
[ port_map_aspect ] ";"
rules component_specification ::=
instantiation_list ":" component_name
rules composite_type_definition ::=
array_type_definition
| record_type_definition
rules concurrent_assertion_statement ::=
[ label ":" ] [ "POSTPONED" ] assertion ";"
rules concurrent_procedure_call_statement ::=
[ label ":" ] [ "POSTPONED" ] procedure_call ";"
rules concurrent_signal_assignment_statement ::=
[ label ":" ] [ "POSTPONED" ] conditional_signal_assignment
| [ label ":" ] [ "POSTPONED" ] selected_signal_assignment
rules concurrent_statement ::=
block_statement
| process_statement
| concurrent_procedure_call_statement
| concurrent_assertion_statement
| concurrent_signal_assignment_statement
| component_instantiation_statement
| generate_statement
rules condition ::= boolean_expression
rules condition_clause ::= "UNTIL" condition
rules conditional_signal_assignment ::=
target <= options conditional_waveforms ";"
rules conditional_waveforms ::=
{ waveform "WHEN" condition "ELSE" }
waveform [ "WHEN" condition ]
rules configuration_declaration ::=
"CONFIGURATION" identifier "OF" entity_name "IS"
configuration_declarative_part
block_configuration
"END" [ "CONFIGURATION" ] [ configuration_simple_name ] ";"
rules configuration_declarative_item ::=
use_clause
| attribute_specification
| group_declaration
rules configuration_declarative_part ::=
{ configuration_declarative_item }
rules configuration_item ::=
block_configuration
| component_configuration
rules configuration_specification ::=
"FOR" component_specification binding_indication ";"
rules constant_declaration ::=
"CONSTANT" identifier_list ":" subtype_indication [ := expression ] ";"
rules constrained_array_definition ::=
"ARRAY" index_constraint "OF" element_subtype_indication
rules constraint ::=
range_constraint
| index_constraint
rules context_clause ::= { context_item }
rules context_item ::=
library_clause
| use_clause
rules decimal_literal ::= integer [ . integer ] [ exponent ]
rules declaration ::=
type_declaration
| subtype_declaration
| object_declaration
| interface_declaration
| alias_declaration
| attribute_declaration
| component_declaration
| group_template_declaration
| group_declaration
| entity_declaration
| configuration_declaration
| subprogram_declaration
| package_declaration
rules delay_mechanism ::=
"TRANSPORT"
| [ "REJECT" time_expression ] "INERTIAL"
rules design_file ::= design_unit { design_unit }
rules design_unit ::= context_clause library_unit
rules designator ::= identifier | operator_symbol
rules direction ::= "TO" | "DOWNTO"
rules disconnection_specification ::=
"DISCONNECT" guarded_signal_specification "AFTER" time_expression ";"
rules discrete_range ::= discrete_subtype_indication | range
rules element_association ::=
[ choices "=>" ] expression
rules element_declaration ::=
identifier_list ":" element_subtype_definition ";"
rules element_subtype_definition ::= subtype_indication
rules entity_aspect ::=
"ENTITY" entity_name [ "(" architecture_identifier")" ]
| "CONFIGURATION" configuration_name
| "OPEN"
rules entity_class ::=
"ENTITY" | "ARCHITECTURE" | "CONFIGURATION"
| "PROCEDURE" | "FUNCTION" | "PACKAGE"
| "TYPE" | "SUBTYPE" | "CONSTANT"
| "SIGNAL" | "VARIABLE" | "COMPONENT"
| "LABEL" | "LITERAL" | "UNITS"
| "GROUP" | "FILE"
rules entity_class_entry ::= entity_class [ <> ]
rules entity_class_entry_list ::=
entity_class_entry { "," entity_class_entry }
rules entity_declaration ::=
"ENTITY" identifier "IS"
entity_header
entity_declarative_part
[ "BEGIN"
entity_statement_part ]
"END" [ "ENTITY" ] [ entity_simple_name ] ";"
rules entity_declarative_item ::=
subprogram_declaration
| subprogram_body
| type_declaration
| subtype_declaration
| constant_declaration
| signal_declaration
| shared_variable_declaration
| file_declaration
| alias_declaration
| attribute_declaration
| attribute_specification
| disconnection_specification
| use_clause
| group_template_declaration
| group_declaration
rules entity_declarative_part ::=
{ entity_declarative_item }
rules entity_designator ::= entity_tag [ signature ]
rules entity_header ::=
[ formal_generic_clause ]
[ formal_port_clause ]
rules entity_name_list ::=
entity_designator { "," entity_designator }
| "OTHERS"
| "ALL"
rules entity_specification ::=
entity_name_list ":" entity_class
rules entity_statement ::=
concurrent_assertion_statement
| passive_concurrent_procedure_call_statement
| passive_process_statement
rules entity_statement_part ::=
{ entity_statement }
rules entity_tag ::= simple_name | character_literal | operator_symbol
rules enumeration_literal ::= identifier | character_literal
rules enumeration_type_definition ::=
"(" enumeration_literal { "," enumeration_literal } ")"
rules exit_statement ::=
[ label ":" ] "EXIT" [ loop_label ] [ "WHEN" condition ] ";"
rules exponent ::= "E" [ "+" ] integer | "E" "-" integer
rules expression ::=
relation { "AND" relation }
| relation { "OR" relation }
| relation { "XOR" relation }
| relation [ "NAND" relation ]
| relation [ "NOR" relation ]
| relation { "XNOR" relation }
rules extended_digit ::= digit | letter
rules extended_identifier ::=
\ graphic_character { graphic_character } \
rules factor ::=
primary [ "**" primary ]
| "ABS" primary
| "NOT" primary
rules file_declaration ::=
"FILE" identifier_list ":" subtype_indication file_open_information ] ";"
rules file_logical_name ::= string_expression
rules file_open_information ::=
[ "OPEN" file_open_kind_expression ] "IS" file_logical_name
rules file_type_definition ::=
"FILE" "OF" type_mark
rules floating_type_definition ::= range_constraint
rules formal_designator ::=
generic_name
| port_name
| parameter_name
rules formal_parameter_list ::= parameter_interface_list
rules formal_part ::=
formal_designator
| function_name "(" formal_designator ")"
| type_mark "(" formal_designator ")"
rules full_type_declaration ::=
"TYPE" identifier "IS" type_definition ";"
rules function_call ::=
function_name [ "(" actual_parameter_part ")" ]
rules generate_statement ::=
generate_label :
generation_scheme "GENERATE"
[ { block_declarative_item }
"BEGIN" ]
{ concurrent_statement }
"END" "GENERATE" [ generate_label ] ";"
rules generation_scheme ::=
"FOR" generate_parameter_specification
| "IF" condition
rules generic_clause ::=
"GENERIC" "(" generic_list ")" ";"
rules generic_list ::= generic_interface_list
rules generic_map_aspect ::=
"GENERIC" "MAP" "(" generic_association_list ")"
rules graphic_character ::=
basic_graphic_character | lower_case_letter | other_special_character
rules group_constituent ::= name | character_literal
rules group_constituent_list ::= group_constituent { "," group_constituent }
rules group_template_declaration ::=
"GROUP" identifier "IS" "(" entity_class_entry_list ")" ";"
rules group_declaration ::=
"GROUP" identifier ":" group_template_name "(" group_constituent_list ")" ";"
rules guarded_signal_specification ::=
guarded_signal_list ":" type_mark
rules identifier ::=
basic_identifier | extended_identifier
rules identifier_list ::= identifier { "," identifier }
rules if_statement ::=
[ if_label ":" ]
"IF" condition "THEN"
sequence_of_statements
{ "ELSIF" condition "THEN"
sequence_of_statements }
[ "ELSE"
sequence_of_statements ]
"END" "IF" [ if_label ] ";"
rules incomplete_type_declaration ::= "TYPE" identifier ";"
rules index_constraint ::= "(" discrete_range { "," discrete_range } ")"
rules index_specification ::=
discrete_range
| static_expression
rules index_subtype_definition ::= type_mark range <>
rules indexed_name ::= prefix "(" expression { "," expression } ")"
rules instantiated_unit ::=
[ "COMPONENT" ] component_name
| "ENTITY" entity_name [ "(" architecture_identifier ")" ]
| "CONFIGURATION" configuration_name
rules instantiation_list ::=
instantiation_label { "," instantiation_label }
| "OTHERS"
| "ALL"
rules integer ::= digit { [ underline ] digit }
rules integer_type_definition ::= range_constraint
rules interface_constant_declaration ::=
[ "CONSTANT" ] identifier_list ":" [ "IN" ] subtype_indication [ := static_expression ]
rules interface_declaration ::=
interface_constant_declaration
| interface_signal_declaration
| interface_variable_declaration
| interface_file_declaration
rules interface_element ::= interface_declaration
rules interface_file_declaration ::=
"FILE" identifier_list ":" subtype_indication
rules interface_list ::=
interface_element { ";" interface_element }
rules interface_signal_declaration ::=
["SIGNAL"] identifier_list ":" [ mode ] subtype_indication [ "BUS" ] [ := static_expression ]
rules interface_variable_declaration ::=
["VARIABLE"] identifier_list ":" [ mode ] subtype_indication [ := static_expression ]
rules iteration_scheme ::=
"WHILE" condition
| "FOR" loop_parameter_specification
rules label ::= identifier
rules letter ::= upper_case_letter | lower_case_letter
rules letter_or_digit ::= letter | digit
rules library_clause ::= "LIBRARY" logical_name_list ";"
rules library_unit ::=
primary_unit
| secondary_unit
rules literal ::=
numeric_literal
| enumeration_literal
| string_literal
| bit_string_literal
| "NULL"
rules logical_name ::= identifier
rules logical_name_list ::= logical_name { "," logical_name }
rules logical_operator ::= "AND" | "OR" | "NAND" | "NOR" | "XOR" | "XNOR"
rules loop_statement ::=
[ loop_label ":" ]
[ iteration_scheme ] "LOOP"
sequence_of_statements
"END" "LOOP" [ loop_label ] ";"
rules miscellaneous_operator ::= "**" | "ABS" | "NOT"
rules mode ::= "IN" | "OUT" | "INOUT" | "BUFFER" | "LINKAGE"
rules multiplying_operator ::= * | "/" | "MOD" | "REM"
rules name ::=
simple_name
| operator_symbol
| selected_name
| indexed_name
| slice_name
| attribute_name
rules next_statement ::=
[ label ":" ] "NEXT" [ loop_label ] [ "WHEN" condition ] ";"
rules null_statement ::= [ label ":" ] "NULL" ";"
rules numeric_literal ::=
abstract_literal
| physical_literal
rules object_declaration ::=
constant_declaration
| signal_declaration
| variable_declaration
| file_declaration
rules operator_symbol ::= string_literal
rules options ::= [ "GUARDED" ] [ delay_mechanism ]
rules package_body ::=
"PACKAGE" body package_simple_name "IS"
package_body_declarative_part
"END" [ "PACKAGE" "BODY" ] [ package_simple_name ] ";"
rules package_body_declarative_item ::=
subprogram_declaration
| subprogram_body
| type_declaration
| subtype_declaration
| constant_declaration
| shared_variable_declaration
| file_declaration
| alias_declaration
| use_clause
| group_template_declaration
| group_declaration
rules package_body_declarative_part ::=
{ package_body_declarative_item }
rules package_declaration ::=
"PACKAGE" identifier "IS"
package_declarative_part
"END" [ "PACKAGE" ] [ package_simple_name ] ";"
rules package_declarative_item ::=
subprogram_declaration
| type_declaration
| subtype_declaration
| constant_declaration
| signal_declaration
| shared_variable_declaration
| file_declaration
| alias_declaration
| component_declaration
| attribute_declaration
| attribute_specification
| disconnection_specification
| use_clause
| group_template_declaration
| group_declaration
rules package_declarative_part ::=
{ package_declarative_item }
rules parameter_specification ::=
identifier "IN" discrete_range
rules physical_literal ::= [ abstract_literal ] unit_name
rules physical_type_definition ::=
range_constraint
"UNITS"
base_unit_declaration
{ secondary_unit_declaration }
"END" "UNITS" [ physical_type_simple_name ]
rules port_clause ::=
"PORT" "(" port_list ")" ";"
rules port_list ::= port_interface_list
rules port_map_aspect ::=
"PORT" "MAP" "(" port_association_list ")"
rules prefix ::=
name
| function_call
rules primary ::=
name
| literal
| aggregate
| function_call
| qualified_expression
| type_conversion
| allocator
| "(" expression ")"
rules primary_unit ::=
entity_declaration
| configuration_declaration
| package_declaration
rules procedure_call ::= procedure_name [ "(" actual_parameter_part ")" ]
rules procedure_call_statement ::=
[ label ":" ] procedure_call ";"
rules process_declarative_item ::=
subprogram_declaration
| subprogram_body
| type_declaration
| subtype_declaration
| constant_declaration
| variable_declaration
| file_declaration
| alias_declaration
| attribute_declaration
| attribute_specification
| use_clause
| group_template_declaration
| group_declaration
rules process_declarative_part ::=
{ process_declarative_item }
rules process_statement ::=
[ process_label ":" ]
[ "POSTPONED" ] "PROCESS" [ "(" sensitivity_list ")" ] [ "IS" ]
process_declarative_part
"BEGIN"
process_statement_part
"END" [ "POSTPONED" ] "PROCESS" [ process_label ] ";"
rules process_statement_part ::=
{ sequential_statement }
rules qualified_expression ::=
type_mark ' "(" expression ")"
| type_mark ' aggregate
rules range ::=
range_attribute_name
| simple_expression direction simple_expression
rules range_constraint ::= range range
rules record_type_definition ::=
"RECORD"
element_declaration
{ element_declaration }
"END" "RECORD" [ record_type_simple_name ]
rules relation ::=
shift_expression [ relational_operator shift_expression ]
rules relational_operator ::= = | "/"= | < | <= | > | >=
rules report_statement ::=
[ label ":" ]
"REPORT" expression
[ "SEVERITY" expression ] ";"
rules return_statement ::=
[ label ":" ] "RETURN" [ expression ] ";"
rules scalar_type_definition ::=
enumeration_type_definition | integer_type_definition
| floating_type_definition | physical_type_definition
rules secondary_unit ::=
architecture_body
| package_body
rules secondary_unit_declaration ::= identifier = physical_literal ";"
rules selected_name ::= prefix . suffix
rules selected_signal_assignment ::=
"WITH" expression "SELECT"
target <= options selected_waveforms ";"
rules selected_waveforms ::=
{ waveform "WHEN" choices "," }
waveform "WHEN" choices
rules sensitivity_clause ::= "ON" sensitivity_list
rules sensitivity_list ::= signal_name { "," signal_name }
rules sequence_of_statements ::=
{ sequential_statement }
rules sequential_statement ::=
wait_statement
| assertion_statement
| report_statement
| signal_assignment_statement
| variable_assignment_statement
| procedure_call_statement
| if_statement
| case_statement
| loop_statement
| next_statement
| exit_statement
| return_statement
| null_statement
rules shift_expression ::=
simple_expression [ shift_operator simple_expression ]
rules shift_operator ::= "SLL" | "SRL" | "SLA" | "SRA" | "ROL" | "ROR"
rules sign ::= "+" | "-"
rules signal_assignment_statement ::=
[ label ":" ] target <= [ delay_mechanism ] waveform ";"
rules signal_declaration ::=
signal identifier_list ":" subtype_indication [ signal_kind ] [ := expression ] ";"
rules signal_kind ::= "REGISTER" | "BUS"
rules signal_list ::=
signal_name { "," signal_name }
| "OTHERS"
| "ALL"
rules signature ::= [ [ type_mark { "," type_mark } ] [ return type_mark ] ]
rules simple_expression ::=
[ sign ] term { adding_operator term }
rules simple_name ::= identifier
rules slice_name ::= prefix "(" discrete_range ")"
rules string_literal ::= " { graphic_character } "
rules subprogram_body ::=
subprogram_specification "IS"
subprogram_declarative_part
"BEGIN"
subprogram_statement_part
"END" [ subprogram_kind ] [ designator ] ";"
rules subprogram_declaration ::=
subprogram_specification ";"
rules subprogram_declarative_item ::=
subprogram_declaration
| subprogram_body
| type_declaration
| subtype_declaration
| constant_declaration
| variable_declaration
| file_declaration
| alias_declaration
| attribute_declaration
| attribute_specification
| use_clause
| group_template_declaration
| group_declaration
rules subprogram_declarative_part ::=
{ subprogram_declarative_item }
rules subprogram_kind ::= "PROCEDURE" | "FUNCTION"
rules subprogram_specification ::=
"PROCEDURE" designator [ "(" formal_parameter_list ")" ]
| [ "PURE" | "IMPURE" ] "FUNCTION" designator [ "(" formal_parameter_list ")" ]
"RETURN" type_mark
rules subprogram_statement_part ::=
{ sequential_statement }
rules subtype_declaration ::=
"SUBTYPE" identifier "IS" subtype_indication ";"
rules subtype_indication ::=
[ resolution_function_name ] type_mark [ constraint ]
rules suffix ::=
simple_name
| character_literal
| operator_symbol
| "ALL"
rules target ::=
name
| aggregate
rules term ::=
factor { multiplying_operator factor }
rules timeout_clause ::= "FOR" time_expression
rules type_conversion ::= type_mark "(" expression ")"
rules type_declaration ::=
full_type_declaration
| incomplete_type_declaration
rules type_definition ::=
scalar_type_definition
| composite_type_definition
| access_type_definition
| file_type_definition
rules type_mark ::=
type_name
| subtype_name
rules unconstrained_array_definition ::=
"ARRAY" "(" index_subtype_definition { "," index_subtype_definition } ")"
"OF" element_subtype_indication
rules use_clause ::=
"USE" selected_name { "," selected_name } ";"
rules variable_assignment_statement ::=
[ label ":" ] target := expression ";"
rules variable_declaration ::=
[ "SHARED" ] "VARIABLE" identifier_list ":" subtype_indication [ := expression ] ";"
rules wait_statement ::=
[ label ":" ] "WAIT" [ sensitivity_clause ] [ condition_clause ] [ timeout_clause ] ";"
rules waveform ::=
waveform_element { "," waveform_element }
| "UNAFFECTED"
rules waveform_element ::=
value_expression [ "AFTER" time_expression ]
| "NULL" [ "AFTER" time_expression ]
I see at least two problems in the grammar:
[...]
in LBNF is used to denote a repetition, so [A]
is "a list of A
". It takes a single category and you need to define a terminator or separator (or write the list rules yourself). E.g.
Foo. Foo ::= [Bar];
separator Bar ",";
But ["abc"]
or [Foo Bar]
are both invalid.{...}
is not a valid construction in LBNF rules.If you want to indicate that an element is optional, you need to write the different cases. E.g.:
rules FooOptionalBar ::= Foo Bar | Foo;
or
rules FooOptionalBar ::= Foo OptionalBar;
rules OptionalBar ::= Bar | ;