ADA SYNTAX ANALYZER
version 1.0
by Dmitry A. Kazakov
(mailbox@dmitry-kazakov.de)
![]()
This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate generics from this unit, or you link this unit with other files to produce an executable, this unit does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Public License.
The current version provides a full Ada 2022 syntax analyzer library. The analyzer parses the source and creates the syntax tree and cross reference of defining identifiers in the source. Both structures are allocated in an arena pool storage and can be released as a whole. The code source can be file, stream or a user-defined container implementing multi-line source interface. Unicode is fully supported as well as Unicode identifiers normalization checks.
| ARM | Intel | ||||||||
| Download Ada syntax analyzer | Platform: | 64- | 32- | 64- | 32bit | ||||
| Arch packages |
|
precompiled and packaged for pacman |
|
||||||
| Fedora packages |
|
precompiled and packaged using RPM |
|
|
|||||
| CentOS packages |
|
precompiled and packaged using RPM | |||||||
| Debian packages |
|
precompiled and packaged for dpkg |
|
||||||
| Ubuntu packages |
|
precompiled and packaged for dpkg |
|
|
|||||
| Source distribution (any platform) | ada_syntax_analyzer_1_0.tgz (tar + gzip, Windows users may use WinZip) |
|
|||||||
See also changes log.
The package Parsers.Ada_Syntax_Analyzer provides an Ada syntax analyzer:
type Ada_Program
( Pool : access Root_Storage_Pool'Class;
Xref : Cross_Reference_Ptr
) is new Ada_Expression with private;
The type is derived from the Ada expression parser from Simple Components. The discriminants are:
The following operations are defined on the type:
function Parse
( Context : access Ada_Program;
Code : access Source'Class;
File : Source_Description_Ptr
) return Tokens.Argument_Token;
This function parses one compilation unit in the source Code and advances the source to the first position following the unit. The result is returned as the topmost node of the syntax tree allocated in the arena pool. The cross-reference Xref if specified is updated with the new defining identifiers declared across the unit and the contexts containing these identifiers. File is the source file description to be used with defining identifiers. It can be null if only one file is used. If multiple files are used the source file description is used to distinguish them in the cross-reference.
The Syntax_Error exception defined in the package Parsers is propagated on syntax errors. Upon an error the source is left at the last parsed position. The syntax error text contains the source primary source location of the error at its end. For example:
'end if' is expected at 18:6..10
The location can be extracted from the text using the function Get_Location. Upon failure the memory pool is cleared. The source can be any descendant of the type Parsers.Multiline_Source.Source_Type. It can be a text file, string, stream or user-defined.
function Get_Trace_File (Context : Ada_Program)
return Ada.Text_IO.File_Access;
This function returns the file presently used for tracing. It is null if tracing is inactive.
procedure Set_Trace_File
( Context : in out Ada_Program;
File : Ada.Text_IO.File_Access := null
);
This procedure sets the trace file. When null tracing is deactivated.
type Tree_Stub (Context : access Ada_Program'Class) is
new Ada.Finalization.Limited_Controlled with private;
An instance of this type marks the pool used by Context. When finalized it frees all memory allocated there since initialization.
The following type is the base type of a context containing defining identifiers (ARM 3.1):
type Compilation_Context is abstract new Declaration_Node with record
Parent : Context_Location;
File : Source_Description_Ptr;
Scope : Parsers.Multiline_Source.Location := Empty;
end record;
type Compilation_Context_Ptr is
access constant Compilation_Context'Class;;
A compilation context:
| package T is | |||
|
I : Integer; A : Float; procedure X |
|||
|
(
J : Integer; P : Float; S : String |
Location (inherited) |
Parent's location | |
|
) is begin J := J + 1; I := J; |
Scope | ||
| end X; | |||
| end T; |
The operations to navigate contexts:
function Get_Item
( Context : Compilation_Context;
Index : Positive
) return Declaration_Ptr is abstract;
This function returns the declaration node by its index. Nodes are enumerated starting with 1. Constraint_Error is propagated when Index is wrong.
function Get_Items_Number (Context : Compilation_Context)
return Natural is abstract;
This function returns the number of declaration nodes in the context.
type Context_Location is record
Context : Compilation_Context_Ptr;
After : Natural := 0;
end record;
Values of this type indicates a declaration item:
function Is_Library_Unit (Context : Context_Location) return Boolean;
This function returns true if Context indicates an item declared in a library unit context.
function Get (Context : Context_Location) return Declaration_Ptr;
This function returns the declaration node specified by Context. Constraint_Error is propagated on errors.
package Context_Location_Sets is
new Generic_Set (Context_Location, (null, 0));
This instantiation provides sets of context locations.
function Precedes (Left, Right : Location) return Boolean;
This function orders source locations so that a location precedes another if it indicates a source interval preceding than the later or else contains it.
The defining identifier is declared as follows:
type Named_Term_Ptr is access constant Named_Term'Class;
type Defining_Identifier is record
Declared : Context_Location;
Outer : Program_Node_Ptr;
Name : Named_Term_Ptr;
Term : Tokens.Argument_Token;
File : Source_Description_Ptr;
Next : Defining_Identifier_Ptr;
end record;
type Defining_Identifier_Ptr is access constant Defining_Identifier;
This type represents either a defining identifier or a defining symbol:
type Defining_Identifier_Array is
array (Positive range <>) of aliased Defining_Identifier;type Source_Description is abstract tagged null record;
type Source_Description_Ptr is
access constant Source_Description'Class;
The source description can be used with multiple sources to indicate which source the identifier was declared in. The following operations are defined on source descriptions:
Source_Description_Ptr is
access constant Source_Description'Class;
The source descriptio
type Cross_Reference
( Pool : access Root_Storage_Pool'Class
) is new Ada.Finalization.Limited_Controlled with private;
type Cross_Reference_Ptr is access all Cross_Reference'Class;
This type represents a cross-reference of the items declared in the parsed units. The discriminant Pool can be the same storage pool as the pool used by the parser. Items added to the reference are allocated after the pool mark. When the parser object is finalized or when the stub is finalized Program_Error is propagated if the items from a still existing cross-reference are deallocated in the result.
The following operations are defined on cross-reference:
function Find
( Xref : Cross_Reference;
Name : String;
Location : Parsers.Multiline_Source.Location;
File : Source_Description_Ptr := null
) return Context_Location_Sets.Set;
This function searches for the name in the cross-reference Xref. Name is the name to search for. Location is the source location to start at. The result the set of defining identifier locations with the names matching Name. The set contains only identifiers with the visibility scope containing Location in File. The result is a set of potential candidates to resolve Name ignoring the use clauses.
function Get
( Xref : Cross_Reference;
Name : String
) return Identifier_Entry;
This function returns the entry corresponding Name. The result is No_Identifier if no entry is found.
function Get
( Xref : Cross_Reference;
Location : Parsers.Multiline_Source.Location;
File : Source_Description_Ptr := null
) return Context_Entry;
This function returns the context entry corresponding to the narrowest scope containing Location in File. The result is No_Entry is no such entry exists.
function Get_First
( Xref : Cross_Reference
) return Identifier_Entry;
This function returns the first identifier entry in the reference. The result is No_Identifier if the reference is empty.
function Get_First
( Xref : Cross_Reference
) return Context_Entry;
This function returns the first context entry in the reference. The result is No_Context if the reference is empty.
function Get_Last
( Xref : Cross_Reference
) return Identifier_Entry;
This function returns the last identifier entry in the reference. The result is No_Identifier if the reference is empty.
function Get_Last
( Xref : Cross_Reference
) return Context_Entry;
This function returns the last context entry in the reference. The result is No_Context if the reference is empty.
type Identifier_Entry is private;
No_Identifier : constant Identifier_Entry;
This type represents an entry in the cross-reference corresponding a name. All items in an entry are defining identifiers having this name.
function Get_First (Item : Identifier_Entry)
return Defining_Identifier_Ptr;
This function returns the first defining identifier in the entry Item. Constraint_Error is propagated if Item is No_Identifier.
function Get_Identifiers_Number (Item : Identifier_Entry)
return Positive;
This function returns the number of defining identifiers in the entry Item. The result is zero if Item is No_Identifier.
function Get_Last (Item : Identifier_Entry)
return Defining_Identifier_Ptr;
This function returns the last defining identifiers in the entry Item. Constraint_Error is propagated if Item is No_Identifier.
function Get_Name (Item : Identifier_Entry) return String;
This function returns the name the entry Item corresponds to. Constraint_Error is propagated if Item is No_Identifier.
function Get_Next (Item : Identifier_Entry) return Identifier_Entry;
This function returns the next entry to Item in the cross-reference. The result is No_Identifier if there is none or if Item is No_Identifier.
function Get_Previous (Item : Identifier_Entry) return Identifier_Entry;
This function returns the previous entry to Item in the cross-reference. The result is No_Identifier if there is none or if Item is No_Identifier.
type Context_Entry is private;
No_Context : constant Context_Entry;
This type represents an entry in the cross-reference corresponding a context. That is a declarative region and its scope. Entries are ordered in the textual order of the scopes where context declarations are directly visible. Note the difference between the location of declarations and the scope where these become visible.
function Get_Context (Item : Context_Entry)
return Compilation_Context_Ptr;
This function returns the context corresponding to the entry Item. Constraint_Error is propagated if Item is No_Context.
function Get_Location (Item : Context_Entry)
return Parsers.Multiline_Source.Location;
This function returns the location in the source where context corresponding to entry Item is directly visible. It may or may not include the declaration of the context. For example parameter profile declarations are not visible inside the profile. Constraint_Error is propagated if Item is No_Context. See also Get_Scope which also returns the source description.
function Get_Next (Item : Context_Entry) return Context_Entry;
This function returns the next entry to Item in the cross-reference. The result is No_Identifier if there is none or if Item is No_Context.
function Get_Previous (Item : Context_Entry) return Context_Entry;
This function returns the previous entry to Item in the cross-reference. The result is No_Identifier if there is none or if Item is No_Context.
procedure Get_Scope
( Item : Context_Entry;
File : out Source_Description_Ptr;
Location : out Parsers.Multiline_Source.Location
);
This procedure returns the location and source description in the source where context corresponding to the entry Item is directly visible. It may or may not include the declaration of the context. For example parameter profile identifiers are not visible inside the profile itself. Constraint_Error is propagated if Item is No_Context.
The syntax tree nodes are derived from Ada expression nodes:
type Program_Node is abstract new Node with null record;
type Program_Node_Ptr is
access constant Program_Node'Class;
A whole compilation unit is a single tree node.
All text internally are kept as Ada strings encoded in UTF-8.
function Get_Class (Item : Program_Node)
return Program_Node_Class is abstract;
The function returns the enumeration type value corresponding to the program node. It can be used to avoid explicit tag testing:
type Program_Node_Class is
( Abort_Statement_Node,
Accept_Statement_Node,
...
With_Clause_Node
);
All declaration nodes are descendants of Declaration_Node:
type Declaration_Node is abstract new Program_Node with record
Location : Parsers.Multiline_Source.Location;
end record;
type Declaration_Ptr is access constant Declaration_Node'Class;
This type is the base type of all declaration nodes.
The child package Parsers.Ada_Syntax_Analyzer.Declarations provides basic types used in declaration nodes.
This enumeration type specifies the type of a declaration context::type Compilation_Context_Type is
( Code_Block_Context,
Generic_Formal_Parameters_Context,
Library_Unit_Context,
Package_Interface_Context,
Package_Private_Context,
Protected_Interface_Context,
Protected_Private_Context,
Protected_Body_Context,
Record_Component_Context,
Task_Interface_Context,
Task_Private_Context
);
declare
<Code_Block_Context>
begin
...
end;<Library_Unit_Context>
generic
<Generic_Formal_Parameters_Context>
package P
<Package_Interface_Context>
private
<Package_Private_Context>
end P;protected type P is
<Protected_Interface_Context>
private
<Protected_Private_Context>
end P;protected body P is
<Protected_Body_Context>
end P;type T is record
<Record_Component_Context>
end record;task type T is
<Task_Interface_Context>
private
<Task_Private_Context>
end P;
function Image (Item : Compilation_Context_Type) return String;
The declaration context node.
type Declaration_Context (Kind_Of : Compilation_Context_Type) is
new Compilation_Context with
record
Declarations : Declaration_Ptr_Array_Ptr;
Last_Use_Clause : Use_Clause_Ptr;
end record;
type Declaration_Context_Ptr is access constant Declaration_Context;
The declaration context contains a list of declarations:
type Declaration_Ptr_Array is
array (Positive range <>) of Declaration_Ptr;
type Declaration_Ptr_Array_Ptr is
access constant Declaration_Ptr_Array;
and the list of use clauses inside:
type Use_Clause is abstract new Context_Clause with record
Location : Context_Location;
Previous : Use_Clause_Ptr;
end record;
type Use_Clause_Ptr is access constant Use_Clause'Class;
The use clauses are linked inside the context in order to simplify resolution of names according to visibility.
type Context_Clause (Length : Positive) is
abstract new Declaration_Node with
record
List : Argument_List (1..Length);
end record;
The context clause is the base type of with-, use- and use-type clause nodes. It contains list of nodes each represents a name.
The child package Parsers.Ada_Syntax_Analyzer.Declarations.Formal_Parameters provides declaration of nodes used for generic formal parameters.
type Formal_Parameter is abstract new Declaration_Node with record
Name : aliased Defining_Identifier;
end record;
This is the base type of all formal parameters. The node types declared in the package:
The child package Parsers.Ada_Syntax_Analyzer.Declarations.Specifications provides declaration of nodes used for specifications.
type Mode_Type is
( Inout_Mode, -- in out Sybtype_Mark
Out_Mode, -- out Sybtype_Mark
In_Mode, -- in Sybtype_Mark
Access_To_All, -- access all
Access_To_Constant, -- access constant
Access_To_Variable, -- access
Access_To_Procedure, -- access procedure
Access_To_Protected_Procedure, -- access protected procedure
Access_To_Function, -- access function
Access_To_Protected_Function, -- access protected function
Object_Mode, -- Subtype_Indication
Array_Mode, -- array
Constant_Mode -- <number>
);
subtype Parameter_Mode is Mode_Type
range Inout_Mode..Access_To_Protected_Function;
subtype Access_Mode is Mode_Type
range Access_To_All..Access_To_Protected_Function;
subtype Access_To_Mode_Type is Mode_Type
range Access_To_Constant..Access_To_Variable;
subtype Access_To_Subprogram_Mode is Mode_Type
range Access_To_Procedure..Access_To_Protected_Function;
subtype Component_Mode is Mode_Type
range Access_To_All..Object_Mode;
subtype Result_Mode is Mode_Type
range In_Mode..Access_To_Protected_Function;
The type mode enumeration specifies modes applied to a parameter or component.
type Anonymous_Access_Definition (Mode : Access_Mode) is record
Not_Null : Boolean;
case Mode is
when Access_To_All..Access_To_Variable =>
Object : Subtype_Indication;
when Access_To_Subprogram_Mode =>
Profile : Parameter_Profile_Ptr;
case Mode is
when Access_To_Function | Access_To_Protected_Function =>
Result : Object_Specification_Ptr;
when others =>
null;
end case;
end case;
end record;
This type defines components of an access type. It can be either an access to object or an access to a subprogram.
type Array_Type_Specification
( Mode : Component_Mode;
Dimension : Positive;
Aliased_Component : Boolean
) is
record
Indices : Subtype_Indication_Array (1..Dimension);
case Mode is
when Access_Mode =>
Access_Component : Anonymous_Access_Definition (Mode);
when Object_Mode =>
Object_Component : Subtype_Indication;
end case;
end record;
type Array_Type_Specification_Ptr is
access constant Array_Type_Specification;
This type defines components of an access type. It can be either an access to object or an access to a subprogram.
type Object_Specification (Mode : Mode_Type) is record
case Mode is
when Object_Mode =>
Variable : Subtype_Indication;
when In_Mode | Inout_Mode | Out_Mode =>
Not_Null : Boolean;
Result : Subtype_Mark;
when Access_Mode =>
Pointer : Anonymous_Access_Definition (Mode);
when Array_Mode =>
Array_Object : Array_Type_Specification_Ptr;
when Constant_Mode =>
null;
end case;
end record;
type Object_Specification_Ptr is
access constant Object_Specification;
This type defines an object, component or result of a subprogram. It can be:
type Parameter_Profile
( Parameters_Count : Natural
) is new Compilation_Context with
record
Outer : Program_Node_Ptr;
List : Parameter_Specification_Ptr_Array (1..Parameters_Count);
end record;
type Parameter_Profile_Ptr is access constant Parameter_Profile;
This type defines parameters of a subprogram. The profile is a context since names of parameters are defining identifiers visible in the body of the subprogram.
type Parameter_Specification
( Mode : Parameter_Mode;
Aliased_Parameter : Boolean;
Defaulted : Boolean;
Length : Natural;
Parameters_Count : Positive;
Aspects_Count : Natural
) is new Declaration_Node with
record
Parameters : Defining_Identifier_Array (1..Parameters_Count);
Profile : Parameter_Profile_Ptr;
Aspects : Aspect_Items_Array (1..Aspects_Count);
Default : Optional (Defaulted);
case Mode is
when In_Mode | Inout_Mode | Out_Mode =>
Not_Null : Boolean;
Value : Subtype_Mark;
when Access_Mode =>
Pointer : Anonymous_Access_Definition (Mode);
end case;
end record;
type Parameter_Specification_Ptr is
access constant Parameter_Specification;
type Parameter_Specification_Ptr_Array is
array (Positive range <>) of Parameter_Specification_Ptr;
This type defines parameters in the profile having the same definition like X, Y : Integer.
type Singleton_Parameter is new Compilation_Context with record
Name : aliased Defining_Identifier;
Type_Of : Parameter_Type;
end record;
Singleton parameter is a context with a single parameter defined, e.g. a loop parameter.
Further nodes are:
The child package Parsers.Ada_Syntax_Analyzer.Declarations.Renamings provides declaration of nodes used for renaming Ada entities.
type Abstract_Renaming
( Aspects_Count : Natural
) is abstract new Declaration_Node with
record
Name : aliased Defining_Identifier;
Target : Tokens.Argument_Token;
Aspects : Aspect_Items_Array (1..Aspects_Count);
end record;
This is the base type of all renaming nodes:
The child package Parsers.Ada_Syntax_Analyzer.Declarations.Types provides declaration of nodes used for type declarations.
type Abstract_Type_Declaration
( Aspects_Count : Natural
) is abstract new Declaration_Node with
record
Name : aliased Defining_Identifier;
Aspects : Aspect_Items_Array (1..Aspects_Count);
end record;
This is the base type of all declaration nodes:
The child package Parsers.Ada_Syntax_Analyzer.Declarations.Stubs provides declaration of nodes used for stub declarations.
type Abstract_Stub
( Aspects_Count : Natural
) is abstract new Declaration_Node with
record
Name : aliased Defining_Identifier;
Aspects : Aspect_Items_Array (1..Aspects_Count);
end record;
This is the base type of all stub declaration nodes:
The child package Parsers.Ada_Syntax_Analyzer.Bodies provides declaration of nodes used bodies.
type Abstract_Body
( Declarations : access constant Declaration_Context;
Aspects_Count : Natural
) is abstract new Declaration_Node with
record
Name : aliased Defining_Identifier;
Aspects : Aspect_Items_Array (1..Aspects_Count);
end record;
This is the base type of all body declaration nodes:
The child package Parsers.Ada_Syntax_Analyzer.Statements provides declaration of nodes used bodies.
type Abstract_Statement_Node (Labels_Count : Natural) is abstract
new Program_Node with
record
Location : Parsers.Multiline_Source.Location;
Path : Statement_Location;
Labels : Defining_Identifier_Array (1..Labels_Count);
end record;
type Statement_Ptr is access constant Abstract_Statement_Node'Class;
type Statement_Ptr_Array is
array (Positive range <>) of Statement_Ptr;
This is the base type of all statement nodes. The statement has a location in the source and a location in a statement sequence. The statement also has a list of labels. The labels are located in front of the statement except for a sequence of statements which has labels at its end.
type Statement_Location is record
Sequence : Statement_Sequence_Ptr;
Position : Positive;
end record;
The statement location points a sequence and position inside it.
type Statement_Sequence
( Labels_Count : Natural;
Length : Positive
) is new Abstract_Statement_Node (Labels_Count) with
record
Context : Context_Location;
Outer : Program_Node_Ptr;
List : Statement_Ptr_Array (1..Length);
end record;
type Statement_Sequence_Ptr is
access constant Statement_Sequence'Class;
type Unhandled_Statement_Sequence_Ptr is
access constant Statement_Sequence;
A statement sequence is a statement that contains other statements. Context is the location of context in where the sequence is located. Outer is the node that contains the sequence. List is the statements list. For example:
procedure P is I : Integer;
A : Float;Context begin if I < 0 then A := 0.0; Sequence Outer (if statement) end if; end P;
type Handled_Statement_Sequence
( Labels_Count : Natural;
Length : Positive;
Handlers_Count : Natural
) is new Statement_Sequence
( Labels_Count => Labels_Count,
Length => Length
) with
record
Handlers : Exception_Handler_Ptr_Array (1..Handlers_Count);
end record;
type Handled_Statement_Sequence_Ptr is
access constant Handled_Statement_Sequence;
A handled statement sequence has exception handlers attached to it.
type Exception_Handler
( Has_Parameter : Boolean;
Choices_Count : Natural
) is
record
Outer : Handled_Statement_Sequence_Ptr;
Sequence : Unhandled_Statement_Sequence_Ptr;
Choices : Argument_List (1..Choices_Count);
case Has_Parameter is
when True =>
Parameter : aliased Singleton_Parameter;
when False =>
null;
end case;
end record;
type Exception_Handler_Ptr is access constant Exception_Handler;
type Exception_Handler_Ptr_Array is
array (Positive range <>) of Exception_Handler_Ptr;
A handler has a list of choices, sequence of statements and optionally a parameter.
The statement nodes are:
The child package Parsers.Ada_Syntax_Analyzer.Text_IO provides procedures to output the tree and cross-reference.
procedure Put
( Tree : Tokens.Argument_Token;
Output : File_Type := Standard_Output;
Prefix : String := "";
Nested : Nesting := Top
);
procedure Put
( Tree : Tokens.Argument_Token;
Name : String;
Prefix : String := "";
Nested : Nesting:= Top
);
These procedures output the abstract syntax tree. For example, the output of Hello-World procedure:
<library>
declarations
|__with at 10:1..13:16
| |__Ada.Text_IO at 8:6..16
|__use at 10:1..13:16
|__Ada.Text_IO at 8:24..34
procedure Hello_World at 10:1..13:16
begin
|__*() at 12:13..28
|__Put_Line at 12:4..11
|__"Hello world!" at 12:14..27
procedure Put_Contexts (File : File_Type; Xref : Cross_Reference);
procedure Put_Contexts (Xref : Cross_Reference);
These procedures output the contexts from the cross-reference. The output contains the list context visibility scopes with the context type, its location and the chain of it parent contexts. For example the cross-reference of this program:
01 -- 02 -- ARM 3.10(21-26) Access Types 03 -- 04 -- Success: 21:1..39:13 Tree * 05 -- 06 -- package body ARM_3_10 is 07 -- type Frame is access Matrix; 08 -- type Peripheral_Ref is not null access Peripheral; 09 -- type Binop_Ptr is access all Binary_Operation'Class; 10 -- subtype Drum_Ref is Peripheral_Ref (Drum); 11 -- type Message_Procedure is access procedure (M : String := "Error!"); 12 -- procedure Default_Message_Procedure (M : String); 13 -- Give_Message : Message_Procedure := Default_Message_Procedure'Access; 14 -- procedure Other_Procedure (M : String); 15 -- begin 16 -- Give_Message := Other_Procedure'Access; 17 -- Give_Message ("File not found."); 18 -- Give_Message.all; 19 -- end ARM_3_10; 20 -- 21 package body ARM_3_10 is 22 type Frame is access Matrix; -- see 3.6 23 type Peripheral_Ref is not null access Peripheral; -- see 3.8.1 24 type Binop_Ptr is access all Binary_Operation'Class; 25 -- general access-to-class-wide, see 3.9.1 26 subtype Drum_Ref is Peripheral_Ref(Drum); -- see 3.8.1 27 28 type Message_Procedure is access procedure (M : in String := "Error!"); 29 procedure Default_Message_Procedure(M : in String); 30 Give_Message : Message_Procedure := Default_Message_Procedure'Access; 31 32 procedure Other_Procedure(M : in String); 33 begin 34 Give_Message := Other_Procedure'Access; 35 36 Give_Message("File not found."); 37 -- call with parameter (.all is optional) 38 Give_Message.all; -- call with no parameters 39 end ARM_3_10;
looks like::
Scopes Defining identifiers context
------ ----------------------------
21:1..39:13 library unit context at 21:1 (0 items)
22:4..39:0 declarative part at 22:4..33:0 (8 items)
after library unit context at 21:1 (0 items)
There are two contexts. The library unit context with no items declared. The package body is attached to that context. The visibility scope covers all package body. The package body has a declaration context with 8 items declared in it. Its parent context is the library unit context.
procedure Put_Defining_Identifiers
( File : File_Type;
Xref : Cross_Reference;
Field : Output_Length := 50
);
procedure Put_Defining_Identifiers
( Xref : Cross_Reference;
Field : Output_Length := 50
);
These procedures output the list of declared items in the cross-reference. The parameter Field specified the maximum identifier name length. If the name exceeds this limit, it is truncated in the output. For the program above:
Identifier Locations
---------- ---------
ARM_3_10 21:14..21
Binop_Ptr 24:9..17
Default_M...rocedure 29:14..38
Drum_Ref 26:12..19
Frame 22:9..13
Give_Message 30:4..15
M 28:48..48, 29:40..40, 32:30..30
Message_Procedure 28:9..25
Other_Procedure 32:14..28
Peripheral_Ref 23:9..22
The child package Parsers.Ada_Syntax_Analyzer.Serialization provides syntax tree serialization. The following subprograms are defined in the package:
procedure Restore
( Stream : in out Root_Stream_Type'Class;
Pool : in out Root_Storage_Pool'Class;
Offset : in out Stream_Element_Offset;
Result : out Tokens.Argument_Token;
Xref : Cross_Reference_Ptr := null;
File : Source_Description_Ptr := null;
Trace : File_Access := null;
Prefix : String := ""
);
This procedure restores a syntax tree from Stream. The tree is allocated in Pool. Offset is incremented by the number of storage elements read. Result is the tree. Xref is the cross-reference to update with the defining identifiers and scopes read. File is the source description to apply to the input. Trace is the trace file. Prefix is the prefix to use with the trace file output. Constraint_Error is propagated on errors.
function Restore
( Stream : access Root_Stream_Type'Class;
Pool : access Root_Storage_Pool'Class;
Xref : Cross_Reference_Ptr := null;
File : Source_Description_Ptr := null;
Trace : File_Access := null;
Prefix : String := ""
) return Tokens.Argument_Token;
This function is a variant of the above procedure.
procedure Store
( Stream : in out Root_Stream_Type'Class;
Tree : Tokens.Argument_Token;
[ Offset : in out Stream_Element_Offset; ]
Trace : File_Access := null;
Prefix : String := ""
);
This procedure stores the syntax tree Tree into Stream. Offset is incremented by the number of storage elements written. Trace is the trace file. Prefix is the prefix to use with the trace file output. Constraint_Error is propagated on errors.
The test suite directory contains the project test_suite.gpr. The arguments of the program is the list of files or directories containing tests. When the keyword trace appears then tracing is enabled for the following arguments. Without file or directory arguments the subdirectory tests is used. The program scans each directory and uses each file as a test. It stops at the first test failed. The program exist code is success only when all tests pass.
The test is a source of an Ada program that may consist of several compilation units. The source starts with a comment. The comment specifies the required outcome.
A succes test contains the keyword Success followed by colon. For example:
01 -- 02 -- Description: Hello world test 03 -- 04 -- Success: 10:1..13:16 Tree * 05 -- 06 -- with Ada.Text_IO; use Ada.Text_IO; procedure Hello_World is begin Put_Line ("Hello world!"); end Hello_World; 07 -- 08 with Ada.Text_IO; use Ada.Text_IO; 09 10 procedure Hello_World is 11 begin 12 Put_Line ("Hello world!"); 13 end Hello_World;
The keyword Success is followed by a comma-separated list of excepted locations. For each unit in the test there is one item in the list. Then the following optional elements may follow:
A cross-reference check starts with the keyword find. The has the syntax
<check> ::= find <name> at <location> = <places-set> | empty
<places-set> ::= <place> [,<places-set>]
<place> ::= <location>(<position>)
The set of places specifies the list of locations where an identifier matching the specified one is declared. The position is one of the declaration. The check is made against the function Find. For example:
01 -- 02 -- Object orientation https://en.wikibooks.org/wiki/Ada_Programming/Object_Orientation 03 -- 04 -- Success: 26:1..37:15 find Object at 27:9..14 = empty 05 -- find Class_Member_1 at 35:14..27 = 27:4..37:0(2) 06 -- find New_Class_Member at 37:0 = 27:4..37:0(3) 07 -- find Skilled_In at 31:23..35 = empty 08 -- find Skilled_In at 32:1..1 = 31:1..32:6(1) 09 -- find Programmer at 27:1 = 25:1..26:0(2) 10 -- 11 -- with Person; 12 -- package Programmer is 13 -- type Object is new Person.Object 14 -- and Printable.Object 15 -- with 16 -- record 17 -- Skilled_In : Language_List; 18 -- end record; 19 -- overriding 20 -- procedure Class_Member_1 (This : Object); 21 -- not overriding 22 -- procedure New_Class_Member (This : Object; That : String); 23 -- end Programmer; 24 -- 25 with Person; 26 package Programmer is 27 type Object is new Person.Object 28 and Printable.Object 29 with 30 record 31 Skilled_In : Language_List; 32 end record; 33 overriding 34 procedure Class_Member_1 (This : in Object); 35 not overriding 36 procedure New_Class_Member (This : Object; That : String); 37 end Programmer;
If ! appears before Success the test is the last test to run.
A test for invalid program contains the keyword Failure followed by colon. The expected error message is specified on the same line. For example:
01 -- 02 -- ACATS B55A01V 03 -- 04 -- Failure: Expression is expected at 12:20 05 -- 06 PROCEDURE B55A01V IS 07 08 VBF : BOOLEAN := FALSE; 09 10 BEGIN 11 12 WHILE VBF LOOP; -- ERROR: ';'. 13 NULL; 14 END LOOP; 15 16 END B55A01V;
If ! appears before Failure the test is the last test to run.
The following versions were tested with the compilers:
First release 1.0