Previous | Next | Table of Contents | Index | Program List | Copyright

Appendix B: Ada 95 Syntax Rules

This Appendix is adapted from Annex P of the Ada 95 Reference Manual.

The syntactic form of an Ada program is described by means of a context-free notation called Extended Backus-Naur Form or EBNF. EBNF describes a language in terms of a set of syntax rules of the form X ::= Y (read "X is defined as Y"), where X is always a single syntactic category or nonterminal, and Y can be one or more symbols.

Lower case words, some containing embedded underlines, are used to denote nonterminals, for example:

    case_statement
Reserved words are given in the Ada standard in lower case, but appear here in upper case for consistency with the text, for example:
    ARRAY
Square brackets enclose optional items; the two following rules are equivalent.
    return_statement ::= RETURN [expression];
    return_statement ::= RETURN; | RETURN expression;
Curly brackets enclose a repeated item. The item may appear zero or more times; the two following rules are equivalent.
    term ::= factor {multiplying_operator factor}
    term ::= factor | term multiplying_operator factor
A vertical line separates alternative items unless it occurs immediately after an opening curly bracket, in which case it stands for itself:
    constraint ::= scalar_constraint | composite_constraint
    discrete_choice_list ::= discrete_choice {| discrete_choice}

We have organized the syntax rules in strict alphabetical order by the left side of the rule. In tracing a syntax error in a student program, the reader will probably wish to begin with the nonterminal compilation_unit.

abort_statement ::= ABORT task_name {, task_name};

abortable_part ::= sequence_of_statements

abstract_subprogram_declaration ::= 
   subprogram_specification IS ABSTRACT;

accept_alternative ::=
   accept_statement [sequence_of_statements]

accept_statement ::=
   ACCEPT entry_direct_name [(entry_index)] parameter_profile DO 
     handled_sequence_of_statements
   END [entry_identifier]];

access_definition ::= ACCESS subtype_mark
   
access_type_definition ::=
   access_to_object_definition
 | access_to_subprogram_definition
   
access_to_object_definition ::=
   ACCESS [general_access_modifier] subtype_indication

access_to_subprogram_definition ::=
   ACCESS [PROTECTED] PROCEDURE parameter_profile
 | ACCESS [PROTECTED] FUNCTION  parameter_and_result_profile

actual_parameter_part ::=
   (parameter_association {, parameter_association})

aggregate ::= record_aggregate | extension_aggregate | array_aggregate

allocator ::=
   NEW subtype_indication | NEW qualified_expression

ancestor_part ::= expression | subtype_mark

array_aggregate ::=
   positional_array_aggregate | named_array_aggregate

array_component_association ::=
   discrete_choice_list => expression

array_type_definition ::=
   unconstrained_array_definition | constrained_array_definition
   
assignment_statement ::=
   variable_name := expression;

asynchronous_select ::=
   SELECT
     triggering_alternative
   THEN ABORT
     abortable_part
   END SELECT;

at_clause ::= FOR direct_name USE AT expression;

attribute_definition_clause ::=
   FOR local_name'attribute_designator USE expression;
 | FOR local_name'attribute_designator USE name;

attribute_designator ::=
   identifier[(static_expression)]
 | Access | Delta | Digits

attribute_reference ::= prefix'attribute_designator

base ::= numeral
  
based_literal ::=
   base # based_numeral [.based_numeral] # [exponent]

based_numeral ::=
   extended_digit {[underline] extended_digit}

basic_declaration ::=
   type_declaration                | subtype_declaration
 | object_declaration              | number_declaration
 | subprogram_declaration          | abstract_subprogram_declaration
 | package_declaration             | renaming_declaration
 | exception_declaration           | generic_declaration
 | generic_instantiation

basic_declarative_item ::=
   basic_declaration | representation_clause | use_clause

binary_adding_operator ::=  +  | -   | &

block_statement ::=
   [block_statement_identifier:]
      [DECLARE
           declarative_part]
       BEGIN
           handled_sequence_of_statements
       END [block_identifier];

body ::= proper_body | body_stub

body_stub ::= 
   subprogram_body_stub | package_body_stub 
 | task_body_stub      | protected_body_stub

