From 9a4065320bd9985cf7b1955a78ddda32730b251a Mon Sep 17 00:00:00 2001 From: grammarware Date: Sun, 22 May 2011 21:54:50 +0000 Subject: [PATCH] ANTLR Ada? git-svn-id: https://slps.svn.sourceforge.net/svnroot/slps@1046 ab42f6e0-554d-0410-b580-99e487e6eeb2 --- topics/grammars/ada/kellogg/README.txt | 41 + topics/grammars/ada/kellogg/ada.g | 1949 +++++++++++++++++ .../grammars/ada/laemmel-verhoef/README.txt | 2 +- .../ada/lncs-1246/src.syntax.summary.txt | 517 ++++- 4 files changed, 2507 insertions(+), 2 deletions(-) create mode 100644 topics/grammars/ada/kellogg/README.txt create mode 100644 topics/grammars/ada/kellogg/ada.g diff --git a/topics/grammars/ada/kellogg/README.txt b/topics/grammars/ada/kellogg/README.txt new file mode 100644 index 00000000..2917fcf0 --- /dev/null +++ b/topics/grammars/ada/kellogg/README.txt @@ -0,0 +1,41 @@ +http://www.antlr.org/grammar/list: + ↳ http://www.antlr.org/grammar/ada + +Oliver kellogg Mon Aug 4, 2003 12:43 +By Oliver Kellogg. Tested on several Ada projects totalling a few ten thousand lines of code. Has tree construction. The parser and tree parser have successfully translated ACES, one of the large standard test suites for Ada compilers. + +http://www.antlr.org/grammar/ada/README contents follow: + +Last updated: 2003-08-03 + +The Ada tree structure (ada.g) and superclass (ada.tree.g) have +been tested somewhat due to work on a first real application, +Ada support in kdevelop (http://www.kdevelop.org) + +suggestions on the tree structure are still +-- + +You can see the generated tree as follows: +Define an environment variable, ANTLR_TREE. +Then run the parser program, and redirect the output to a file. + +Example in Bourne shell: + +$ export ANTLR_TREE=1 +$ ada my_ada_program.adb > adatree.tmp + +This temporary output file will not be nicely readable because +everything is on a single line. You can get readable output using +the choptree script: + +$ choptree adatree.tmp + +If you want to additionally run the generated tree through the +AdaTreeParserSuper, then define the symbol ANTLR_TREE_WALK: + +$ export ANTLR_TREE_WALK=1 + +This verifies that the tree produced by the AdaParser matches the +tree expected by the AdaTreeParserSuper. + + diff --git a/topics/grammars/ada/kellogg/ada.g b/topics/grammars/ada/kellogg/ada.g new file mode 100644 index 00000000..0818b524 --- /dev/null +++ b/topics/grammars/ada/kellogg/ada.g @@ -0,0 +1,1949 @@ +/* + * Ada95 Recognizer for ANTLR + * + * Oliver M. Kellogg + * + * Adapted from lexer9x.l/grammar9x.y, + * + ******* A YACC grammar for Ada 9X ********************************* + * Copyright (C) Intermetrics, Inc. 1994 Cambridge, MA USA * + * Copying permitted if accompanied by this statement. * + * Derivative works are permitted if accompanied by this statement.* + * This grammar is thought to be correct as of May 1, 1994 * + * but as usual there is *no warranty* to that effect. * + ******************************************************************* + * + * $Id: ada.g,v 1.2 2003/08/02 20:00:00 okellogg Exp $ + * + * Not all rules from the Ada95 Reference Manual (RM) Annex P, + * Syntax Summary, are mirrored as rules here. + * The tree nodes follow the RM grammar as closely as sensible. + * This applies in particular to the terminals. OTOH, trivially + * reconstructable non-terminal rules are not reflected in the tree. + * FIXME: Document the exact rationale of the tree design. + * + */ + + +header "pre_include_hpp" { +#include // antlr wants this +#include "AdaAST.hpp" +#include "preambles.h" +} + +options { + language="Cpp"; +} + + +//----------------------------------------------------------------------------- +// Define a Parser, calling it AdaParser +//----------------------------------------------------------------------------- +class AdaParser extends Parser; +options { + k = 2; // token lookahead + exportVocab=Ada; // Call its vocabulary "Ada" + // codeGenMakeSwitchThreshold = 2; // Some optimizations + // codeGenBitsetTestThreshold = 3; + defaultErrorHandler = true; // Generate parser error handlers + buildAST = true; + ASTLabelType = "RefAdaAST"; +} + +{ + ANTLR_PARSER_PREAMBLE + +public: + // Ada support stuff + void push_def_id (const RefAdaAST& defid); + const RefAdaAST& pop_def_id (); + bool end_id_matches_def_id (const RefAdaAST& endid); + bool definable_operator (const char *string); // operator_symbol sans "/=" + bool is_operator_symbol (const char *string); +} + +// Compilation Unit: This is the start rule for this parser. +// The rules in this grammar are listed in the order in which +// compilation_unit introduces them, depth first, with the +// exception of the expression related rules which are listed +// towards the end. +compilation_unit + : context_items_opt ( library_item | subunit ) ( pragma )* + ; + +// The pragma related rules are pulled up here to get them out of the way. + +pragma : PRAGMA^ IDENTIFIER pragma_args_opt SEMI! + ; + +pragma_args_opt : ( LPAREN! pragma_arg ( COMMA! pragma_arg )* RPAREN! )? + ; + +pragma_arg : ( IDENTIFIER RIGHT_SHAFT^ )? expression + ; + +context_items_opt : ( pragma )* ( with_clause ( use_clause | pragma )* )* + { #context_items_opt = + #(#[CONTEXT_CLAUSE, "CONTEXT_CLAUSE"], #context_items_opt); } + // RM Annex P neglects pragmas; we include them. + // The node should really be named CONTEXT_ITEMS_OPT, but we + // stick with the RM wording. + ; + +with_clause : w:WITH^ c_name_list SEMI! + { Set(#w, WITH_CLAUSE); } + ; + +c_name_list : compound_name ( COMMA! compound_name )* + ; + +compound_name : IDENTIFIER ( DOT^ IDENTIFIER )* + // Strangely, the RM never defines this rule, which however is + // required for tightening up the syntax of certain names + // (library unit names etc.) + ; + +use_clause : u:USE^ + ( TYPE! subtype_mark ( COMMA! subtype_mark )* + { Set(#u, USE_TYPE_CLAUSE); } + | c_name_list { Set(#u, USE_CLAUSE); } + ) + SEMI! + ; + +subtype_mark : compound_name ( TIC^ attribute_id )? + // { #subtype_mark = #(#[SUBTYPE_MARK, "SUBTYPE_MARK"], #subtype_mark); } + ; + +attribute_id : RANGE + | DIGITS + | DELTA + | ACCESS + | IDENTIFIER + ; + +library_item : private_opt + /* Slightly loose; PRIVATE can only precede + {generic|package|subprog}_decl. + Semantic check required to ensure it.*/ + ( lib_pkg_spec_or_body + | subprog_decl_or_rename_or_inst_or_body[true] + | generic_decl[true] + ) + { #library_item = #(#[LIBRARY_ITEM, "LIBRARY_ITEM"], #library_item); } + ; + +private_opt : ( PRIVATE )? + { #private_opt = #(#[MODIFIERS, "MODIFIERS"], #private_opt); } + ; + +lib_pkg_spec_or_body + : pkg:PACKAGE^ + ( BODY! def_id[true] IS! pkg_body_part end_id_opt! SEMI! + { Set(#pkg, PACKAGE_BODY); } + | def_id[true] spec_decl_part[#pkg] + ) + ; + +subprog_decl [bool lib_level] + { RefAdaAST t; } + : p:PROCEDURE^ def_id[lib_level] + ( generic_subp_inst + { Set(#p, GENERIC_PROCEDURE_INSTANTIATION); } + | formal_part_opt + ( renames { Set(#p, PROCEDURE_RENAMING_DECLARATION); } + | is_separate_or_abstract_or_decl[#p] + ) + SEMI! + ) + | f:FUNCTION^ def_designator[lib_level] + ( generic_subp_inst + { Set(#f, GENERIC_FUNCTION_INSTANTIATION); } + | function_tail + ( renames { Set(#f, FUNCTION_RENAMING_DECLARATION); } + | is_separate_or_abstract_or_decl[#f] + ) + SEMI! + ) + ; + +def_id [bool lib_level] + : { lib_level }? cn:compound_name { push_def_id(#cn); } + | { !lib_level }? n:IDENTIFIER { push_def_id(#n); } + ; + +generic_subp_inst : IS! generic_inst SEMI! + ; + +generic_inst : NEW! compound_name ( LPAREN! value_s RPAREN! )? + { pop_def_id(); } + ; + +parenth_values : LPAREN! value ( COMMA! value )* RPAREN! + ; + +value : ( OTHERS^ RIGHT_SHAFT! expression + | ranged_expr_s ( RIGHT_SHAFT^ expression )? + ) + // { #value = #(#[VALUE, "VALUE"], #value); } + ; + +ranged_expr_s : ranged_expr ( PIPE^ ranged_expr )* + // { #ranged_expr_s = + // #(#[RANGED_EXPRS, "RANGED_EXPRS"], #ranged_expr_s); } + ; + +ranged_expr : expression + ( DOT_DOT^ simple_expression + | RANGE^ range + )? + ; + +range_constraint : RANGE! range + ; + +range : ( (range_dots) => range_dots + | range_attrib_ref + ) + // Current assumption is we don't need an extra node for range, + // otherwise uncomment the following line: + // { #range = #(#[RANGE_EXPR, "RANGE_EXPR"], #range); } + ; + +range_dots : simple_expression DOT_DOT^ simple_expression + ; + +range_attrib_ref : // "name TIC RANGE" is ambiguous; instead: + prefix TIC! r:RANGE^ ( LPAREN! expression RPAREN! )? + { Set(#r, RANGE_ATTRIBUTE_REFERENCE); } + ; + +// Here, the definition of `prefix' deviates from the RM. +// This gives us some more strictness than `name' (which the RM uses to +// define `prefix'.) +prefix : IDENTIFIER + ( DOT^ ( ALL | IDENTIFIER ) + | p:LPAREN^ value_s RPAREN! + { Set(#p, INDEXED_COMPONENT); } + )* + ; + +formal_part_opt : ( LPAREN! parameter_specification + ( SEMI! parameter_specification )* + RPAREN! )? + { #formal_part_opt = #([FORMAL_PART_OPT, "FORMAL_PART_OPT"], + #formal_part_opt); } + ; + +parameter_specification : def_ids_colon mode_opt subtype_mark init_opt + { #parameter_specification = + #(#[PARAMETER_SPECIFICATION, + "PARAMETER_SPECIFICATION"], #parameter_specification); } + ; + +def_ids_colon : defining_identifier_list COLON! + ; + +defining_identifier_list : IDENTIFIER ( COMMA! IDENTIFIER )* + { #defining_identifier_list = + #(#[DEFINING_IDENTIFIER_LIST, + "DEFINING_IDENTIFIER_LIST"], #defining_identifier_list); } + ; + +mode_opt : ( IN ( OUT )? | OUT | ACCESS )? + { #mode_opt = #(#[MODIFIERS, "MODIFIERS"], #mode_opt); } + ; + +renames { RefAdaAST dummy; } + : RENAMES! ( name + | dummy=definable_operator_symbol + ) + { pop_def_id(); } + ; + +name { RefAdaAST dummy; } + : IDENTIFIER + ( DOT^ ( ALL + | IDENTIFIER + | CHARACTER_LITERAL + | dummy=is_operator + ) + | p:LPAREN^ value_s RPAREN! + { Set(#p, INDEXED_COMPONENT); } + | TIC^ attribute_id // must be in here because of e.g. + // Character'Pos (x) + )* + // { #name = #(#[NAME, "NAME"], #name); } + ; + +is_operator returns [RefAdaAST d] + : { is_operator_symbol(LT(1)->getText().c_str()) }? + op:CHAR_STRING { #op->setType(OPERATOR_SYMBOL); d=#op; } + ; + +definable_operator_symbol returns [RefAdaAST d] + : { definable_operator(LT(1)->getText().c_str()) }? + op:CHAR_STRING { #op->setType(OPERATOR_SYMBOL); d=#op; } + ; + +parenthesized_primary : pp:LPAREN^ + ( NuLL RECORD! + | value_s extension_opt + ) + RPAREN! + { Set(#pp, PARENTHESIZED_PRIMARY); } + ; + +extension_opt : ( WITH! ( NuLL RECORD! | value_s ) )? + { #extension_opt = + #(#[EXTENSION_OPT, "EXTENSION_OPT"], #extension_opt); } + ; + +is_separate_or_abstract_or_decl! [RefAdaAST t] + : IS! separate_or_abstract[t] + | { pop_def_id(); + if (t->getType() == AdaTokenTypes::PROCEDURE) + Set(t, PROCEDURE_DECLARATION); + else + Set(t, FUNCTION_DECLARATION); + } + ; + +separate_or_abstract! [RefAdaAST t] + : SEPARATE! + { pop_def_id(); + if (t->getType() == AdaTokenTypes::PROCEDURE) + Set(t, PROCEDURE_BODY_STUB); + else + Set(t, FUNCTION_BODY_STUB); + } + | ABSTRACT! + { pop_def_id(); + if (t->getType() == AdaTokenTypes::PROCEDURE) + Set(t, ABSTRACT_PROCEDURE_DECLARATION); + else + Set(t, ABSTRACT_FUNCTION_DECLARATION); + } + ; + +def_designator [bool lib_level] + { RefAdaAST d; } + : { lib_level }? n:compound_name { push_def_id(#n); } + | { !lib_level }? d=designator { push_def_id(d); } + ; + +designator returns [RefAdaAST d] + { RefAdaAST op; } + : op=definable_operator_symbol { d = op; } + | n:IDENTIFIER { d = #n; } + ; + +function_tail : func_formal_part_opt RETURN! subtype_mark + ; + +// formal_part_opt is not strict enough for functions, i.e. it permits +// "in out" and "out" as modes, thus we make an extra rule: +func_formal_part_opt : ( LPAREN! func_param ( SEMI! func_param )* RPAREN! )? + { #func_formal_part_opt = + #([FORMAL_PART_OPT, + "FORMAL_PART_OPT"], #func_formal_part_opt); } + ; + +func_param : def_ids_colon in_access_opt subtype_mark init_opt + { #func_param = + #(#[PARAMETER_SPECIFICATION, + "PARAMETER_SPECIFICATION"], #func_param); } + ; + +in_access_opt : ( IN! | ACCESS )? + { #in_access_opt = #(#[MODIFIERS, "MODIFIERS"], #in_access_opt); } + ; + +spec_decl_part [RefAdaAST pkg] + : ( IS! ( generic_inst { Set(pkg, GENERIC_PACKAGE_INSTANTIATION); } + | pkg_spec_part { Set(pkg, PACKAGE_SPECIFICATION); } + ) + | renames { Set(pkg, PACKAGE_RENAMING_DECLARATION); } + ) + SEMI! + ; + +pkg_spec_part : basic_declarative_items_opt + ( PRIVATE! basic_declarative_items_opt )? + end_id_opt! + ; + +basic_declarative_items_opt : ( basic_decl_item | pragma )* + { #basic_declarative_items_opt = + #(#[BASIC_DECLARATIVE_ITEMS_OPT, + "BASIC_DECLARATIVE_ITEMS_OPT"], + #basic_declarative_items_opt); } + ; + +basic_declarative_items : ( basic_decl_item | pragma )+ + { #basic_declarative_items = + #(#[BASIC_DECLARATIVE_ITEMS_OPT, + "BASIC_DECLARATIVE_ITEMS_OPT"], + #basic_declarative_items); } + ; + +basic_decl_item + : pkg:PACKAGE^ def_id[false] spec_decl_part[#pkg] + | tsk:TASK^ task_type_or_single_decl[#tsk] + | pro:PROTECTED^ prot_type_or_single_decl[#pro] SEMI! + | subprog_decl[false] + | decl_common + ; + +task_type_or_single_decl [RefAdaAST tsk] + : TYPE! def_id[false] discrim_part_opt task_definition_opt + { Set(tsk, TASK_TYPE_DECLARATION); } + | def_id[false] task_definition_opt + { Set(tsk, SINGLE_TASK_DECLARATION); } + ; + +task_definition_opt + : IS! task_items_opt private_task_items_opt end_id_opt! SEMI! + | SEMI! { pop_def_id(); } + ; + +discrim_part_opt + : ( discrim_part_text )? + { #discrim_part_opt = + #(#[DISCRIM_PART_OPT, + "DISCRIM_PART_OPT"], #discrim_part_opt); } + ; + +discrim_part_text : LPAREN! (BOX | discriminant_specifications) RPAREN! + ; + +known_discrim_part + : LPAREN! discriminant_specifications RPAREN! + { #known_discrim_part = + #(#[DISCRIM_PART_OPT, + "DISCRIM_PART_OPT"], #known_discrim_part); } + ; + +empty_discrim_opt : /* empty */ + { #empty_discrim_opt = + #(#[DISCRIM_PART_OPT, + "DISCRIM_PART_OPT"], #empty_discrim_opt); } + ; + +discrim_part + : discrim_part_text + { #discrim_part = + #(#[DISCRIM_PART_OPT, + "DISCRIM_PART_OPT"], #discrim_part); } + ; + +discriminant_specifications : discriminant_specification + ( SEMI! discriminant_specification )* + { #discriminant_specifications = + #(#[DISCRIMINANT_SPECIFICATIONS, + "DISCRIMINANT_SPECIFICATIONS"], + #discriminant_specifications); } + ; + +discriminant_specification : def_ids_colon access_opt subtype_mark init_opt + { #discriminant_specification = + #(#[DISCRIMINANT_SPECIFICATION, + "DISCRIMINANT_SPECIFICATION"], + #discriminant_specification); } + ; + +access_opt : ( ACCESS )? + { #access_opt = #(#[MODIFIERS, "MODIFIERS"], #access_opt); } + ; + +init_opt : ( ASSIGN! expression )? + { #init_opt = #(#[INIT_OPT, "INIT_OPT"], #init_opt); } + ; // `expression' is of course much too loose; + // semantic checks are required in the usage contexts. + +task_items_opt : ( pragma )* entrydecls_repspecs_opt + { #task_items_opt = + #(#[TASK_ITEMS_OPT, "TASK_ITEMS_OPT"], #task_items_opt); } + ; + +entrydecls_repspecs_opt : ( entry_declaration ( pragma | rep_spec )* )* + ; + +entry_declaration : e:ENTRY^ IDENTIFIER + discrete_subtype_def_opt formal_part_opt SEMI! + { Set (#e, ENTRY_DECLARATION); } + ; + +discrete_subtype_def_opt : ( (LPAREN discrete_subtype_definition RPAREN) => + LPAREN! discrete_subtype_definition RPAREN! + | /* empty */ + ) + { #discrete_subtype_def_opt = + #(#[DISCRETE_SUBTYPE_DEF_OPT, + "DISCRETE_SUBTYPE_DEF_OPT"], #discrete_subtype_def_opt); } + ; + +discrete_subtype_definition : ( (range) => range + | subtype_ind + ) + // Looks alot like discrete_range, but it's not + // (as soon as we start doing semantics.) + /* TBC: No need for extra node, just use the inner nodes? + { #discrete_subtype_definition = + #(#[DISCRETE_SUBTYPE_DEFINITION, + "DISCRETE_SUBTYPE_DEFINITION"], + #discrete_subtype_definition); } + */ + ; + +rep_spec : r:FOR^ subtype_mark USE! rep_spec_part[#r] SEMI! + ; + +rep_spec_part [RefAdaAST t] + : RECORD! align_opt comp_loc_s END! RECORD! // record_type_spec + { Set(t, RECORD_REPRESENTATION_CLAUSE); } + | AT! expression // address_spec (Ada83) + { Set(t, AT_CLAUSE); } + | expression // attrib_def. Semantic check must ensure that the + // respective subtype_mark contains an attribute reference. + { Set(t, ATTRIBUTE_DEFINITION_CLAUSE); } + ; + +align_opt : ( AT! MOD! expression SEMI! )? + { #align_opt = #(#[MOD_CLAUSE_OPT, "MOD_CLAUSE_OPT"], #align_opt); } + ; + +comp_loc_s : ( pragma | subtype_mark AT! expression RANGE! range SEMI! )* + { #comp_loc_s = #(#[COMPONENT_CLAUSES_OPT, "COMPONENT_CLAUSES_OPT"], + #comp_loc_s); } + ; + +private_task_items_opt : ( PRIVATE! ( pragma )* entrydecls_repspecs_opt )? + { #private_task_items_opt = + #(#[PRIVATE_TASK_ITEMS_OPT, + "PRIVATE_TASK_ITEMS_OPT"], #private_task_items_opt); } + // Maybe we could just reuse TASK_ITEMS_OPT here instead of + // making a separate node type. + ; + +prot_type_or_single_decl [RefAdaAST pro] + : TYPE! def_id[false] discrim_part_opt protected_definition + { Set(pro, PROTECTED_TYPE_DECLARATION); } + | def_id[false] protected_definition + { Set(pro, SINGLE_PROTECTED_DECLARATION); } + ; + +protected_definition + : IS! prot_op_decl_s ( PRIVATE! prot_member_decl_s )? end_id_opt! + ; + +prot_op_decl_s : ( prot_op_decl )* + { #prot_op_decl_s = #(#[PROT_OP_DECLARATIONS, + "PROT_OP_DECLARATIONS"], #prot_op_decl_s); } + ; + +prot_op_decl : entry_declaration + | p:PROCEDURE^ def_id[false] formal_part_opt SEMI! + { pop_def_id(); Set(#p, PROCEDURE_DECLARATION); } + | f:FUNCTION^ def_designator[false] function_tail SEMI! + { pop_def_id(); Set(#f, FUNCTION_DECLARATION); } + | rep_spec + | pragma + ; + +prot_member_decl_s : ( prot_op_decl | comp_decl )* + { #prot_member_decl_s = + #(#[PROT_MEMBER_DECLARATIONS, + "PROT_MEMBER_DECLARATIONS"], #prot_member_decl_s); } + ; + +comp_decl : def_ids_colon component_subtype_def init_opt SEMI! + { #comp_decl = + #(#[COMPONENT_DECLARATION, + "COMPONENT_DECLARATION"], #comp_decl); } + ; + +// decl_common is shared between declarative_item and basic_decl_item. +// decl_common only contains specifications. +decl_common + : t:TYPE^ IDENTIFIER + ( IS! type_def[#t] + | ( discrim_part + ( IS! derived_or_private_or_record[#t, true] + | { Set(#t, INCOMPLETE_TYPE_DECLARATION); } + ) + | empty_discrim_opt + { Set(#t, INCOMPLETE_TYPE_DECLARATION); } + // NB: In this case, the discrim_part_opt does not + // appear in the INCOMPLETE_TYPE_DECLARATION node. + ) + /* The artificial derived_or_private_or_record rule + gives us some syntax-level control over where a + discrim_part may appear. + However, a semantic check is still necessary to make + sure the discrim_part is not given for a derived type + of an elementary type, or for the full view of a + private type that turns out to be such. */ + ) + SEMI! + | s:SUBTYPE^ IDENTIFIER IS! subtype_ind SEMI! // subtype_decl + { Set(#s, SUBTYPE_DECLARATION); } + | generic_decl[false] + | use_clause + | r:FOR^ ( (local_enum_name USE LPAREN) => local_enum_name USE! + enumeration_aggregate + { Set(#r, ENUMERATION_REPESENTATION_CLAUSE); } + | subtype_mark USE! rep_spec_part[#r] + ) + SEMI! + | (IDENTIFIER COLON EXCEPTION RENAMES) => + IDENTIFIER erd:COLON^ EXCEPTION! RENAMES! compound_name SEMI! + { Set(#erd, EXCEPTION_RENAMING_DECLARATION); } + | (IDENTIFIER COLON subtype_mark RENAMES) => + IDENTIFIER ord:COLON^ subtype_mark RENAMES! name SEMI! + { Set(#ord, OBJECT_RENAMING_DECLARATION); } + | defining_identifier_list od:COLON^ // object_declaration + ( EXCEPTION! + { Set(#od, EXCEPTION_DECLARATION); } + | (CONSTANT ASSIGN) => CONSTANT! ASSIGN! expression + { Set(#od, NUMBER_DECLARATION); } + | aliased_constant_opt + ( array_type_definition[#od] init_opt + { Set(#od, ARRAY_OBJECT_DECLARATION); } + // Not an RM rule, but simplifies distinction + // from the non-array object_declaration. + | subtype_ind init_opt + { Set(#od, OBJECT_DECLARATION); } + ) + ) + SEMI! + ; + +type_def [RefAdaAST t] + : LPAREN! enum_id_s RPAREN! + { Set(t, ENUMERATION_TYPE_DECLARATION); } + | RANGE! range + { Set(t, SIGNED_INTEGER_TYPE_DECLARATION); } + | MOD! expression + { Set(t, MODULAR_TYPE_DECLARATION); } + | DIGITS! expression range_constraint_opt + { Set(t, FLOATING_POINT_DECLARATION); } + | DELTA! expression + ( RANGE! range + { Set(t, ORDINARY_FIXED_POINT_DECLARATION); } + | DIGITS! expression range_constraint_opt + { Set(t, DECIMAL_FIXED_POINT_DECLARATION); } + ) + | array_type_definition[t] + | access_type_definition[t] + | empty_discrim_opt derived_or_private_or_record[t, false] + ; + +enum_id_s : enumeration_literal_specification + ( COMMA! enumeration_literal_specification )* + ; + +enumeration_literal_specification : IDENTIFIER | CHARACTER_LITERAL + ; + +range_constraint_opt : ( range_constraint )? + ; + +array_type_definition [RefAdaAST t] + : ARRAY! LPAREN! index_or_discrete_range_s RPAREN! + OF! component_subtype_def + { Set(t, ARRAY_TYPE_DECLARATION); } + ; + +index_or_discrete_range_s + : index_or_discrete_range ( COMMA^ index_or_discrete_range )* + ; + +index_or_discrete_range + : simple_expression + ( DOT_DOT^ simple_expression // constrained + | RANGE^ ( BOX // unconstrained + | range // constrained + ) + )? + ; + +component_subtype_def : aliased_opt subtype_ind + ; + +aliased_opt : ( ALIASED )? + { #aliased_opt = #(#[MODIFIERS, "MODIFIERS"], #aliased_opt); } + ; + +subtype_ind : subtype_mark constraint_opt + { #subtype_ind = #(#[SUBTYPE_INDICATION, "SUBTYPE_INDICATION"], + #subtype_ind); } + ; + +constraint_opt : ( range_constraint + | digits_constraint + | delta_constraint + | (index_constraint) => index_constraint + | discriminant_constraint + )? + ; + +digits_constraint : d:DIGITS^ expression range_constraint_opt + { Set(#d, DIGITS_CONSTRAINT); } + ; + +delta_constraint : d:DELTA^ expression range_constraint_opt + { Set(#d, DELTA_CONSTRAINT); } + ; + +index_constraint : p:LPAREN^ discrete_range ( COMMA! discrete_range )* RPAREN! + { Set(#p, INDEX_CONSTRAINT); } + ; + +discrete_range + : (range) => range + | subtype_ind + ; + +discriminant_constraint : p:LPAREN^ discriminant_association + ( COMMA! discriminant_association )* RPAREN! + { Set(#p, DISCRIMINANT_CONSTRAINT); } + ; + +discriminant_association : selector_names_opt expression + { #discriminant_association = + #(#[DISCRIMINANT_ASSOCIATION, + "DISCRIMINANT_ASSOCIATION"], #discriminant_association); } + ; + +selector_names_opt : ( (association_head) => association_head + | /* empty */ + ) + { #selector_names_opt = + #(#[SELECTOR_NAMES_OPT, + "SELECTOR_NAMES_OPT"], #selector_names_opt); } + ; + +association_head : selector_name ( PIPE! selector_name )* RIGHT_SHAFT! + ; + +selector_name : IDENTIFIER // TBD: sem pred + ; + +access_type_definition [RefAdaAST t] + : ACCESS! + ( protected_opt + ( PROCEDURE! formal_part_opt + { Set(t, ACCESS_TO_PROCEDURE_DECLARATION); } + | FUNCTION! func_formal_part_opt RETURN! subtype_mark + { Set(t, ACCESS_TO_FUNCTION_DECLARATION); } + ) + | constant_all_opt subtype_ind + { Set(t, ACCESS_TO_OBJECT_DECLARATION); } + ) + ; + +protected_opt : ( PROTECTED )? + { #protected_opt = #(#[MODIFIERS, "MODIFIERS"], #protected_opt); } + ; + +constant_all_opt : ( CONSTANT | ALL )? + { #constant_all_opt = + #(#[MODIFIERS, "MODIFIERS"], #constant_all_opt); } + ; + +derived_or_private_or_record [RefAdaAST t, bool has_discrim] + : ( ( ABSTRACT )? NEW subtype_ind WITH ) => + abstract_opt NEW! subtype_ind WITH! + ( PRIVATE! { Set(t, PRIVATE_EXTENSION_DECLARATION); } + | record_definition[has_discrim] + { Set(t, DERIVED_RECORD_EXTENSION); } + ) + | NEW! subtype_ind { Set(t, ORDINARY_DERIVED_TYPE_DECLARATION); } + | abstract_tagged_limited_opt + ( PRIVATE! { Set(t, PRIVATE_TYPE_DECLARATION); } + | record_definition[has_discrim] + { Set(t, RECORD_TYPE_DECLARATION); } + ) + ; + +abstract_opt : ( ABSTRACT )? + { #abstract_opt = #(#[MODIFIERS, "MODIFIERS"], #abstract_opt); } + ; + +record_definition [bool has_discrim] + : RECORD! component_list[has_discrim] END! RECORD! + | NuLL! RECORD! // Thus the component_list is optional in the tree. + ; + +component_list [bool has_discrim] + : NuLL! SEMI! // Thus the component_list is optional in the tree. + | component_items ( variant_part { has_discrim }? )? + | empty_component_items variant_part { has_discrim }? + ; + +component_items : ( pragma | comp_decl )+ + { #component_items = + #(#[COMPONENT_ITEMS, + "COMPONENT_ITEMS"], #component_items); } + ; + +empty_component_items : + { #empty_component_items = + #(#[COMPONENT_ITEMS, + "COMPONENT_ITEMS"], #empty_component_items); } + ; + +variant_part : c:CASE^ discriminant_direct_name IS! variant_s END! CASE! SEMI! + { Set (#c, VARIANT_PART); } + ; + +discriminant_direct_name : IDENTIFIER // TBD: symtab lookup. + ; + +variant_s : ( variant )+ + { #variant_s = #(#[VARIANTS, "VARIANTS"], #variant_s); } + ; + +variant : w:WHEN^ choice_s RIGHT_SHAFT! component_list[true] + { Set (#w, VARIANT); } + ; + +choice_s : choice ( PIPE^ choice )* + ; + +choice : OTHERS + | (discrete_with_range) => discrete_with_range + | expression // ( DOT_DOT^ simple_expression )? + ; // No, that's already in discrete_with_range + +discrete_with_range : (mark_with_constraint) => mark_with_constraint + | range + ; + +mark_with_constraint : subtype_mark range_constraint + { #mark_with_constraint = + #(#[MARK_WITH_CONSTRAINT, + "MARK_WITH_CONSTRAINT"], #mark_with_constraint); } + ; + +abstract_tagged_limited_opt + : ( ABSTRACT TAGGED! | TAGGED )? + ( LIMITED )? + { #abstract_tagged_limited_opt = + #(#[MODIFIERS, "MODIFIERS"], #abstract_tagged_limited_opt); } + ; + +local_enum_name : IDENTIFIER // to be refined: do a symbol table lookup + ; + +enumeration_aggregate : parenth_values + ; + +aliased_constant_opt : ( ALIASED )? ( CONSTANT )? + { #aliased_constant_opt = + #(#[MODIFIERS, "MODIFIERS"], #aliased_constant_opt); } + ; + +generic_decl [bool lib_level] + : g:GENERIC^ generic_formal_part_opt + ( PACKAGE! def_id[lib_level] + ( renames { Set(#g, GENERIC_PACKAGE_RENAMING); } + | IS! pkg_spec_part { Set(#g, GENERIC_PACKAGE_DECLARATION); } + ) + | PROCEDURE! def_id[lib_level] formal_part_opt + ( renames { Set(#g, GENERIC_PROCEDURE_RENAMING); } + // ^^^ Semantic check must ensure that the (generic_formal)* + // after GENERIC is not given here. + | { Set(#g, GENERIC_PROCEDURE_DECLARATION); pop_def_id(); } + ) + | FUNCTION! def_designator[lib_level] function_tail + ( renames { Set(#g, GENERIC_FUNCTION_RENAMING); } + // ^^^ Semantic check must ensure that the (generic_formal)* + // after GENERIC is not given here. + | { Set(#g, GENERIC_FUNCTION_DECLARATION); pop_def_id(); } + ) + ) + SEMI! + ; + +generic_formal_part_opt : ( use_clause | pragma | generic_formal_parameter )* + { #generic_formal_part_opt = + #(#[GENERIC_FORMAL_PART, + "GENERIC_FORMAL_PART"], + #generic_formal_part_opt); } + ; + +generic_formal_parameter : + ( t:TYPE^ def_id[false] + ( IS! + ( LPAREN! BOX! RPAREN! + { Set (#t, FORMAL_DISCRETE_TYPE_DECLARATION); } + | RANGE! BOX! + { Set (#t, FORMAL_SIGNED_INTEGER_TYPE_DECLARATION); } + | MOD! BOX! + { Set (#t, FORMAL_MODULAR_TYPE_DECLARATION); } + | DELTA! BOX! + ( DIGITS! BOX! + { Set (#t, FORMAL_DECIMAL_FIXED_POINT_DECLARATION); } + | { Set (#t, FORMAL_ORDINARY_FIXED_POINT_DECLARATION); } + ) + | DIGITS! BOX! + { Set (#t, FORMAL_FLOATING_POINT_DECLARATION); } + | array_type_definition[#t] + | access_type_definition[#t] + | empty_discrim_opt discriminable_type_definition[#t] + ) + | discrim_part IS! discriminable_type_definition[#t] + ) + { pop_def_id(); } + | w:WITH^ ( PROCEDURE! def_id[false] formal_part_opt subprogram_default_opt + { Set(#w, FORMAL_PROCEDURE_DECLARATION); } + | FUNCTION! def_designator[false] function_tail subprogram_default_opt + { Set(#w, FORMAL_FUNCTION_DECLARATION); } + | PACKAGE! def_id[false] IS! NEW! compound_name formal_package_actual_part_opt + { Set(#w, FORMAL_PACKAGE_DECLARATION); } + ) + { pop_def_id(); } + | parameter_specification + ) + SEMI! + ; + +discriminable_type_definition [RefAdaAST t] + : ( ( ABSTRACT )? NEW subtype_ind WITH ) => + abstract_opt NEW! subtype_ind WITH! PRIVATE! + { Set (t, FORMAL_PRIVATE_EXTENSION_DECLARATION); } + | NEW! subtype_ind + { Set (t, FORMAL_ORDINARY_DERIVED_TYPE_DECLARATION); } + | abstract_tagged_limited_opt PRIVATE! + { Set (t, FORMAL_PRIVATE_TYPE_DECLARATION); } + ; + +subprogram_default_opt : ( IS! ( BOX | name ) )? + ; + +formal_package_actual_part_opt + : ( LPAREN! ( BOX | defining_identifier_list ) RPAREN! )? + ; + +subprog_decl_or_rename_or_inst_or_body [bool lib_level] + { RefAdaAST t; } + : p:PROCEDURE^ def_id[lib_level] + ( generic_subp_inst + { Set(#p, GENERIC_PROCEDURE_INSTANTIATION); } + | formal_part_opt + ( renames { Set(#p, PROCEDURE_RENAMING_DECLARATION); } + | IS! ( separate_or_abstract[#p] + | body_part { Set(#p, PROCEDURE_BODY); } + ) + | { pop_def_id(); + Set(#p, PROCEDURE_DECLARATION); } + ) + SEMI! + ) + | f:FUNCTION^ def_designator[lib_level] + ( generic_subp_inst + { Set(#f, GENERIC_FUNCTION_INSTANTIATION); } + | function_tail + ( renames { Set(#f, FUNCTION_RENAMING_DECLARATION); } + | IS! ( separate_or_abstract[#f] + | body_part { Set(#f, FUNCTION_BODY); } + ) + | { pop_def_id(); + Set(#f, FUNCTION_DECLARATION); } + ) + SEMI! + ) + ; + +body_part : declarative_part block_body end_id_opt! + ; + +declarative_part : ( pragma | declarative_item )* + { #declarative_part = + #(#[DECLARATIVE_PART, "DECLARATIVE_PART"], + #declarative_part); } + ; + +// A declarative_item may appear in the declarative part of any body. +declarative_item : + ( pkg:PACKAGE^ ( body_is + ( separate { Set(#pkg, PACKAGE_BODY_STUB); } + | pkg_body_part end_id_opt! + { Set(#pkg, PACKAGE_BODY); } + ) + SEMI! + | def_id[false] spec_decl_part[#pkg] + ) + | tsk:TASK^ ( body_is + ( separate { Set(#tsk, TASK_BODY_STUB); } + | body_part { Set(#tsk, TASK_BODY); } + ) + SEMI! + | task_type_or_single_decl[#tsk] + ) + | pro:PROTECTED^ + ( body_is + ( separate { Set(#pro, PROTECTED_BODY_STUB); } + | prot_op_bodies_opt end_id_opt! + { Set(#pro, PROTECTED_BODY); } + ) + | prot_type_or_single_decl[#pro] + ) + SEMI! + | subprog_decl_or_rename_or_inst_or_body[false] + | decl_common + ) + /* DECLARATIVE_ITEM is just a pass-thru node so we omit it. + Objections anybody? + { #declarative_item = + #(#[DECLARATIVE_ITEM, + "DECLARATIVE_ITEM"], #declarative_item); } + */ + ; + +body_is : BODY! def_id[false] IS! + ; + +separate : SEPARATE! { pop_def_id(); } + ; + +pkg_body_part : declarative_part block_body_opt + ; + +block_body_opt : ( BEGIN! handled_stmt_s )? + { #block_body_opt = + #(#[BLOCK_BODY_OPT, + "BLOCK_BODY_OPT"], #block_body_opt); } + ; + +prot_op_bodies_opt : ( entry_body + | subprog_decl_or_body + | pragma + )* + { #prot_op_bodies_opt = + #(#[PROT_OP_BODIES_OPT, + "PROT_OP_BODIES_OPT"], #prot_op_bodies_opt); } + ; + +subprog_decl_or_body + : p:PROCEDURE^ def_id[false] formal_part_opt + ( IS! body_part { Set(#p, PROCEDURE_BODY); } + | { pop_def_id(); Set(#p, PROCEDURE_DECLARATION); } + ) + SEMI! + | f:FUNCTION^ def_designator[false] function_tail + ( IS! body_part { Set(#f, FUNCTION_BODY); } + | { pop_def_id(); Set(#f, FUNCTION_DECLARATION); } + ) + SEMI! + ; + +block_body : b:BEGIN^ handled_stmt_s + { Set(#b, BLOCK_BODY); } + ; + +handled_stmt_s : statements except_handler_part_opt + { #handled_stmt_s = + #(#[HANDLED_SEQUENCE_OF_STATEMENTS, + "HANDLED_SEQUENCE_OF_STATEMENTS"], #handled_stmt_s); } + ; + +statements : ( pragma | statement )+ + { #statements = #(#[SEQUENCE_OF_STATEMENTS, + "SEQUENCE_OF_STATEMENTS"], #statements); } + ; + +statement : def_label_opt + ( null_stmt + | exit_stmt + | return_stmt + | goto_stmt + | delay_stmt + | abort_stmt + | raise_stmt + | requeue_stmt + | accept_stmt + | select_stmt + | if_stmt + | case_stmt + | loop_stmt SEMI! + | block END! SEMI! + | statement_identifier + ( loop_stmt id_opt! SEMI! // FIXME: The statement_identifier + | block end_id_opt! SEMI! // is not promoted into the tree. + ) + | call_or_assignment + // | code_stmt // TBD: resolve ambiguity + ) + { #statement = #(#[STATEMENT, "STATEMENT"], #statement); } + ; + +def_label_opt : ( LT_LT! IDENTIFIER GT_GT! )? + { #def_label_opt = #(#[LABEL_OPT, "LABEL_OPT"], #def_label_opt); } + ; + +null_stmt : s:NuLL SEMI! + { Set(#s, NULL_STATEMENT); } + ; + +if_stmt : s:IF^ cond_clause elsifs_opt + else_opt + END! IF! SEMI! + { Set(#s, IF_STATEMENT); } + ; + +cond_clause : condition c:THEN^ statements + { Set(#c, COND_CLAUSE); } + ; + +condition : expression + // { #condition = #(#[CONDITION, "CONDITION"], #condition); } + ; + +elsifs_opt : ( ELSIF! cond_clause )* + { #elsifs_opt = #(#[ELSIFS_OPT, "ELSIFS_OPT"], #elsifs_opt); } + ; + +else_opt : ( ELSE! statements )? + { #else_opt = #(#[ELSE_OPT, "ELSE_OPT"], #else_opt); } + ; + +case_stmt : s:CASE^ expression IS! alternative_s END! CASE! SEMI! + { Set(#s, CASE_STATEMENT); } + ; + +alternative_s : ( case_statement_alternative )+ + ; + +case_statement_alternative : s:WHEN^ choice_s RIGHT_SHAFT! statements + { Set(#s, CASE_STATEMENT_ALTERNATIVE); } + ; + +loop_stmt : iteration_scheme_opt + LOOP! statements END! LOOP! // basic_loop + { #loop_stmt = #(#[LOOP_STATEMENT, "LOOP_STATEMENT"], #loop_stmt); } + ; + +iteration_scheme_opt : ( WHILE^ condition + | FOR^ IDENTIFIER IN! reverse_opt discrete_subtype_definition + )? + { #iteration_scheme_opt = + #(#[ITERATION_SCHEME_OPT, + "ITERATION_SCHEME_OPT"], #iteration_scheme_opt); } + ; + +reverse_opt : ( REVERSE )? + { #reverse_opt = #(#[MODIFIERS, "MODIFIERS"], #reverse_opt); } + ; + +id_opt { RefAdaAST endid; } : + endid=definable_operator_symbol { end_id_matches_def_id (endid) }? + | n:compound_name { end_id_matches_def_id (#n) }? + /* Ordinarily we would need to be stricter here, i.e. + match compound_name only for the library-level case + (and IDENTIFIER otherwise), but end_id_matches_def_id + does the right thing for us. */ + | { pop_def_id(); } + ; + +end_id_opt : END! id_opt + ; + +/* Note: This rule should really be `statement_identifier_opt'. + However, manual disambiguation of `loop_stmt' from `block' + in the presence of the statement_identifier in `statement' + results in this rule. The case of loop_stmt/block given + without the statement_identifier is directly coded in + `statement'. */ +statement_identifier! : n:IDENTIFIER COLON! + { push_def_id(#n); } + ; + +/* +statement_identifier_opt : ( n:IDENTIFIER COLON! { push_def_id(#n); } )? + { #statement_identifier_opt = + #(#[STATEMENT_IDENTIFIER_OPT, + "STATEMENT_IDENTIFIER_OPT"], #statement_identifier_opt); } + ; + */ + +block : declare_opt block_body + { #block = #(#[BLOCK_STATEMENT, "BLOCK_STATEMENT"], #block); } + ; + +declare_opt : ( DECLARE! declarative_part )? + { #declare_opt = #(#[DECLARE_OPT, "DECLARE_OPT"], #declare_opt); } + ; + +exit_stmt : s:EXIT^ ( label_name )? ( WHEN condition )? SEMI! + { Set(#s, EXIT_STATEMENT); } + ; + +label_name : IDENTIFIER + ; + +return_stmt : s:RETURN^ ( expression )? SEMI! + { Set(#s, RETURN_STATEMENT); } + ; + +goto_stmt : s:GOTO^ label_name SEMI! + { Set(#s, GOTO_STATEMENT); } + ; + +call_or_assignment : // procedure_call is in here. + name ( ASSIGN! expression + { #call_or_assignment = + #(#[ASSIGNMENT_STATEMENT, + "ASSIGNMENT_STATEMENT"], #call_or_assignment); } + | { #call_or_assignment = + #(#[CALL_STATEMENT, + "CALL_STATEMENT"], #call_or_assignment); } + /* Preliminary. Use semantic analysis to produce + {PROCEDURE|ENTRY}_CALL_STATEMENT. */ + ) + SEMI! + ; + +entry_body : e:ENTRY^ def_id[false] entry_body_formal_part entry_barrier IS! + body_part SEMI! + { Set (#e, ENTRY_BODY); } + ; + +entry_body_formal_part : entry_index_spec_opt formal_part_opt + ; + +entry_index_spec_opt : + ( (LPAREN FOR) => + LPAREN! FOR! def_id[false] IN! discrete_subtype_definition RPAREN! + | /* empty */ + ) + { #entry_index_spec_opt = + #(#[ENTRY_INDEX_SPECIFICATION, + "ENTRY_INDEX_SPECIFICATION"], #entry_index_spec_opt); } + ; + +entry_barrier : WHEN! condition + ; + +entry_call_stmt : name SEMI! // Semantic analysis required, for example + // to ensure `name' is an entry. + { #entry_call_stmt = + #(#[ENTRY_CALL_STATEMENT, + "ENTRY_CALL_STATEMENT"], #entry_call_stmt); } + ; + +accept_stmt : a:ACCEPT^ def_id[false] entry_index_opt formal_part_opt + ( DO! handled_stmt_s end_id_opt! SEMI! + | SEMI! { pop_def_id(); } + ) + { Set (#a, ACCEPT_STATEMENT); } + ; + +entry_index_opt : ( (LPAREN expression RPAREN) => LPAREN! expression RPAREN! + // Looks alot like parenthesized_expr_opt, but it's not. + // We need the syn pred for the usage context in accept_stmt. + // The formal_part_opt that follows the entry_index_opt there + // creates ambiguity (due to the opening LPAREN.) + | /* empty */ + ) + { #entry_index_opt = + #(#[ENTRY_INDEX_OPT, + "ENTRY_INDEX_OPT"], #entry_index_opt); } + ; + +delay_stmt : d:DELAY^ until_opt expression SEMI! + { Set (#d, DELAY_STATEMENT); } + ; + +until_opt : ( UNTIL )? + { #until_opt = #(#[MODIFIERS, "MODIFIERS"], #until_opt); } + ; + +// SELECT_STATEMENT itself is not modeled since it is trivially +// reconstructed: +// select_statement ::= selective_accept | timed_entry_call +// | conditional_entry_call | asynchronous_select +// +select_stmt : s:SELECT^ + ( (triggering_alternative THEN ABORT) => + triggering_alternative THEN! ABORT! abortable_part + { Set (#s, ASYNCHRONOUS_SELECT); } + | selective_accept + { Set (#s, SELECTIVE_ACCEPT); } + | entry_call_alternative + ( OR! delay_alternative { Set (#s, TIMED_ENTRY_CALL); } + | ELSE! statements { Set (#s, CONDITIONAL_ENTRY_CALL); } + ) + ) + END! SELECT! SEMI! + // { Set (#s, SELECT_STATEMENT); } + ; + +triggering_alternative : ( delay_stmt | entry_call_stmt ) stmts_opt + { #triggering_alternative = + #(#[TRIGGERING_ALTERNATIVE, + "TRIGGERING_ALTERNATIVE"], #triggering_alternative); } + ; + +abortable_part : stmts_opt + { #abortable_part = + #(#[ABORTABLE_PART, + "ABORTABLE_PART"], #abortable_part); } + ; + +entry_call_alternative : entry_call_stmt stmts_opt + { #entry_call_alternative = + #(#[ENTRY_CALL_ALTERNATIVE, + "ENTRY_CALL_ALTERNATIVE"], #entry_call_alternative); } + ; + +selective_accept : guard_opt select_alternative or_select_opt else_opt + ; + +guard_opt : ( WHEN! condition RIGHT_SHAFT! ( pragma )* )? + { #guard_opt = #(#[GUARD_OPT, "GUARD_OPT"], #guard_opt); } + ; + +select_alternative // Not modeled since it's just a pass-through. + : accept_alternative + | delay_alternative + | t:TERMINATE SEMI! { Set(#t, TERMINATE_ALTERNATIVE); } + ; + +accept_alternative : accept_stmt stmts_opt + { #accept_alternative = + #(#[ACCEPT_ALTERNATIVE, + "ACCEPT_ALTERNATIVE"], #accept_alternative); } + ; + +delay_alternative : delay_stmt stmts_opt + { #delay_alternative = + #(#[DELAY_ALTERNATIVE, + "DELAY_ALTERNATIVE"], #delay_alternative); } + ; + +stmts_opt : ( pragma | statement )* + ; + +or_select_opt : ( OR! guard_opt select_alternative )* + { #or_select_opt = + #(#[OR_SELECT_OPT, "OR_SELECT_OPT"], #or_select_opt); } + ; + +abort_stmt : a:ABORT^ name ( COMMA! name )* SEMI! + { Set (#a, ABORT_STATEMENT); } + ; + +except_handler_part_opt : ( EXCEPTION! ( exception_handler )+ )? + { #except_handler_part_opt = + #(#[EXCEPT_HANDLER_PART_OPT, + "EXCEPT_HANDLER_PART_OPT"], #except_handler_part_opt); } + ; + +exception_handler : w:WHEN^ identifier_colon_opt except_choice_s RIGHT_SHAFT! + statements + { Set (#w, EXCEPTION_HANDLER); } + ; + +identifier_colon_opt : ( IDENTIFIER COLON! )? + { #identifier_colon_opt = + #(#[IDENTIFIER_COLON_OPT, + "IDENTIFIER_COLON_OPT"], #identifier_colon_opt); } + ; + +except_choice_s : exception_choice ( PIPE^ exception_choice )* + ; + +exception_choice : compound_name + | OTHERS + ; + +raise_stmt : r:RAISE^ ( compound_name )? SEMI! + { Set (#r, RAISE_STATEMENT); } + ; + +requeue_stmt : r:REQUEUE^ name ( WITH! ABORT )? SEMI! + { Set (#r, REQUEUE_STATEMENT); } + ; + +operator_call : cs:CHAR_STRING^ operator_call_tail[#cs] + ; + +operator_call_tail [RefAdaAST opstr] + : LPAREN! { is_operator_symbol(opstr->getText().c_str()) }? + value_s RPAREN! { opstr->setType(OPERATOR_SYMBOL); } + ; + +value_s : value ( COMMA! value )* + { #value_s = #(#[VALUES, "VALUES"], #value_s); } + ; + +/* +literal : NUMERIC_LIT + | CHARACTER_LITERAL + | CHAR_STRING + | NuLL + ; + */ + +expression : relation + ( a:AND^ ( THEN! { Set (#a, AND_THEN); } )? relation + | o:OR^ ( ELSE! { Set (#o, OR_ELSE); } )? relation + | XOR^ relation + )* + ; + +relation : simple_expression + ( IN^ range_or_mark + | n:NOT^ IN! range_or_mark { Set (#n, NOT_IN); } + | EQ^ simple_expression + | NE^ simple_expression + | LT_^ simple_expression + | LE^ simple_expression + | GT^ simple_expression + | GE^ simple_expression + )? + ; + +range_or_mark : (range) => range + | subtype_mark + ; + +simple_expression : signed_term + ( PLUS^ signed_term + | MINUS^ signed_term + | CONCAT^ signed_term + )* + ; + +signed_term + : p:PLUS^ term { Set(#p, UNARY_PLUS); } + | m:MINUS^ term { Set(#m, UNARY_MINUS); } + | term + ; + +term : factor ( STAR^ factor + | DIV^ factor + | MOD^ factor + | REM^ factor + )* + ; + +factor : ( NOT^ primary + | ABS^ primary + | primary ( EXPON^ primary )? + ) + ; + +primary : ( name_or_qualified + | parenthesized_primary + | allocator + | NuLL + | NUMERIC_LIT + | CHARACTER_LITERAL + | cs:CHAR_STRING^ ( operator_call_tail[#cs] )? + ) + ; + +// Temporary, to be turned into just `qualified'. +// We get away with it because `qualified' is always mentioned +// together with `name'. +// Only exception: `code_stmt', which is not yet implemented. +name_or_qualified { RefAdaAST dummy; } + : IDENTIFIER + ( DOT^ ( ALL + | IDENTIFIER + | CHARACTER_LITERAL + | dummy=is_operator + ) + | p:LPAREN^ value_s RPAREN! + { Set(#p, INDEXED_COMPONENT); } + | TIC^ ( parenthesized_primary | attribute_id ) + )* + ; + +allocator : n:NEW^ name_or_qualified + { Set(#n, ALLOCATOR); } + ; + +subunit : sep:SEPARATE^ LPAREN! compound_name RPAREN! + { Set(#sep, SUBUNIT); } + ( subprogram_body + | package_body + | task_body + | protected_body + ) + ; + +subprogram_body + : p:PROCEDURE^ def_id[false] formal_part_opt IS! body_part SEMI! + { Set(#p, PROCEDURE_BODY); } + | f:FUNCTION^ function_tail IS! body_part SEMI! + { Set(#f, FUNCTION_BODY); } + ; + +package_body : p:PACKAGE^ body_is pkg_body_part end_id_opt! SEMI! + { Set(#p, PACKAGE_BODY); } + ; + +task_body : t:TASK^ body_is body_part SEMI! + { Set(#t, TASK_BODY); } + ; + +protected_body : p:PROTECTED^ body_is prot_op_bodies_opt end_id_opt! SEMI! + { Set(#p, PROTECTED_BODY); } + ; + +// TBD +// code_stmt : qualified SEMI! +// ; + +//---------------------------------------------------------------------------- +// The Ada scanner +//---------------------------------------------------------------------------- +{ +#include "preambles.h" +} +class AdaLexer extends Lexer; + +options { + charVocabulary = '\3'..'\377'; + exportVocab = Ada; // call the vocabulary "Ada" + testLiterals = false; // don't automatically test for literals + k = 4; // number of characters of lookahead + caseSensitive = false; + caseSensitiveLiterals = false; + defaultErrorHandler = true; +} + +tokens { + // part 1: keywords + ABORT = "abort" ; + ABS = "abs" ; + ABSTRACT = "abstract" ; + ACCEPT = "accept" ; + ACCESS = "access" ; + ALIASED = "aliased" ; + ALL = "all" ; + AND = "and" ; + ARRAY = "array" ; + AT = "at" ; + BEGIN = "begin" ; + BODY = "body" ; + CASE = "case" ; + CONSTANT = "constant" ; + DECLARE = "declare" ; + DELAY = "delay" ; + DELTA = "delta" ; + DIGITS = "digits" ; + DO = "do" ; + ELSE = "else" ; + ELSIF = "elsif" ; + END = "end" ; + ENTRY = "entry" ; + EXCEPTION = "exception" ; + EXIT = "exit" ; + FOR = "for" ; + FUNCTION = "function" ; + GENERIC = "generic" ; + GOTO = "goto" ; + IF = "if" ; + IN = "in" ; + IS = "is" ; + LIMITED = "limited" ; + LOOP = "loop" ; + MOD = "mod" ; + NEW = "new" ; + NOT = "not" ; + NuLL = "null" ; + OF = "of" ; + OR = "or" ; + OTHERS = "others" ; + OUT = "out" ; + PACKAGE = "package" ; + PRAGMA = "pragma" ; + PRIVATE = "private" ; + PROCEDURE = "procedure" ; + PROTECTED = "protected" ; + RAISE = "raise" ; + RANGE = "range" ; + RECORD = "record" ; + REM = "rem" ; + RENAMES = "renames" ; + REQUEUE = "requeue" ; + RETURN = "return" ; + REVERSE = "reverse" ; + SELECT = "select" ; + SEPARATE = "separate" ; + SUBTYPE = "subtype" ; + TAGGED = "tagged" ; + TASK = "task" ; + TERMINATE = "terminate" ; + THEN = "then" ; + TYPE = "type" ; + UNTIL = "until" ; + USE = "use" ; + WHEN = "when" ; + WHILE = "while" ; + WITH = "with" ; + XOR = "xor" ; + + // part 2: RM tokens (synthetic) + ABORTABLE_PART; + ABORT_STATEMENT; + ABSTRACT_SUBPROGRAM_DECLARATION; /* => + ABSTRACT_{FUNCTION|PROCEDURE}_DECLARATION */ + ACCEPT_ALTERNATIVE; + ACCEPT_STATEMENT; + /* ACCESS_TO_FUNCTION_DEFINITION => ACCESS_TO_FUNCTION_DECLARATION */ + /* ACCESS_TO_OBJECT_DEFINITION => ACCESS_TO_OBJECT_DECLARATION */ + /* ACCESS_TO_PROCEDURE_DEFINITION => ACCESS_TO_PROCEDURE_DECLARATION */ + /* ACCESS_TYPE_DEFINITION => ACCESS_TYPE_DECLARATION */ + ALLOCATOR; + /* ARRAY_TYPE_DEFINITION => ARRAY_TYPE_DECLARATION */ + ASSIGNMENT_STATEMENT; + ASYNCHRONOUS_SELECT; + ATTRIBUTE_DEFINITION_CLAUSE; + AT_CLAUSE; + BLOCK_STATEMENT; + CASE_STATEMENT; + CASE_STATEMENT_ALTERNATIVE; + CODE_STATEMENT; + COMPONENT_DECLARATION; + COMPONENT_LIST; // not currently used as an explicit node + CONDITION; + CONDITIONAL_ENTRY_CALL; + CONTEXT_CLAUSE; + /* DECIMAL_FIXED_POINT_DEFINITION => DECIMAL_FIXED_POINT_DECLARATION */ + DECLARATIVE_ITEM; // not currently used + DECLARATIVE_PART; + DEFINING_IDENTIFIER_LIST; + DELAY_ALTERNATIVE; + DELAY_STATEMENT; + DELTA_CONSTRAINT; + /* DERIVED_TYPE_DEFINITION; => + DERIVED_RECORD_EXTENSION, ORDINARY_DERIVED_TYPE_DECLARATION */ + DIGITS_CONSTRAINT; + DISCRETE_RANGE; // Not used; instead, directly use its RHS alternatives. + DISCRIMINANT_ASSOCIATION; + DISCRIMINANT_CONSTRAINT; + DISCRIMINANT_SPECIFICATION; + ENTRY_BODY; + ENTRY_CALL_ALTERNATIVE; + ENTRY_CALL_STATEMENT; + ENTRY_DECLARATION; + ENTRY_INDEX_SPECIFICATION; + ENUMERATION_REPESENTATION_CLAUSE; + /* ENUMERATION_TYPE_DEFINITION => ENUMERATION_TYPE_DECLARATION */ + EXCEPTION_DECLARATION; + EXCEPTION_HANDLER; + EXCEPTION_RENAMING_DECLARATION; + EXIT_STATEMENT; + /* FLOATING_POINT_DEFINITION => FLOATING_POINT_DECLARATION */ + /* FORMAL_ACCESS_TYPE_DEFINITION => FORMAL_ACCESS_TYPE_DECLARATION */ + /* FORMAL_ARRAY_TYPE_DEFINITION => FORMAL_ARRAY_TYPE_DECLARATION */ + /* FORMAL_DECIMAL_FIXED_POINT_DEFINITION => + FORMAL_DECIMAL_FIXED_POINT_DECLARATION */ + /* FORMAL_DERIVED_TYPE_DEFINITION => + FORMAL_{ORDINARY_DERIVED_TYPE|PRIVATE_EXTENSION}_DECLARATION */ + /* FORMAL_DISCRETE_TYPE_DEFINITION => FORMAL_DISCRETE_TYPE_DECLARATION */ + /* FORMAL_FLOATING_POINT_DEFINITION => + FORMAL_FLOATING_POINT_DECLARATION */ + /* FORMAL_MODULAR_TYPE_DEFINITION => FORMAL_MODULAR_TYPE_DECLARATION */ + /* FORMAL_ORDINARY_FIXED_POINT_DEFINITION => + FORMAL_ORDINARY_FIXED_POINT_DECLARATION */ + FORMAL_PACKAGE_DECLARATION; + /* FORMAL_PRIVATE_TYPE_DEFINITION => FORMAL_PRIVATE_TYPE_DECLARATION */ + /* FORMAL_SIGNED_INTEGER_TYPE_DEFINITION => + FORMAL_SIGNED_INTEGER_TYPE_DECLARATION */ + /* FORMAL_SUBPROGRAM_DECLARATION; => + FORMAL_{FUNCTION|PROCEDURE}_DECLARATION */ + FORMAL_TYPE_DECLARATION; /* not used, replaced by the corresponding + finer grained declarations */ + /* FORMAL_TYPE_DEFINITION; not used at all; we use declarations + not definitions */ + FULL_TYPE_DECLARATION; /* not used, replaced by the corresponding + finer grained declarations */ + GENERIC_FORMAL_PART; + GENERIC_INSTANTIATION; /* => + GENERIC_{FUNCTION|PACKAGE|PROCEDURE}_INSTANTIATION */ + GENERIC_PACKAGE_DECLARATION; + GENERIC_RENAMING_DECLARATION; /* => + GENERIC_{FUNCTION|PACKAGE|PROCEDURE}_RENAMING */ + GENERIC_SUBPROGRAM_DECLARATION; /* => + GENERIC_{FUNCTION|PROCEDURE}_DECLARATION */ + GOTO_STATEMENT; + HANDLED_SEQUENCE_OF_STATEMENTS; + IF_STATEMENT; + INCOMPLETE_TYPE_DECLARATION; + INDEXED_COMPONENT; + INDEX_CONSTRAINT; + LIBRARY_ITEM; + LOOP_STATEMENT; + /* MODULAR_TYPE_DEFINITION => MODULAR_TYPE_DECLARATION */ + NAME; + NULL_STATEMENT; + NUMBER_DECLARATION; + OBJECT_DECLARATION; + OBJECT_RENAMING_DECLARATION; + OPERATOR_SYMBOL; + /* ORDINARY_FIXED_POINT_DEFINITION => ORDINARY_FIXED_POINT_DECLARATION */ + PACKAGE_BODY; + PACKAGE_BODY_STUB; + PACKAGE_RENAMING_DECLARATION; + PACKAGE_SPECIFICATION; + PARAMETER_SPECIFICATION; + PREFIX; + PRIMARY; + PRIVATE_EXTENSION_DECLARATION; + PRIVATE_TYPE_DECLARATION; + PROCEDURE_CALL_STATEMENT; // NYI, using CALL_STATEMENT for now. + PROTECTED_BODY; + PROTECTED_BODY_STUB; + PROTECTED_TYPE_DECLARATION; + RAISE_STATEMENT; + RANGE_ATTRIBUTE_REFERENCE; + RECORD_REPRESENTATION_CLAUSE; + /* RECORD_TYPE_DEFINITION => RECORD_TYPE_DECLARATION */ + REQUEUE_STATEMENT; + RETURN_STATEMENT; + SELECTIVE_ACCEPT; + SELECT_ALTERNATIVE; /* Not used - instead, we use the finer grained rules + ACCEPT_ALTERNATIVE | DELAY_ALTERNATIVE + | TERMINATE_ALTERNATIVE */ + SELECT_STATEMENT; /* Not used - instead, we use the finer grained rules + SELECTIVE_ACCEPT | TIMED_ENTRY_CALL + | CONDITIONAL_ENTRY_CALL | ASYNCHRONOUS_SELECT */ + SEQUENCE_OF_STATEMENTS; + /* SIGNED_INTEGER_TYPE_DEFINITION => SIGNED_INTEGER_TYPE_DECLARATION */ + SINGLE_PROTECTED_DECLARATION; + SINGLE_TASK_DECLARATION; + STATEMENT; + SUBPROGRAM_BODY; /* => {FUNCTION|PROCEDURE}_BODY */ + SUBPROGRAM_BODY_STUB; /* => {FUNCTION|PROCEDURE}_BODY_STUB */ + SUBPROGRAM_DECLARATION; /* => {FUNCTION|PROCEDURE}_DECLARATION */ + SUBPROGRAM_RENAMING_DECLARATION; /* => + {FUNCTION|PROCEDURE}_RENAMING_DECLARATION */ + SUBTYPE_DECLARATION; + SUBTYPE_INDICATION; + SUBTYPE_MARK; + SUBUNIT; + TASK_BODY; + TASK_BODY_STUB; + TASK_TYPE_DECLARATION; + TERMINATE_ALTERNATIVE; + TIMED_ENTRY_CALL; + TRIGGERING_ALTERNATIVE; + TYPE_DECLARATION; /* not used, replaced by the corresponding + finer grained declarations */ + USE_CLAUSE; + USE_TYPE_CLAUSE; + VARIANT; + VARIANT_PART; + WITH_CLAUSE; + + // part 3: Non-RM synthetic tokens. + // They exist mainly to normalize the node structure with respect to + // optional items. (Without them, the presence or absence of an optional + // item would change the node layout, but we want a fixed layout.) + ABSTRACT_FUNCTION_DECLARATION; + ABSTRACT_PROCEDURE_DECLARATION; + ACCESS_TO_FUNCTION_DECLARATION; + ACCESS_TO_OBJECT_DECLARATION; + ACCESS_TO_PROCEDURE_DECLARATION; + ACCESS_TYPE_DECLARATION; /* not used, replaced by + ACCESS_TO_{FUNCTION|OBJECT|PROCEDURE}_DECLARATION + */ + ARRAY_OBJECT_DECLARATION; + ARRAY_TYPE_DECLARATION; + AND_THEN; + BASIC_DECLARATIVE_ITEMS_OPT; + BLOCK_BODY; + BLOCK_BODY_OPT; + CALL_STATEMENT; // See {PROCEDURE|ENTRY}_CALL_STATEMENT + COMPONENT_CLAUSES_OPT; + COMPONENT_ITEMS; + COND_CLAUSE; + DECIMAL_FIXED_POINT_DECLARATION; + DECLARE_OPT; + DERIVED_RECORD_EXTENSION; + DERIVED_TYPE_DECLARATION; + DISCRETE_SUBTYPE_DEF_OPT; + DISCRIMINANT_SPECIFICATIONS; + DISCRIM_PART_OPT; + ELSE_OPT; + ELSIFS_OPT; + ENTRY_INDEX_OPT; + ENUMERATION_TYPE_DECLARATION; + EXCEPT_HANDLER_PART_OPT; + EXTENSION_OPT; + FLOATING_POINT_DECLARATION; + /* FORMAL_ACCESS_TYPE_DECLARATION => ACCESS_TYPE_DECLARATION */ + /* FORMAL_ARRAY_TYPE_DECLARATION => ARRAY_TYPE_DECLARATION */ + FORMAL_DECIMAL_FIXED_POINT_DECLARATION; + FORMAL_DISCRETE_TYPE_DECLARATION; + FORMAL_FLOATING_POINT_DECLARATION; + FORMAL_FUNCTION_DECLARATION; + FORMAL_MODULAR_TYPE_DECLARATION; + FORMAL_ORDINARY_DERIVED_TYPE_DECLARATION; + FORMAL_ORDINARY_FIXED_POINT_DECLARATION; + FORMAL_PART_OPT; + FORMAL_PRIVATE_EXTENSION_DECLARATION; + FORMAL_PRIVATE_TYPE_DECLARATION; + FORMAL_PROCEDURE_DECLARATION; + FORMAL_SIGNED_INTEGER_TYPE_DECLARATION; + FUNCTION_BODY; + FUNCTION_BODY_STUB; + FUNCTION_DECLARATION; + FUNCTION_RENAMING_DECLARATION; + GENERIC_FUNCTION_DECLARATION; + GENERIC_FUNCTION_INSTANTIATION; + GENERIC_FUNCTION_RENAMING; + GENERIC_PACKAGE_INSTANTIATION; + GENERIC_PACKAGE_RENAMING; + GENERIC_PROCEDURE_DECLARATION; + GENERIC_PROCEDURE_INSTANTIATION; + GENERIC_PROCEDURE_RENAMING; + GUARD_OPT; + IDENTIFIER_COLON_OPT; + INIT_OPT; + ITERATION_SCHEME_OPT; + LABEL_OPT; + MARK_WITH_CONSTRAINT; + MODIFIERS; /* Possible values: abstract access aliased all constant in + limited out private protected reverse tagged */ + MODULAR_TYPE_DECLARATION; + MOD_CLAUSE_OPT; + // NAME_OR_QUALIFIED; + NOT_IN; + ORDINARY_DERIVED_TYPE_DECLARATION; + ORDINARY_FIXED_POINT_DECLARATION; + OR_ELSE; + OR_SELECT_OPT; + PARENTHESIZED_PRIMARY; + // PARENTHESIZED_VALUES; + // PARENTHESIZED_VALUES_OPT; + PRIVATE_TASK_ITEMS_OPT; + PROCEDURE_BODY; + PROCEDURE_BODY_STUB; + PROCEDURE_DECLARATION; + PROCEDURE_RENAMING_DECLARATION; + PROT_MEMBER_DECLARATIONS; + PROT_OP_BODIES_OPT; + PROT_OP_DECLARATIONS; + RANGED_EXPRS; // ugh, what an ugly name + RECORD_TYPE_DECLARATION; + SELECTOR_NAMES_OPT; + SIGNED_INTEGER_TYPE_DECLARATION; + TASK_ITEMS_OPT; + UNARY_MINUS; + UNARY_PLUS; + VALUE; + VALUES; + VARIANTS; +} + +{ + ANTLR_LEXER_PREAMBLE +} + +//---------------------------------------------------------------------------- +// OPERATORS +//---------------------------------------------------------------------------- +COMMENT_INTRO : "--" ; +DOT_DOT : ".." ; +LT_LT : "<<" ; +BOX : "<>" ; +GT_GT : ">>" ; +ASSIGN : ":=" ; +RIGHT_SHAFT : "=>" ; +NE : "/=" ; +LE : "<=" ; +GE : ">=" ; +EXPON : "**" ; +PIPE : '|' ; +CONCAT : '&' ; +DOT : '.' ; +EQ : '=' ; +LT_ : '<' ; +GT : '>' ; +PLUS : '+' ; +MINUS : '-' ; +STAR : '*' ; +DIV : '/' ; +LPAREN : '(' ; +RPAREN : ')' ; +COLON : ':' ; +COMMA : ',' ; +SEMI : ';' ; + +TIC : { LA(3)!='\'' }? '\'' ; + // condition needed to disambiguate from CHARACTER_LITERAL + + +// Literals. + +// Rule for IDENTIFIER: testLiterals is set to true. This means that +// after we match the rule, we look in the literals table to see if +// it's a keyword or really an identifier. +IDENTIFIER + options {testLiterals=true;} + : ( 'a'..'z' ) ( ('_')? ( 'a'..'z'|'0'..'9' ) )* + ; + +CHARACTER_LITERAL : { LA(3)=='\'' }? + // condition needed to disambiguate from TIC + "'" . "'" + ; + +CHAR_STRING : '"' ("\"\"" | ~('"'))* '"' + ; + +NUMERIC_LIT : ( DIGIT )+ + ( '#' BASED_INTEGER ( '.' BASED_INTEGER )? '#' + | ( '_' ( DIGIT )+ )+ // INTEGER + )? + ( { LA(2)!='.' }? //&& LA(3)!='.' }? + ( '.' ( DIGIT )+ ( '_' ( DIGIT )+ )* ( EXPONENT )? + | EXPONENT + ) + )? + ; + +// a couple protected methods to assist in matching the various numbers + +protected +DIGIT : ( '0'..'9' ) ; + +protected +EXPONENT : ('e') ('+'|'-')? ( DIGIT )+ ; + +protected +EXTENDED_DIGIT : ( DIGIT | 'a'..'f' ) ; + +protected +BASED_INTEGER : ( EXTENDED_DIGIT ) ( ('_')? EXTENDED_DIGIT )* ; + + +// Whitespace -- ignored +WS_ : ( ' ' + | '\t' + | '\f' + // handle newlines + | ( "\r\n" // Evil DOS + | '\r' // Macintosh + | '\n' // Unix (the right way) + ) + { newline(); } + ) + { $setType(antlr::Token::SKIP); } + ; + +// Single-line comments +COMMENT : ( COMMENT_INTRO (~('\n'|'\r'))* ('\n'|'\r'('\n')?) ) + { $setType(antlr::Token::SKIP); newline(); } + ; + + diff --git a/topics/grammars/ada/laemmel-verhoef/README.txt b/topics/grammars/ada/laemmel-verhoef/README.txt index 4d163aaa..2296786e 100644 --- a/topics/grammars/ada/laemmel-verhoef/README.txt +++ b/topics/grammars/ada/laemmel-verhoef/README.txt @@ -1,4 +1,4 @@ -iBrowsable Ada 95 Grammar +Browsable Ada 95 Grammar Copyright (C) 2000 Ralf Lämmel (CWI, Amsterdam) & Chris Verhoef (Free University, Amsterdam) Full copyright information including the copyright information for the underlying Ada 95 Reference Manual are found here. diff --git a/topics/grammars/ada/lncs-1246/src.syntax.summary.txt b/topics/grammars/ada/lncs-1246/src.syntax.summary.txt index 5a8864df..d66e3aef 100644 --- a/topics/grammars/ada/lncs-1246/src.syntax.summary.txt +++ b/topics/grammars/ada/lncs-1246/src.syntax.summary.txt @@ -25,4 +25,519 @@ or a single graphic_character other than a quotation mark. 2.8: pragma ::= pragma identifier [(pragma_argumenLassociation {, pragma__argument_association])]; 2.8: pragma_argumenLassociation ::= -[pragmo_arg~ent_identifier=>] name [ [pragma_arg~entidentifier=>] expression \ No newline at end of file +[pragmo_arg~ent_identifier=>] name [ [pragma_arg~entidentifier=>] expression +3.1: +basic_declaration ::= typedeclaration I subtype_declaration +I object_declaration I number_declaration I subprogram_declaration Iabstract_subprogram_declaration I package_declaration I renaming_declaration I exception_declaration I generic_declaration I genedc_instantiation +3.1: +defining_identifier ::= identifier +3.2.1: type_declaration ::= full_type_declaration +Iincomplete_type declaration I pdvate_type declaration I private_extension_declaration +3.2.]: full_type_declaration ::= +type defining_identifier [known_discdminant_part] is type_definition; I task_type_declaration I protectedtype_declaration +3.2.1: type_definition ::= +enumeration_type_definition I integer_type_definition I real_type_definition I array_type_definition I record_type_definition I access_type_definiUon I derived_type_definition +3.2.2: subtype_declarafion ::= +subtype defining_identifier is subtype_indication; +3.2.2: subtype_indication ::= subtype_mark [constraint] +3.2.2: subtype_mark ::= subtype_name +3.2.2: +constraint ::= scalar_constraint I composite_constraint +3.2.2: scalar_constraint ::= +range_constraint I digits_constraint I delta_constraint +3.2.2: composite_constraint ::= +index constraint I discriminant_.constralnt +3.3.1: +object_declaration ::= defining_identifier_list : [a|iased] [constant] subtype_indication [:= expression]; +I defining_idanfifier_list : [aHased] [constant] array_type_definition [:= expression]; I single_task_declaration I single_protected_declaration +3.3.1: defining_identifier_list ::= +defining identifier {, defining_identifier} +3.3.2: number_declaration ::= +defining_identifier_list : constant := static_expression; 3.4: +derived_type_definition ::= [abstract] new parent_subtype_indication[record_extension_part] 3.5: +range_constraint ::= range range +3.5: +range ::= range_attribute_reference I simple_expression .. simple_expression +3.5.1: enumeration_type_definition ::= +(enumerationJiteral_specification {, enumeration_litsral_specification }) +3.5.1: +enumeration_literal_specification ::= defining_identifier I defining_character literal +3.5.1: +defining_character_literal ::= character_literal +3.5.4: integer type_definition ::= signed_integer_type_definition I modular__type_definition +3.5.4: signed_integer_type_definition ::= range static_simple_expression .. static_simple_expression +3.5.4: modular_type_definition ::= rood staticexpression +3.5.6: +real__type_definition ::= floating_poinLdetinition Ifixed_point_definition +3.5.7: +floating_poinLdefinition ::= digits staticexpression [real_range_specification] +3.5.7: +real_range_specifica'don ::= +rangestatic_simple_expression ..staticsimple_expression 3.5.9: +fixed_pointdefinition ::= ordinary_fixed_pointdefinition I decimal_fixedpoint_definition +3.5.9: ordinary_fixed_point_definition ::= +delta static_expression real_range_specification +3.5.9: +decimal_fixed_point_definition ::= delta static_expression digits static_expression [real_range_specification] +3.5.9: +digits_constraint ::= digits static_expression [range_constraint] +3.6: array_type_definition ::= +unconstrainedarray_definition Iconstrained_array_definition +3.6: +unconstrained_array_definition ::= array(index_subtype_definition {, index_subtype_definition}) of component_definition +3.6: index_subtype_definition ::= subtype_mark range <> +3.6: +constrained_array_definition ::= array (discrete_subtypedefinition {, discrete_subtype_definition }) of component_definition +3.6: +discrete_subtype_definition ::= discrete_subtype_indication I range 3.6: +componenLdefinition ::= [afiased] subtype_indication +3.6.1: index constraint ::= (discrate_range {, discrete_range}) +3.6.1: discrete_range ::= discrete_subtype_indication I range +3.7: +discriminantpart ::= unknown_discriminent_part I known_discriminant part +3.7: +unknown_discriminant_part ::= (<>) +3.7: known_discriminant part ::= +(discriminant_specification {; discdminant_specification }) +3.7: +discriminant_specification ::= defining_identifier_list : subtype_mark [:= default_expression] +I defining_identifier_list : access_definition [:= default.expression] 3.7: +defaulLexpression ::= expression +3.7.1: +discriminanLconstraint ::= (discriminant_association {, discriminanLassociation }) +3.7.1: +discriminant_association ::= [discriminant_selector_name {I discriminant_selector_name } =>] expression +3.8: record type definition ::= [[abstract] tagged] [limited] record_definition +3.8: +recorddefinition ::= +record +component_list +end record Inull record +3.8: +component_list ::= componenLitem {componenLitem} +I {component_item} variant_part +I null; 3.8: +component_item ::= componenLdeclaration I representation_clause +3.8: +componentdeclaration ::= defining_identifier_list : componentdefinition [:= defauit__expression]; +3.8.1: variant_part ::= +case discriminantdirecLname is variant +{variant} end ease; +3.8.1: variant ::= +when discrete_choice_list => component list +3.8,1: +discrete_choice_list ::= discrete_choice {I discrete_choice} +discrete_choice ::= expression I discrete_range I others +3.9.1: record extension_part ::= with record_definition +3.10: access_type_definition ::= +accessjo objecLdefinition I accessjo subpregram_definition +3.10: access., to object__definition ::= +acceSS[general_access_modifier] subtype_indication +3.10: general_access_modifier ::= all I constant +3.10: +accessto_subprogram_definition ::= access [protected] procedure parameter_profile +I access [protected] function parameter_and_rasult_profile +3.10: +access_definition ::= access subtype_mark +3.10.1: +incomplete_type_declaration ::= type defining_identifier [discriminant_part]; +3.11: +declarative_part ::= {declarative_item} +3.11: +declarative_item ::= basic_declarative_item I body +3.11: +basic_declarative_item ::= basic_declaration I representation_clause I use_clause +3.11: body ::= proper body I body_stub +3.11: +proper_body ::= subprogram_body I package_body I task_body I protected_body +4.1: +name ::= direcLname +I indexed_component I selected_component I type_conversion I character_literal +I expnciLdereference I slice I attribute_reference I function_call +4.1: direct_name ::= identifierIoperatoLsymbol +4.1: +prefix ::= name I implicit_dereference +4.1: +explicit__dereference ::= name.all +4.1: impliciLdereference ::= name +4.1.1: indexed_component ::= prefix(expression {, expression}) +4.1.2: +slice ::= prefix(discrete_range) +4.1.3: selected_component ::= prefix, selector_name +4.1.3: selector_name ::= identifier I character_literal I operator_symbol +4.1.4: +attribute_reference ::= prefix'attribute_designator +4.1.4: +attribute_designator ::= +identifier[(stafic_expression)] +I Access I Delta I Digits +4.1.4: range_attribute_reference ::= prefix'range_attribute_designator +4.1.4: range_attribute_designator ::= Range[(static_expression)] +4.3: +aggregate ::= record_aggregate I extension_aggregate I array_aggregate +4.3.1: +record_aggregate ::= (record_componenLassociation list) +4.3,1: record_component_association_list ::= +record_componenLassociation {, record component association} +Inull record +4.3.1: +record_component_association ::= [ componenLchoice list => ] expression +4.3.1: +componenLchoice list ::= +component_selector name { I component.selector_name} +I others +4.3.2: extension_aggregate ::= +(ancestor part with record_componenLassociation_list) +4.3.2: ancestor_part ::= expression I subtype_mark +4.3.3: array aggregate ::= +positional_array_aggregate I named array aggregate +4.3.3: positional_array aggregate ::= +(expression, expression {, expression}) I (expression {, expression }, others => expression) +4.3.3: named_array._aggregate ::= +(array_componentassociation {, array_componenLassociation }) +4.3.3: arraycomponent_association ::= +discrete choice list => expression +4.4: expression ::= +relation {and relation} I relation {and then relation} I relation {or relation} I relation {or else relation} I relation {xor relation} +4.4: relation ::= +simple_expression [relational_operator simple_expression} I simple_expression [not] in range I simple_expression [not] in subtype_mark +4.4: simple expression ::= [unary_adding_operator} term {binary_adding_operator term} +4.4: term ::= factor {multiplying operator factor} +4.4: factor ::= primary [** primary] Iabs primary I not primary +4.4: pdmary ::= +numeric_literal Inull IstringJiteral Iaggregate Iname Iqualified_expression Iallocator I(expression) +4.5: logical operator ::= and I or I xor +4.5: +relational_operator ::= = I/= I < I <= I > I >= +4.5: binary_adding_operator ::= + I- I& +4.5: +unary_adding_operator ::= + I - +4.5: multiplying_operator ::= * I / I rood I rein +4.5: highest_precedence_operator ::= ** Iabs Inot +4.6: type_conversion ::= +subtype_mark(expression) I subtype_mark(name) +4.7: +qualified_expression ::= subtype_mark'(expression) Isubtype_mark'aggregate +4.8: allocator ::= +new subtype_indication I new qualified_expression +5.1: +sequence_of_statements ::= statement {statement} +5.1: +statement 1:= {label} simple_statement I {label} compound_statement +5.1: +simple_statement ::= null_statement +I assignmenLstatementI goto_statementI return_statementI requeue_statementI abo~_statement +I code_statement +I exit_statementI procedure_call_statement +I entry_call_statementI delay_statementI raise_statement +5.1: +compound_statement ::=if_statement +I loop_statementI acceptstatement +I case_statementI block_statementI selecLstatement +5.1:null_statement ::= null; +5.1:label ::= <> +5.1: +statement_identifier ::= direcLname +5.2: +assignmenLstatement ::=vaHab/e_name := expression; +5.3:if_statement ::= +if condition thensequence_of_statements +{elsifcondition thensequence_of statements } +[else +sequence_oLstatements] +end if;5.3: +condition ::= boolean_expression +5.4: +case_statement ::=case expression is +case_statementalte rnative{ case_statement_altemafive } +end case; +5.4: case_statemenLaltemative ::= +when discrete_choice_list => sequence_of_statements +5.5: +loop_statement ::= +[loop_statemenLidentifier:] +[iteration_scheme] loop sequence_of statements end loop [loop_identifier]; +5.5: iteration_scheme ::= while condition +I for loop_parameter_specification +5.5: +loop_parameter_specification ::= defining_identifier in [reverse] discrete_subtype_definition +5.6: +block_statement ::= +[block_statement_identifier:] +5.7: +[declare declarative_part] +begin +handled_sequence of_statements end [block_identifier]; +exit_statement ::= exit [loop_name] [when condition]; +5.8: goto_statement ::= goto label_name; +6.1: +subprogram_declaration ::= subprogram_specification; +6.1: +abstract_subprogram_declaration::=subprogram_specification isabstract; +6.1: +subprogram_specification ::= procedure defining_program_unit_name parameter profile +Ifunction defining_designator parameter_and_result_profile +6.1: designator ::= [parenLuniLname. ]identifier I operator_symbol +6.1: +defining_designator ::= defining_program_unit_name I defining_operator_symbol +6.1: +defining_program_unit_name ::= [parent__unit_name. ]defining_identifier +6.1: +operatoLsymbol ::= string_literal +6.1: defining_operator_symbol::=operator symbol +6.1: +parameter_profile ::= [formal_part] +6.1: +parameter_and_result_profile ::= [formal_part] return subtype_mark +6.1: +formal_part ::= (parameter_specification [; parameter_specification}) +6.1: +parameter_specification ::= defining_identifier_list : mode subtype_mark [:= defaulLexpression] +Idefining_identifier_list:access_definition [:=default_expression +6.1: mode ::= [in] Iin out Iout +6.3: +subprogram_body ::= subprogramspecification is +declarative_part +begin +handled_sequence_of_statements end [designator]; +6.4: procedure_call_statement ::= +procedurename; Iprocedureprefix actual_parameter_part; +6.4: function_call ::= +function_name +Ifunction_prefix actual_parameter__part +6.4: +actual_parameter_part ::= (parameter association {, parameter_association}) +6.4: parameter_association ::= +[formal_parameter_selector__name =>] explicit__actual_parameter 6.4: +explicit_actual_parameter::= expression Ivariablename 6.5: +return_statement ::= return [expression]; 7.1: +package_declaration ::= package_specitication; +7.1: package_specification ::= - +package defining_program_unit_nameis {basic_declarative item} +[private { basic_declarative_item} ] +end [[parenLuniLname.]identifier] +7.2: package_body ::= +package body deflning_pmgram_uniLname is declarative_part +[begin handled_sequence of_statements] +end [[parenLunit_name.]identifier]; +7.3: +private_type_declaration ::= type defining_identifier [discriminant_part] is [[abstract] tagged] [limited] private; +7.3: +private_extension_declaration::= type defining_identifier [discdminant oart] is +[abstract] new Gncestor_subtype_indication with private; 8.4: +use_clause ::= use_package_clause I use_typeclause 8.4: +use_package_clause::=usepacl~ge_name {,pacl~ge_name}; +8.4: use_typeclause ::= use type subtype_mark {, subtype_mark}; +8.5: +renaming_declaration ::= objecLmnaming_declaration +I exception_renaming_declaration I package_renaming_declaration I subprogram_renaming_declaration I generic_renaming_declaration +8.5.1: +objecLranaming_declaration ::= defining_identifier : subtype_mark renames object_name; 8.5.2: +exception_ranaming_deelaration ::= defining_identifier : exception renames exception_name; 8.5.3: +package_renaming_declaration ::= package defining_program_uniLname renames package_name; 8.5.4: +subprogram_ranaming_declaration ::= subprogram_specification renames callable_entity_name; +8.5.5: +generic renaming_declaration ::= +generic package Igeneric procedure Igeneric function +defining_program_unit_name renames generic_package_name; defining_program_uniLname renames generic_.procedure_name; detining._program_unit_name renames generic_function_name; +9.1: task_type_declaration ::= +task type defining_iden•er [known_diseriminant_part] [is task_definition]; +9.1: single_task_declaration ::= +task defining_identifier [is task_definition]; +9.1: +task_definition ::= {task_item} +[ private {task_item}] +end [task_identifier] +9.1: +task_item ::= entry_declaration I representation_clause +9.1: +task_body ::= task body defining identifier is +declarative_part +begin +handled_sequence_of_statements +end [task_identifier]; +9.4: protected_type_declaration ::= +protected type defining_identifier [known_diecriminant_part] is protecteddefinition; +9.4: single._protected_declaration ::= +protected defining_identifier is protected_definition; +9.4: protecteddefinition ::= +{ protected operation_declaration } +[ private { protected_element_declaration } ] +end [protectedidentifier] 9.4: +protected_operation_declaration ::=subprogram_declaration I entry_declaration I representation_clause +9.4: protected_element_declaration ::= protected_operation_declaration +I componenLdeclaration +9.4: protected_body ::= +protected body defining_iden'dfier is { protected_operation_item } +end [protected_identifier]; +9.4: protected__operation_item ::= subprogram_declaration +I subprogram_body I entry_body I representation_ctsuse +9.5.2: entry_declarafion ::= +entry defining_identifier [(discrete_subtypedefinition)] parameter_profile; +9.5.2: accept__statement ::= +accept entry_direct_name [(entry_index)] parameter_profile [do handled_sequence of_statements +end [entry_identifier]I; +9.5.2: entry_index ::= expression +9.5.2: entry_body ::= +entry defining_identifier entry_body_formal_part entry_barrier is declarative_part +begin +handled_sequence_of_statements end [entry_identifier]; +9.5.2: +entry_body_formalpart ::= [(entry_index_specification)] parameter_profile +9.5.2: entry_barrier ::= when condition +9.5.2: entry_index_specification ::= for defining_identifier in discrete_subtype_definition +9.5.3: entry_call_statement ::= entry_name [actual_parameter_part]; +9.5.4: rsqueue_statement ::= requeue entryname [with abort]; +9.6: delay_statement ::= delay_until_statement I delay_relative_statement +9.6: delay_until_statement::= delay until delay_expression; +9.6: delay_relative_statement::= delay delay_expression; +9.7: +selecLstatement ::= selective_accept I timed_entry_call +Iconditional_entry call I asynchronousselect +9.7.1: +selective_accept ::= select +[guard] select_alternative +{ or [guard] +select_alternative } +[ else +sequence_of statements ] end select; +9.7.1: guard ::= when condition => +9.7.1: +select_alternative ::= acceptaltemative I delay_alternative +I terminate_alternative +9.7.1: +accept_alternative ::= accept_statement [sequence_of_statements] +9.7.1: delay_alternative ::= +delay_statement [sequence_of_statements] +9.7.1: +terminate_alternative ::= terminate; +9.7.2: timed_entry_call ::= +select ent ry_call_altemative +or delay alternative +end select; +9.7.2: entrycall_alternative ::= +entry_call_statement [sequence_of_statements] +9.7.3: conditional_entry_call ::= +select entry_call_alternative +else sequence_of statements +end select; +9.7.4: +asynchronous_select ::= +select +triggeringalternative then abort +abortable_part end select; +9.7.4: triggering_alternative ::= triggering_statement [sequence_oLstatements] +9.7.4: triggering_statement ::= entry_call_statement I delaystatement +9.7.4: abortable_part ::= sequence_of_statements +9.8: abort_statement ::= abort task_name {, taskname }; +10.1.1: compilation ::= {compilation_unit} +10.1.1: compilation_unit ::= +context_clause library_item I contextclause subunit +10.1.1: +library_item ::= [private] library_uniLdeclaration +I library_unit_body I[private] library_unit_renaming_declaration +10.1.1: library_unit_declaration ::= +subprogram_declaration I package_declaration I generic_declaration I generic_instantiation +10.1.1: +library_unit_renaming_declaration ::= package_renaming_declaration +I generic_renaming_declaration I subprogram_ranaming_declaration +10.1.1: +library_unit_body ::= subprogram_body I package_body +10.1.1: parent_unit_name ::= name +10.1.2: context_clause ::= {context_item} +10.1.2: +context_item ::= with_clause I use_clause +10.1.2: with_clause ::= with library_unit_name{, library_unit_name}; +10.1.3: body_stub ::= subprogram_body_stub I peckage_body_stub I task_body_stub I protected_body_stub +10.1.3: subprogram_body_stub ::= subprogram_specification is separate; +10.1.3: +package_body_stub ::= package body defining_identifier is separate; +10.1.3: +task_body_stub ::= task body defining_identifier is separate; +10.1.3: protected_body_stub ::= protected body defining_identifier is separate; +10.1.3: subunit ::= separate (parent_uniUname) proper_body +11.1: exception_declaration ::= defining_identifier list : exception; +11.2: +handled_sequence_of_statements ::= sequence_of_statements +[exception +exception_handler {exception_handler }] +11.2: +exception_handler ::= when [choice~oarameter_specification:] exceptionchoice (I exception_choice} => +sequence_of_statements +11.2: +choice_parameter_specification ::= defining_identifier +11.2: +exception_choice ::= exception_nameI others 11.3: +raise_statement ::= raise [exceptionname]; +12.1: +generic_declaration ::= generic_subprogram_declaration I generic_package_declaration +12.1: genedc_subprogram_declaration ::= +generic_formal_part subprogram_specification; +12.1: genedc~oackage_declaration ::= +generic_formal_part package_specification; +12.1: generic_formal_part ::= generic {genedc_fornkaLparameter_declaration I use_clause} +12.1: generic_formal_parameter_declaration ::= +formal_object_declaration I formal_type_declaration I formal_subprogramdeclaration I formal_package_declaration +12.3: generic_instantiation ::= +package defining_program uniLname is new generic_package_name[generic_actual_part]; +Iprocedure defining_program_unit_name is new generic_procedure_name[generic_actual_part]; +I function defining_designator is new generic_jrunction_name[genedc actual part]; +12.3: +generic_actual_part ::= (generic_association {, generic_association}) +12,3: generic_association ::= +[generic_formal_parameter_selector_name=>] explicit__genedc_actual_parameter +12.3: explicitgeneric_actual_parameter ::= expression I variable_name +Isubprogram_nameIentry_name Isubtype_mark Ipackage_instance_name +12.4: formal_object_declaration ::= +defining identifier_list : mode subtype_mark [:= default_expression]; +12.5: formaltype_declaration ::= +type defining_identilier[discriminant_part] is formal_type_definition; +12.5: formal_type_definition ::= +formal_private_type_definition I formal_derived type_definition I formal_discrete_type_definition I formal_signed_integer type_definition I formalmodular_type_definition I formal_floating_poinLdefinition I formal_ordinary_fixed_point_definition I formal_decimal_fixed_point_definition I formalarray_type_definition I formal_access_typedefinition +12.5.1: formal_.private_type_definition ::= [[abstract] tagged] [limited] private +12.5.1: formal_derived_type_definition ::= [abstract] new subtype_mark [with private] +12.5.2: formal_discrete_type_definition ::= (<>) +12.5.2: formal_signed integer_type_definition ::= range <> +12.5.2: formal_modular_type_definition ::= mad o +12.5.2: +formal_floating_point_definition ::= digits <> +12.5.2: formal ordinary_fixed_point_definition ::= delta <> +12.5.2: formal_decimal_fixed_poinLdefinition ::= delta <> digits <> +formal_array_type_definition ::= array_type_definition +12.5.4: +formal_ access- - type- - definition ::= access- - type- - definition +12.6: +formal_subprogram_declaration ::= with subprogram_specification [is subprogram_default]; +12.6: +subprogram_default ::= default_name I <> +12.6: +default_name ::= name +12.7: formai_paekage_declaration ::= +with package defining_identifier is new generic_.package_name formaljoaekage_actual_part; +12.7: formal_package_actual_part ::= +(<>) I[generic_actual_part] +13.1: +representation_clause ::= attributedefinition_clause I enumeration_representation_clause I record_representation_clause I at_clause +13.1: +local_name ::= direcLname I direcLname'attribute_designator I library_unit_name +13.3: attribute_definition_clause ::= +for Iocal_name'attribute_designator use expression; I for Iocal_name'attributs_designator use name; +13.4: enumeration_representation_clause ::= +forfirst_subtypelocal_name use enumeration_aggregate; 13.4: +enumeration_aggregate ::= array_aggregate +13.5.1: record_representation_clause ::= +forfirst subtype_locaUname use +record [mod_clause] {eomponent__clause } +end record; +13.5.1: +component_clause ::= component_local_name at position range firsLbit .. last_bit; +13.5.1: +position ::= static_expression 13.5.1: +first_bit ::= static_simple expression 13.5.1: +last_bit ::= static_simple_expression 13.8: +code_statement ::= qualified_expression; +13.12: restriction ::= restriction_identifier +I restriction_parameter_identifier => expression J.3: +delta_constraint ::= ddta static expression [range_constraint] J.7: +at_clause ::= for direct_name use at expression; +J.8: mod_clause ::= at mod static._expression; \ No newline at end of file