LALR grammar for revised Ada
David Norris
david at ssc-vax.UUCP
Fri Dec 2 09:58:04 AEST 1983
This is an LALR(1) grammar for ANSI standard Ada, acceptable by the
Yacc compiler-compiler under Unix. It is based on a grammar for preliminary
Ada from an article in the ACM Sigplan Notices (see below), and updated by
me to conform to the new standard. I am submitting it to the net for public
use; any comments or suggestions (or mistakes) would be appreciated. I have
a lexical analyzer (also in C) which accompanies the parser generated by this
grammar, if anyone is interested. The addition of error-recovery routines
would make this a good Ada syntax-checker or the start of a full compiler.
-- Dave Norris
-- ..!uw-beaver!ssc-vax!david
/*
An LALR(1) Grammar for (Revised) MIL-STD-1815A Ada
original work done by
Persch, Winterstein, Drossopoulou, and Dausmann
Universitat Karlsruhe, D-7500 Karlsruhe 1
adapted to MIL-STD-1815A by
David C. Norris
October, 1983
From an original paper in the ACM Sigplan Notices
Volume 16, Number 3, March 1981, Page 85
The following is an LALR(1) grammar for the ANSI standard
Ada language, acceptable to the YACC compiler-compiler
under the UNIX operating system. The grammar produces
one shift-reduce conflict (attribute) which is properly
resolved by Yacc's disambiguating rules (shifted).
The tokens accepted by the parser are those which a
typical lexical analyzer might produce.
*/
%start compilation
/* Define as tokens the literals */
%token IDENTIFIER NUMERIC_LITERAL STRING_LITERAL CHARACTER_LITERAL
/* Define as tokens the Ada keywords */
%token ABORT ABS ACCEPT ACCESS ALL AND ARRAY AT
%token BEGIN BODY
%token CASE CONSTANT
%token DECLARE DELAY DELTA DIGITS DO
%token ELSE ELSIF END ENTRY EXCEPTION EXIT
%token FOR FUNCTION
%token GENERIC GOTO
%token IF IN IS
%token LIMITED LOOP
%token MOD
%token NEW NOT NULL
%token OF OR OTHERS OUT
%token PACKAGE PRAGMA PRIVATE PROCEDURE
%token RAISE RANGE RECORD REM RENAMES RETURN REVERSE
%token SELECT SEPARATE SUBTYPE
%token TASK TERMINATE THEN TYPE
%token USE
%token WHEN WHILE WITH
%token XOR
/* Define as tokens the special symbols */
%token ELLIPSIS LEFT_PAREN RIGHT_PAREN COMMA COLON SEMICOLON
%token BOX PERIOD QUOTE EQUAL_TO NOT_EQUAL_TO GREATER_THAN
%token GREATER_EQUAL LESS_THAN LESS_EQUAL PLUS MINUS AMPERSAND SPLAT
%token SLASH DOUBLE_STAR LEFT_LABEL RIGHT_LABEL REPLACEMENT ARROW BAR
%%
pragma : PRAGMA IDENTIFIER SEMICOLON
| PRAGMA IDENTIFIER LEFT_PAREN argument_list RIGHT_PAREN SEMICOLON ;
argument_list : argument
| argument_list COMMA argument ;
/* expression can also be a name */
argument : expression
| IDENTIFIER ARROW expression ;
/* pragmas allowed in declarationive part */
basic_declaration :
object_declaration | number_declaration
| type_declaration | subtype_declaration
| subprogram_declaration | package_declaration
| task_declaration | generic_declaration
| exception_declaration | generic_instantiation
| renaming_declaration | pragma ;
/* deferred_constant_declaration is in here */
object_declaration :
IDENTIFIER COLON subtype_indication
initialization_option SEMICOLON
| IDENTIFIER COLON CONSTANT subtype_indication
initialization_option SEMICOLON
| IDENTIFIER COLON constrained_array_definition
initialization_option SEMICOLON
| IDENTIFIER COLON CONSTANT constrained_array_definition
initialization_option SEMICOLON
| identifier_list2 COLON subtype_indication
initialization_option SEMICOLON
| identifier_list2 COLON CONSTANT subtype_indication
initialization_option SEMICOLON
| identifier_list2 COLON constrained_array_definition
initialization_option SEMICOLON
| identifier_list2 COLON CONSTANT constrained_array_definition
initialization_option SEMICOLON ;
initialization_option : | REPLACEMENT expression ;
number_declaration :
IDENTIFIER COLON CONSTANT REPLACEMENT expression SEMICOLON
| identifier_list2 COLON CONSTANT REPLACEMENT expression SEMICOLON ;
identifier_list2 : IDENTIFIER COMMA IDENTIFIER
| identifier_list2 COMMA IDENTIFIER ;
/* type_definition includes private_type */
type_declaration :
TYPE IDENTIFIER discriminant_part_option IS type_definition SEMICOLON
| incomplete_type_declaration ;
discriminant_part_option : | discriminant_part ;
type_definition : enumeration_type_definition | integer_type_definition
| real_type_definition | array_type_definition
| record_type_definition | access_type_definition
| derived_type_definition | private_type_definition ;
subtype_declaration : SUBTYPE IDENTIFIER IS subtype_indication SEMICOLON ;
subtype_indication : name | subtype_indication_with_constraint ;
/* index_constraint, discriminant_constraint are in name */
subtype_indication_with_constraint : name range_constraint
| name floating_point_constraint
| name fixed_point_constraint ;
derived_type_definition : NEW subtype_indication ;
range_constraint : RANGE range ;
range : simple_expression ELLIPSIS simple_expression
| name QUOTE RANGE
| name QUOTE RANGE LEFT_PAREN expression RIGHT_PAREN ;
enumeration_type_definition : LEFT_PAREN enumeration_literal_list RIGHT_PAREN ;
enumeration_literal_list : enumeration_literal
| enumeration_literal_list COMMA enumeration_literal ;
enumeration_literal : IDENTIFIER | CHARACTER_LITERAL ;
integer_type_definition : range_constraint ;
real_type_definition : floating_point_constraint | fixed_point_constraint ;
floating_point_constraint : DIGITS simple_expression range_constraint_option ;
range_constraint_option : | range_constraint ;
fixed_point_constraint : DELTA simple_expression range_constraint_option ;
array_type_definition : unconstrained_array_definition
| constrained_array_definition ;
unconstrained_array_definition :
ARRAY LEFT_PAREN index_list RIGHT_PAREN OF subtype_indication
constrained_array_definition :
ARRAY index_constraint OF subtype_indication
index_list : index_subtype_definition
| index_list COMMA index_subtype_definition ;
index_subtype_definition : name RANGE BOX ;
index_constraint : LEFT_PAREN discrete_range_list RIGHT_PAREN ;
discrete_range_list : discrete_range
| discrete_range_list COMMA discrete_range ;
discrete_range : subtype_indication | range ;
record_type_definition : RECORD component_list END RECORD ;
component_list : component_declaration_list0 component_declaration
| component_declaration_list0 variant_part
| NULL ;
component_declaration_list0 :
| component_declaration_list0 component_declaration ;
component_declaration :
IDENTIFIER COLON subtype_indication initialization_option SEMICOLON
| identifier_list2 COLON subtype_indication initialization_option SEMICOLON ;
discriminant_part : LEFT_PAREN discriminant_specification_list RIGHT_PAREN ;
discriminant_specification_list :
discriminant_specification
| discriminant_specification_list SEMICOLON discriminant_specification ;
discriminant_specification :
IDENTIFIER COLON name initialization_option
| identifier_list2 COLON name initialization_option ;
variant_part : CASE IDENTIFIER IS variant_list1 END CASE SEMICOLON ;
variant_list1 : WHEN choice_list ARROW component_list
| variant_list1 WHEN choice_list ARROW component_list ;
/* simple_expression can be simple_name */
/* "name range_constraint" and "range" substitutes for discrete_range */
/* choice OTHERS must stand by itself, so is not included in choice_list */
choice : simple_expression | name range_constraint | range ;
choice_list : OTHERS
| choice_list1 ;
choice_list1 : choice | choice_list BAR choice ;
access_type_definition : ACCESS subtype_indication ;
incomplete_type_declaration :
TYPE IDENTIFIER discriminant_part_option SEMICOLON ;
/* "body" separates basic_items from later_items */
declarative_part :
basic_declarative_item_list0
| basic_declarative_item_list0 body later_declarative_item_list0 ;
basic_declarative_item_list0 :
| basic_declarative_item_list0 basic_declaration
| basic_declarative_item_list0 representation_clause
| basic_declarative_item_list0 use_clause ;
body : proper_body | body_stub ;
later_declarative_item_list0 :
| later_declarative_item_list0 body
| later_declarative_item_list0 subprogram_declaration
| later_declarative_item_list0 package_declaration
| later_declarative_item_list0 task_declaration
| later_declarative_item_list0 generic_declaration
| later_declarative_item_list0 use_clause
| later_declarative_item_list0 generic_instantiation ;
proper_body : subprogram_body | package_body | task_body ;
/* "indexed_component" substitutes for slice */
/* operator_symbol substitutes for string_literal in primary */
name : IDENTIFIER | CHARACTER_LITERAL | operator_symbol
| indexed_component | selected_component | attribute ;
/* "indexed_component" covers:
indexed_components
slices
function_calls
name index_constraint (in subtype_indication)
name discriminant_constraint (in subtype_indication)
procedure_calls
type_conversion
subtype_indication (in allocator)
*/
indexed_component : name LEFT_PAREN generalized_expression_list RIGHT_PAREN ;
generalized_expression_list :
generalized_expression
| generalized_expression_list COMMA generalized_expression ;
generalized_expression : expression
| range
| subtype_indication_with_constraint
| choice_list ARROW expression
| choice_list ARROW subtype_indication_with_constraint ;
selected_component : name PERIOD IDENTIFIER
| name PERIOD ALL
| name PERIOD operator_symbol
| name PERIOD CHARACTER_LITERAL ;
/* shift-reduce conflict here properly resolved (shifted) */
attribute : name QUOTE IDENTIFIER
| name QUOTE DELTA
| name QUOTE DIGITS
| name QUOTE IDENTIFIER LEFT_PAREN expression RIGHT_PAREN ;
/* aggregate must have 2 component associations or have choices
with an arrow to distinguish from "(expression)" */
aggregate : LEFT_PAREN component_association_list2 RIGHT_PAREN
| LEFT_PAREN choice_list ARROW expression RIGHT_PAREN ;
component_association_list2 :
component_association COMMA component_association
| component_association_list2 COMMA component_association ;
component_association : expression | choice_list ARROW expression ;
expression : relation
| and_expression
| or_expression
| xor_expression
| andthen_expression
| orelse_expression ;
and_expression : relation AND relation
| and_expression AND relation ;
or_expression : relation OR relation
| or_expression OR relation ;
xor_expression : relation XOR relation
| xor_expression XOR relation ;
andthen_expression : relation AND THEN relation
| andthen_expression AND THEN relation ;
orelse_expression : relation OR ELSE relation
| orelse_expression OR ELSE relation ;
relation : simple_expression
| simple_expression relational_operator simple_expression
| simple_expression membership_operator range
| simple_expression membership_operator name ;
membership_operator : IN | NOT IN ;
simple_expression : term_list
| unary_adding_operator term_list ;
term_list : term
| term_list binary_adding_operator term ;
term : factor
| term multiplying_operator factor ;
factor : primary
| primary DOUBLE_STAR primary
| ABS primary
| NOT primary ;
/* string_literal can be name (operator_symbol) */
/* function_call is name (indexed_component) */
/* type_conversion is name (indexed_component) */
primary : NUMERIC_LITERAL | NULL | aggregate
| name | allocator | qualified_expression
| LEFT_PAREN expression RIGHT_PAREN ;
relational_operator : EQUAL_TO | NOT_EQUAL_TO
| GREATER_THAN | GREATER_EQUAL
| LESS_THAN | LESS_EQUAL ;
binary_adding_operator : PLUS | MINUS | AMPERSAND ;
unary_adding_operator : PLUS | MINUS ;
multiplying_operator : SPLAT | SLASH | MOD | REM ;
qualified_expression : name QUOTE LEFT_PAREN expression RIGHT_PAREN
| name QUOTE aggregate ;
/* name can be subtype_indication (indexed_component) */
allocator : NEW name | NEW qualified_expression ;
sequence_of_statements : statement | sequence_of_statements statement ;
statement : label_list simple_statement | label_list compound_statement ;
label_list : | label_list label ;
simple_statement : null_statement | assignment_statement
| exit_statement | return_statement
| goto_statement | procedure_call_statement
| delay_statement | abort_statement
| raise_statement | code_statement ;
compound_statement : if_statement | case_statement
| loop_statement | block_statement
| accept_statement | select_statement ;
label : LEFT_LABEL IDENTIFIER RIGHT_LABEL ;
null_statement : NULL SEMICOLON ;
assignment_statement : name REPLACEMENT expression SEMICOLON ;
if_statement : IF condition THEN
sequence_of_statements
elsif_list0
else_option
END IF SEMICOLON ;
elsif_list0 : | elsif_list0 ELSIF condition THEN sequence_of_statements ;
else_option : | ELSE sequence_of_statements ;
condition : expression ;
case_statement : CASE expression IS
alternative_list1
END CASE SEMICOLON ;
alternative_list1 :
WHEN choice_list ARROW sequence_of_statements
| alternative_list1 WHEN choice_list ARROW sequence_of_statements ;
loop_statement :
iteration_clause_option basic_loop SEMICOLON
| IDENTIFIER COLON iteration_clause_option basic_loop IDENTIFIER SEMICOLON ;
basic_loop : LOOP sequence_of_statements END LOOP ;
iteration_clause_option : FOR IDENTIFIER IN discrete_range
| FOR IDENTIFIER IN REVERSE discrete_range
| WHILE condition ;
block_statement : declare_part_option
BEGIN
sequence_of_statements
exception_option
END SEMICOLON
| IDENTIFIER COLON
declare_part_option
BEGIN
sequence_of_statements
exception_option
END IDENTIFIER SEMICOLON ;
declare_part_option : | DECLARE declarative_part ;
exception_option : | EXCEPTION exception_handler_list1 ;
exception_handler_list1 : exception_handler
| exception_handler_list1 exception_handler ;
exit_statement : EXIT name_option when_option SEMICOLON ;
name_option : | name ;
when_option : | WHEN condition ;
return_statement : RETURN SEMICOLON | RETURN expression SEMICOLON ;
goto_statement : GOTO name SEMICOLON ;
subprogram_declaration : subprogram_specification SEMICOLON ;
subprogram_specification :
PROCEDURE IDENTIFIER formal_part_option
| FUNCTION designator formal_part_option RETURN name ;
subprogram_specification_is :
PROCEDURE IDENTIFIER IS
| FUNCTION designator formal_part_option RETURN name IS ;
designator : IDENTIFIER | operator_symbol ;
operator_symbol : STRING_LITERAL ;
formal_part : LEFT_PAREN parameter_specification_list RIGHT_PAREN ;
formal_part_option : | formal_part ;
parameter_specification_list :
parameter_specification
| parameter_specification_list SEMICOLON parameter_specification ;
parameter_specification :
IDENTIFIER COLON mode name initialization_option
| identifier_list2 COLON mode name initialization_option ;
mode : | IN | OUT | IN OUT ;
subprogram_body : subprogram_specification_is
declarative_part
BEGIN
sequence_of_statements
exception_option
END designator_option SEMICOLON ;
designator_option : | designator ;
procedure_call_statement : name SEMICOLON ;
package_declaration : package_specification SEMICOLON ;
package_specification : PACKAGE IDENTIFIER IS
basic_declarative_item_list0
private_part_option
END identifier_option ;
private_part_option : | PRIVATE basic_declarative_item_list0 ;
identifier_option : | IDENTIFIER ;
package_body : PACKAGE BODY IDENTIFIER IS
declarative_part
statements_option
END identifier_option SEMICOLON ;
statements_option : | BEGIN sequence_of_statements exception_option ;
private_type_definition : LIMITED PRIVATE | PRIVATE ;
use_clause : USE name_list SEMICOLON ;
name_list : name | name_list COMMA name ;
renaming_declaration : IDENTIFIER COLON name RENAMES name SEMICOLON
| IDENTIFIER COLON EXCEPTION RENAMES name SEMICOLON
| PACKAGE IDENTIFIER RENAMES name SEMICOLON
| subprogram_specification RENAMES name SEMICOLON ;
task_declaration : task_specification SEMICOLON ;
task_specification : TASK IDENTIFIER task_specifier
| TASK TYPE IDENTIFIER task_specifier ;
task_specifier :
| IS
entry_declaration_list0
representation_clause_list0
END identifier_option SEMICOLON ;
representation_clause_list0 :
| representation_clause_list0 representation_clause ;
entry_declaration_list0 : | entry_declaration_list0 entry_declaration ;
task_body : TASK BODY IDENTIFIER IS
declarative_part
BEGIN
sequence_of_statements
exception_option
END identifier_option SEMICOLON ;
entry_declaration : ENTRY IDENTIFIER formal_part_option SEMICOLON
| ENTRY IDENTIFIER LEFT_PAREN discrete_range RIGHT_PAREN
formal_part_option SEMICOLON ;
/* identical syntax as procedure_call */
entry_call_statement : procedure_call_statement ;
accept_statement :
ACCEPT IDENTIFIER formal_part_option SEMICOLON
| ACCEPT IDENTIFIER LEFT_PAREN expression RIGHT_PAREN formal_part_option
SEMICOLON
| ACCEPT IDENTIFIER formal_part_option DO
sequence_of_statements
END identifier_option SEMICOLON
| ACCEPT IDENTIFIER LEFT_PAREN expression RIGHT_PAREN formal_part_option
DO
sequence_of_statements
END identifier_option SEMICOLON ;
delay_statement : DELAY simple_expression SEMICOLON ;
select_statement : selective_wait | conditional_entry_call | timed_entry_call ;
selective_wait : SELECT
condition_option
select_alternative
select_alternative_list0
else_option
END SELECT SEMICOLON ;
select_alternative_list0 : | select_alternative_list0
OR condition_option select_alternative ;
condition_option : | WHEN condition ARROW ;
select_alternative : accept_statement sequence_of_statements_option
| delay_statement sequence_of_statements_option
| TERMINATE SEMICOLON ;
sequence_of_statements_option : | sequence_of_statements ;
conditional_entry_call : SELECT
entry_call_statement sequence_of_statements_option
ELSE
sequence_of_statements
END SELECT SEMICOLON ;
timed_entry_call : SELECT
entry_call_statement sequence_of_statements_option
OR
delay_statement sequence_of_statements_option
END SELECT SEMICOLON ;
abort_statement : ABORT name_list SEMICOLON ;
compilation : compilation_list ;
compilation_list : pragma_list0 compilation_unit
| compilation_list pragma_list0 compilation_unit ;
pragma_list0 : | pragma_list0 pragma ;
compilation_unit : context_clause subprogram_declaration
| context_clause subprogram_body
| context_clause package_declaration
| context_clause package_body
| context_clause generic_declaration
| context_clause generic_instantiation
| context_clause subunit ;
context_clause : | context_clause with_clause use_clause_option ;
use_clause_option : | use_clause ;
with_clause : WITH name_list SEMICOLON ;
subunit : SEPARATE LEFT_PAREN name RIGHT_PAREN proper_body ;
body_stub : subprogram_specification_is SEPARATE SEMICOLON
| PACKAGE BODY IDENTIFIER IS SEPARATE SEMICOLON
| TASK BODY IDENTIFIER IS SEPARATE SEMICOLON ;
exception_declaration : IDENTIFIER COLON EXCEPTION SEMICOLON
| identifier_list2 COLON EXCEPTION SEMICOLON ;
exception_handler : WHEN exception_choice_list ARROW sequence_of_statements ;
exception_choice_list : OTHERS
| exception_choice_list1 ;
exception_choice_list1 : name | exception_choice_list1 BAR name ;
raise_statement : RAISE name_option SEMICOLON ;
generic_declaration : generic_specification SEMICOLON ;
generic_specification : generic_formal_part subprogram_specification
| generic_formal_part package_specification ;
generic_formal_part : GENERIC
| generic_formal_part generic_parameter_declaration ;
/* generic_type_definition includes private_type_definition */
generic_parameter_declaration :
parameter_specification SEMICOLON
| TYPE IDENTIFIER IS generic_type_definition SEMICOLON
| WITH subprogram_specification SEMICOLON
| WITH subprogram_specification_is name SEMICOLON
| WITH subprogram_specification_is BOX SEMICOLON ;
generic_type_definition : LEFT_PAREN BOX RIGHT_PAREN
| RANGE BOX
| DELTA BOX
| DIGITS BOX
| array_type_definition
| access_type_definition
| private_type_definition ;
generic_instantiation :
PACKAGE IDENTIFIER IS NEW name SEMICOLON
| PROCEDURE IDENTIFIER IS NEW name SEMICOLON
| FUNCTION designator IS NEW name SEMICOLON ;
representation_clause : type_representation_clause | address_clause ;
type_representation_clause : length_clause
| enumeration_representation_clause
| record_representation_clause ;
length_clause : FOR attribute USE simple_expression SEMICOLON ;
enumeration_representation_clause : FOR IDENTIFIER USE aggregate SEMICOLON ;
record_representation_clause : FOR IDENTIFIER USE
RECORD alignment_clause_option
component_clause0
END RECORD SEMICOLON ;
component_clause0 :
| component_clause0 name AT simple_expression RANGE range SEMICOLON ;
alignment_clause_option : | AT MOD simple_expression SEMICOLON ;
address_clause : FOR IDENTIFIER USE AT simple_expression SEMICOLON ;
code_statement : name QUOTE aggregate SEMICOLON ;
More information about the Comp.sources.unix
mailing list