case_statement ::=
   CASE expression IS
      case_statement_alternative
     {case_statement_alternative}
   END CASE;

case_statement_alternative ::=
   WHEN discrete_choice_list =>
      sequence_of_statements

character ::= 
   graphic_character | format_effector | other_control_function

character_literal ::= 'graphic_character'

choice_parameter_specification ::= defining_identifier

code_statement ::= qualified_expression;

compilation ::= {compilation_unit}

compilation_unit ::=
   context_clause library_item
 | context_clause subunit

component_choice_list ::=
   component_selector_name {| component_selector_name}
 | OTHERS

component_clause ::=
   component_local_name AT position RANGE first_bit .. last_bit;

component_definition ::= [ALIASED] subtype_indication

component_item ::= component_declaration | representation_clause

component_list ::=
   component_item {component_item}
 | {component_item} variant_part
 | NULL;

composite_constraint ::=
   index_constraint | discriminant_constraint

compound_statement ::=
   if_statement           | case_statement
 | loop_statement         | block_statement
 | accept_statement       | select_statement

condition ::= boolean_expression

conditional_entry_call ::=
   SELECT
     entry_call_alternative
   ELSE
     sequence_of_statements
   END SELECT;

constrained_array_definition ::=
   ARRAY (discrete_subtype_definition {, discrete_subtype_definition}) 
   OF component_definition

constraint ::= scalar_constraint | composite_constraint

context_clause ::= {context_item}

context_item ::= with_clause | use_clause

decimal_fixed_point_definition ::=
   DELTA static_expression 
   DIGITS static_expression [real_range_specification]

decimal_literal ::= numeral [.numeral] [exponent]

declarative_item ::=
   basic_declarative_item | body
   
declarative_part ::= {declarative_item}

default_expression ::= expression

default_name ::= name

defining_character_literal ::= character_literal

defining_designator ::= 
   defining_program_unit_name | defining_operator_symbol
   
defining_identifier ::= identifier

defining_identifier_list ::=
   defining_identifier {, defining_identifier}

defining_operator_symbol ::= operator_symbol

defining_program_unit_name ::= [parent_unit_name . ]defining_identifier

delay_alternative ::=
   delay_statement [sequence_of_statements]

delay_relative_statement ::= DELAY delay_expression;

delay_statement ::= delay_until_statement | delay_relative_statement

delay_until_statement ::= DELAY UNTIL delay_expression;

delta_constraint ::= DELTA static_expression [range_constraint]

derived_type_definition ::= 
   [ABSTRACT] NEW parent_subtype_indication [record_extension_part]

designator ::= [parent_unit_name . ]identifier | operator_symbol

digits_constraint ::=
   digits static_expression [range_constraint]

direct_name ::= identifier | operator_symbol

discrete_choice ::= expression | discrete_range | OTHERS

discrete_choice_list ::= discrete_choice {| discrete_choice}

discrete_range ::= discrete_subtype_indication | range

discrete_subtype_definition ::= discrete_subtype_indication | range

discriminant_association ::=
   [discriminant_selector_name 
   {| discriminant_selector_name} =>] expression

discriminant_constraint ::=
   (discriminant_association {, discriminant_association})

discriminant_part ::= 
   unknown_discriminant_part | known_discriminant_part

discriminant_specification ::=
   defining_identifier_list : subtype_mark [:= default_expression]
 | defining_identifier_list : access_definition [:= default_expression]

entry_barrier ::= WHEN condition

entry_body ::=
   ENTRY defining_identifier entry_body_formal_part entry_barrier IS
     declarative_part
   BEGIN
     handled_sequence_of_statements
   END [entry_identifier];

entry_body_formal_part ::= 
   [(entry_index_specification)] parameter_profile

entry_call_alternative ::=
   entry_call_statement [sequence_of_statements]

entry_call_statement ::= entry_name [actual_parameter_part];

entry_declaration ::=
   ENTRY defining_identifier 
   [(discrete_subtype_definition)] parameter_profile;
   
entry_index ::= expression

entry_index_specification ::= 
   FOR defining_identifier IN discrete_subtype_definition

enumeration_aggregate ::= array_aggregate

enumeration_literal_specification ::=  
   defining_identifier | defining_character_literal

enumeration_representation_clause ::=
   FOR first_subtype_local_name USE enumeration_aggregate;

enumeration_type_definition ::=
   (enumeration_literal_specification 
   {, enumeration_literal_specification})

exception_declaration ::= defining_identifier_list : EXCEPTION;

exception_choice ::= exception_name | OTHERS

exception_handler ::=
   WHEN [choice_parameter_specification:] exception_choice 
   {| exception_choice} =>
     sequence_of_statements    
   
exception_renaming_declaration ::= 
   defining_identifier : EXCEPTION RENAMES exception_name;

exit_statement ::=
   EXIT [loop_name] [WHEN condition];

explicit_actual_parameter ::= expression | variable_name

explicit_dereference ::= name.ALL

explicit_generic_actual_parameter ::= 
   expression | variable_name
 | subprogram_name | entry_name 
 | subtype_mark | package_instance_name

exponent ::= E [+] numeral | E - numeral

expression ::=
   relation {AND relation} | relation {AND THEN relation}
 | relation {OR relation}  | relation {OR ELSE relation}
 | relation {XOR relation}

extension_aggregate ::=
   (ancestor_part with record_component_association_list)

factor ::= primary [** primary] | ABS primary | NOT primary

first_bit ::= static_simple_expression

fixed_point_definition ::= 
   ordinary_fixed_point_definition | decimal_fixed_point_definition

floating_point_definition ::=
   DIGITS static_expression [real_range_specification]

formal_access_type_definition ::= access_type_definition

formal_array_type_definition ::= array_type_definition

formal_decimal_fixed_point_definition ::= DELTA <> DIGITS <>

formal_derived_type_definition ::= 
   [ABSTRACT] NEW subtype_mark [WITH PRIVATE]

formal_discrete_type_definition ::= (<>)

formal_floating_point_definition ::= DIGITS <>

formal_modular_type_definition ::= MOD <>

formal_object_declaration ::=
   defining_identifier_list : 
   mode subtype_mark [:= default_expression];

formal_ordinary_fixed_point_definition ::= DELTA <>

formal_package_actual_part ::=
   (<>) | [generic_actual_part]

formal_package_declaration ::=
   WITH package defining_identifier 
   IS NEW generic_package_name formal_package_actual_part;

formal_part ::=
   (parameter_specification {; parameter_specification})

formal_private_type_definition ::= 
   [[ABSTRACT] TAGGED] [LIMITED] PRIVATE

formal_signed_integer_type_definition ::= RANGE <>

formal_subprogram_declaration ::= 
   WITH subprogram_specification [IS subprogram_default];

formal_type_declaration ::=
   TYPE defining_identifier[discriminant_part] 
      IS formal_type_definition;

formal_type_definition ::=
   formal_private_type_definition
 | formal_derived_type_definition
 | formal_discrete_type_definition
 | formal_signed_integer_type_definition
 | formal_modular_type_definition
 | formal_floating_point_definition
 | formal_ordinary_fixed_point_definition
 | formal_decimal_fixed_point_definition
 | formal_array_type_definition
 | formal_access_type_definition

format_effector???

full_type_declaration ::=
   TYPE defining_identifier [known_discriminant_part] 
      IS type_definition;
 | task_type_declaration
 | protected_type_declaration

function_call ::=
   function_name
 | function_prefix actual_parameter_part

general_access_modifier ::= ALL | CONSTANT

generic_actual_part ::=
   (generic_association {, generic_association})

generic_association ::=
   [generic_formal_parameter_selector_name =>] 
   explicit_generic_actual_parameter

generic_declaration ::= 
   generic_subprogram_declaration | generic_package_declaration

generic_formal_parameter_declaration ::=
   formal_object_declaration
 | formal_type_declaration
 | formal_subprogram_declaration
 | formal_package_declaration

generic_formal_part ::= 
   generic {generic_formal_parameter_declaration | use_clause}

generic_instantiation ::=
   PACKAGE defining_program_unit_name IS
        NEW generic_package_name [generic_actual_part];
 | PROCEDURE defining_program_unit_name IS
        NEW generic_procedure_name [generic_actual_part];
 | FUNCTION defining_designator IS
        NEW generic_function_name [generic_actual_part];
   
generic_package_declaration ::=
   generic_formal_part package_specification;

generic_renaming_declaration ::=
   GENERIC PACKAGE defining_program_unit_name 
        RENAMES generic_package_name;
 | GENERIC PROCEDURE defining_program_unit_name 
        RENAMES generic_procedure_name;
 | GENERIC FUNCTION defining_program_unit_name 
        RENAMES generic_function_name;

generic_subprogram_declaration ::=
   generic_formal_part subprogram_specification;

goto_statement ::= GOTO label_name;

graphic_character ::= 
   identifier_letter | digit | space_character | special_character

guard ::= WHEN condition =>

handled_sequence_of_statements ::=
   sequence_of_statements
  [EXCEPTION
     exception_handler
    {exception_handler}]

identifier ::=
   identifier_letter {[underline] letter_or_digit}

if_statement ::=
   IF condition THEN
      sequence_of_statements
   {ELSIF condition THEN
      sequence_of_statements}
   [ELSE
      sequence_of_statements]
   END IF;
   
implicit_dereference ::= name

incomplete_type_declaration ::= 
   TYPE defining_identifier [discriminant_part];
   
index_constraint ::=  (discrete_range {, discrete_range})

index_subtype_definition ::= subtype_mark range <>

indexed_component ::= prefix(expression {, expression})

integer_type_definition ::= 
   signed_integer_type_definition | modular_type_definition

iteration_scheme ::= WHILE condition
 | FOR loop_parameter_specification

known_discriminant_part ::=
   (discriminant_specification {; discriminant_specification})

label ::= <<label_statement_identifier>>

last_bit ::= static_simple_expression

letter_or_digit ::= identifier_letter | digit

library_item ::= [PRIVATE] library_unit_declaration
 | library_unit_body
 | [private] library_unit_renaming_declaration

library_unit_body ::= subprogram_body | package_body

library_unit_declaration ::=
   subprogram_declaration | package_declaration
 | generic_declaration    | generic_instantiation

library_unit_renaming_declaration ::=
   package_renaming_declaration
 | generic_renaming_declaration
 | subprogram_renaming_declaration

local_name ::= direct_name
 | direct_name'attribute_designator
 | library_unit_name

loop_parameter_specification ::=
   defining_identifier IN [REVERSE] discrete_subtype_definition

loop_statement ::=
   [loop_statement_identifier:]
     [iteration_scheme] LOOP
        sequence_of_statements
      END LOOP [loop_identifier];

mod_clause ::= AT MOD static_expression;

mode ::= [IN] | IN OUT | OUT

modular_type_definition ::= MOD static_expression

multiplying_operator ::=  *  | /   | MOD | REM

name ::=
   direct_name               | explicit_dereference
 | indexed_component         | slice
 | selected_component        | attribute_reference
 | type_conversion           | function_call
 | character_literal

named_array_aggregate ::=
   (array_component_association {, array_component_association})

null_statement ::= NULL;

number_declaration ::=
   defining_identifier_list : CONSTANT := static_expression;

numeral ::= digit {[underline] digit}

numeric_literal ::= decimal_literal | based_literal

object_declaration ::=
   defining_identifier_list : 
      [ALIASED] [CONSTANT] subtype_indication [:= expression];
 | defining_identifier_list : 
      [ALIASED] [CONSTANT] array_type_definition [:= expression];
 | single_task_declaration
 | single_protected_declaration

object_renaming_declaration ::= 
   defining_identifier : subtype_mark RENAMES object_name;

operator_symbol ::= string_literal

ordinary_fixed_point_definition ::=
   DELTA static_expression real_range_specification

other_control_function???
   
package_body ::=
   PACKAGE BODY defining_program_unit_name IS
      declarative_part
   [BEGIN
      handled_sequence_of_statements]
   END [[parent_unit_name.]identifier];

package_body_stub ::= PACKAGE BODY defining_identifier IS SEPARATE;

package_declaration ::= package_specification;

package_renaming_declaration ::= 
   PACKAGE defining_program_unit_name RENAMES package_name;

package_specification ::=
   PACKAGE defining_program_unit_name IS
     {basic_declarative_item}
   [PRIVATE
     {basic_declarative_item}]
   END [[parent_unit_name.]identifier]

parameter_and_result_profile ::= [formal_part] RETURN subtype_mark

parameter_association ::=
   [formal_parameter_selector_name =>] explicit_actual_parameter

parameter_profile ::= [formal_part]

parameter_specification ::=
   defining_identifier_list : 
      mode subtype_mark [:= default_expression]
 | defining_identifier_list : 
      access_definition [:= default_expression]

parent_unit_name ::= name

position ::= static_expression

positional_array_aggregate ::=
   (expression, expression {, expression})
 | (expression {, expression}, OTHERS => expression)

pragma ::= PRAGMA identifier 
   [(pragma_argument_association {, pragma_argument_association})];

prefix ::= name | implicit_dereference
   
primary ::=
   numeric_literal | NULL | string_literal | aggregate
 | name | qualified_expression | allocator | (expression)

private_extension_declaration ::=
   TYPE defining_identifier [discriminant_part] IS
      [ABSTRACT] NEW ancestor_subtype_indication WITH PRIVATE;

private_type_declaration ::=
   TYPE defining_identifier [discriminant_part] 
      IS [[ABSTRACT] TAGGED] [LIMITED] PRIVATE;

procedure_call_statement ::=
   procedure_name;
 | procedure_prefix actual_parameter_part;

proper_body ::=
   subprogram_body | package_body | task_body | protected_body

protected_body ::=
   PROTECTED BODY defining_identifier IS
     { protected_operation_item }
   END [protected_identifier];

protected_body_stub ::= PROTECTED BODY defining_identifier IS SEPARATE;

protected_definition ::=
     { protected_operation_declaration }
   [ PRIVATE
     { protected_element_declaration } ]
   END [protected_identifier]

protected_element_declaration ::= 
   protected_operation_declaration | component_declaration

protected_operation_declaration ::= subprogram_declaration
 | entry_declaration
 | representation_clause

protected_operation_item ::= subprogram_declaration
 | subprogram_body
 | entry_body
 | representation_clause

protected_type_declaration ::=
   PROTECTED TYPE defining_identifier [known_discriminant_part] 
     IS protected_definition;

qualified_expression ::=
   subtype_mark'(expression) | subtype_mark'aggregate

raise_statement ::= RAISE [exception_name];

range ::= RANGE | simple_expression .. simple_expression

range_attribute_designator ::= Range[(static_expression)]

range_attribute_reference ::= prefix'range_attribute_designator

range_constraint ::=  RANGE range
   
real_range_specification ::=
   RANGE static_simple_expression .. static_simple_expression

real_type_definition ::=
   floating_point_definition | fixed_point_definition

record_aggregate ::= (record_component_association_list)

record_component_association ::=
   [ component_choice_list => ] expression

record_component_association_list ::=
   record_component_association {, record_component_association}
 | NULL RECORD

record_definition ::=
   RECORD
      component_list
   END RECORD
 | NULL RECORD

record_extension_part ::= WITH record_definition

record_representation_clause ::=
   FOR first_subtype_local_name USE
     RECORD [mod_clause]
       {component_clause}
     END RECORD;

record_type_definition ::= 
   [[ABSTRACT] TAGGED] [LIMITED] record_definition

relation ::=
   simple_expression [relational_operator simple_expression]
 | simple_expression [NOT] IN range
 | simple_expression [NOT] IN subtype_mark

relational_operator ::=  =  | /=  | <   | <= | > | >=

renaming_declaration ::=
   object_renaming_declaration
 | exception_renaming_declaration
 | package_renaming_declaration
 | subprogram_renaming_declaration
 | generic_renaming_declaration

representation_clause ::= attribute_definition_clause
  | enumeration_representation_clause
  | record_representation_clause
  | at_clause

requeue_statement ::= REQUEUE entry_name [WITH ABORT];

return_statement ::= RETURN [expression];

scalar_constraint ::=
   range_constraint | digits_constraint | delta_constraint

select_alternative ::=
   accept_alternative
 | delay_alternative
 | terminate_alternative

select_statement ::=
   selective_accept
 | timed_entry_call
 | conditional_entry_call
 | asynchronous_select

selected_component ::= prefix . selector_name
   
selective_accept ::=
   SELECT
     [guard]
     select_alternative
   { OR
     [guard]
     select_alternative }
   [ ELSE
     sequence_of_statements ]
   END SELECT;

selector_name ::= identifier | character_literal | operator_symbol

sequence_of_statements ::= statement {statement}

signed_integer_type_definition ::= 
   RANGE static_simple_expression .. static_simple_expression

simple_expression ::= 
   [unary_adding_operator] term {binary_adding_operator term}
   
simple_statement ::= null_statement
 | assignment_statement   | exit_statement
 | goto_statement         | procedure_call_statement
 | return_statement       | entry_call_statement
 | requeue_statement      | delay_statement
 | abort_statement        | raise_statement
 | code_statement

single_protected_declaration ::=
   PROTECTED defining_identifier IS protected_definition;

single_task_declaration ::=
   TASK defining_identifier [IS task_definition];

slice ::= prefix(discrete_range)

space_character???

special_character???

statement ::=
   {label} simple_statement | {label} compound_statement

statement_identifier ::= direct_name

string_element ::= "" | non_quotation_mark_graphic_character

string_literal ::= "{string_element}"

subprogram_body ::=
   subprogram_specification IS
      declarative_part
   BEGIN
      handled_sequence_of_statements
   END [designator];

subprogram_body_stub ::= subprogram_specification IS SEPARATE;

subprogram_declaration ::= subprogram_specification;

subprogram_default ::= default_name | <>

subprogram_renaming_declaration ::= 
   subprogram_specification RENAMES callable_entity_name;

subprogram_specification ::=
   PROCEDURE defining_program_unit_name parameter_profile
 | FUNCTION defining_designator parameter_and_result_profile

subtype_declaration ::=
   SUBTYPE defining_identifier IS subtype_indication;

subtype_indication ::=  subtype_mark [constraint]

subtype_mark ::= subtype_name

subunit ::= SEPARATE (parent_unit_name) proper_body

task_body ::=
   TASK BODY defining_identifier IS
     declarative_part
   BEGIN
     handled_sequence_of_statements
   END [task_identifier];
   
task_body_stub ::= TASK BODY defining_identifier IS SEPARATE;

task_definition ::=
    {task_item}
  [ PRIVATE
    {task_item}]
  END [task_identifier]
  
task_item ::= entry_declaration | representation_clause

task_type_declaration ::=
   TASK TYPE defining_identifier [known_discriminant_part] 
      [IS task_definition];

term ::= factor {multiplying_operator factor}

terminate_alternative ::= TERMINATE;

timed_entry_call ::=
   SELECT
     entry_call_alternative
   OR
     delay_alternative
   END SELECT;
  
triggering_alternative ::= 
   triggering_statement [sequence_of_statements]

triggering_statement ::= entry_call_statement | delay_statement  
   
type_conversion ::=
   subtype_mark(expression)
 | subtype_mark(name)

type_declaration ::=  full_type_declaration
 | incomplete_type_declaration
 | private_type_declaration
 | private_extension_declaration

type_definition ::=
   enumeration_type_definition | integer_type_definition
 | real_type_definition        | array_type_definition
 | record_type_definition      | access_type_definition
 | derived_type_definition

unary_adding_operator ::=  +  | -

unconstrained_array_definition ::=
   ARRAY(index_subtype_definition 
  {, index_subtype_definition}) OF component_definition

unknown_discriminant_part ::= (<>)

use_clause ::= use_package_clause | use_type_clause

use_package_clause ::= USE package_name {, package_name};

use_type_clause ::= USE TYPE subtype_mark {, subtype_mark};

variant ::=
   WHEN discrete_choice_list =>
     component_list
     
variant_part ::=
   CASE discriminant_direct_name IS
      variant
     {variant}
   END CASE;

with_clause ::= WITH library_unit_name {, library_unit_name};


Previous | Next | Table of Contents | Index | Program List | Copyright

Copyright © 1996 by Addison-Wesley Publishing Company, Inc.