mirror of
https://github.com/AdaCore/PolyORB.git
synced 2026-02-12 13:01:15 -08:00
newest GNAT wavefronts in -gnatg mode. [Imported from Perforce change 9292 at 2006-12-01 21:18:37] Subversion-branch: /trunk/polyorb Subversion-revision: 36798
2910 lines
82 KiB
Ada
2910 lines
82 KiB
Ada
with GNAT.Table;
|
|
|
|
with Errors; use Errors;
|
|
with Lexer; use Lexer;
|
|
with Locations; use Locations;
|
|
with Namet; use Namet;
|
|
with Nodes; use Nodes;
|
|
with Nutils; use Nutils;
|
|
-- with Scopes; use Scopes;
|
|
with Types; use Types;
|
|
with Utils; use Utils;
|
|
|
|
package body Parser is
|
|
|
|
procedure Declare_Base_Type (L : Token_List_Type; K : Node_Kind);
|
|
-- L denotes a token list used to name an IDL base type. Allocate
|
|
-- a node for it and associate it to the concatenated names.
|
|
|
|
function Resolve_Base_Type (L : Token_List_Type) return Node_Id;
|
|
-- Take the sequence of tokens in the paremter list to return the
|
|
-- node of the IDL predefined type.
|
|
|
|
function Is_Param_Type_Spec (E : Node_Id) return Boolean;
|
|
-- Return true when the type specifier N belongs to the restricted
|
|
-- parameter type specifier set.
|
|
|
|
function Operator (E : Node_Id) return Operator_Type;
|
|
procedure Set_Operator (E : Node_Id; O : Operator_Type);
|
|
|
|
function Parameter_Mode (E : Node_Id) return Mode_Type;
|
|
pragma Unreferenced (Parameter_Mode);
|
|
procedure Set_Parameter_Mode (E : Node_Id; M : Mode_Type);
|
|
|
|
Sequencing_Level : Natural := 0;
|
|
|
|
function P_No_Such_Node return Node_Id;
|
|
|
|
function P_Attribute_Declaration return Node_Id;
|
|
function P_Complex_Declarator return Node_Id;
|
|
function P_Constant_Declaration return Node_Id;
|
|
function P_Constant_Expression return Node_Id;
|
|
function P_Constant_Type return Node_Id;
|
|
function P_Declarator return Node_Id;
|
|
function P_Declarator_List return Node_Id;
|
|
function P_Definition return Node_Id;
|
|
function P_Enumeration_Type return Node_Id;
|
|
function P_Exception_Declaration return Node_Id;
|
|
function P_Export return Node_Id;
|
|
function P_Fixed_Point_Type return Node_Id;
|
|
function P_Identifier return Node_Id;
|
|
function P_Initializer_Declaration return Node_Id;
|
|
function P_Interface return Node_Id;
|
|
function P_Interface_Declaration return Node_Id;
|
|
function P_Interface_Name return Node_Id;
|
|
function P_Member return Node_Id;
|
|
function P_Module return Node_Id;
|
|
function P_Operation_Declaration return Node_Id;
|
|
function P_Parameter_Declaration return Node_Id;
|
|
function P_Pragma return Node_Id
|
|
renames P_No_Such_Node;
|
|
function P_Scoped_Name return Node_Id;
|
|
function P_Sequence_Type return Node_Id;
|
|
function P_Simple_Declarator return Node_Id;
|
|
function P_Simple_Type_Spec return Node_Id;
|
|
function P_Specification return Node_Id;
|
|
function P_State_Member return Node_Id;
|
|
function P_Structure_Type return Node_Id;
|
|
function P_String_Type return Node_Id;
|
|
function P_Type_Declaration return Node_Id;
|
|
function P_Type_Spec return Node_Id;
|
|
function P_Union_Type return Node_Id;
|
|
function P_Value return Node_Id;
|
|
function P_Value_Abstract_Declaration return Node_Id;
|
|
function P_Value_Box_Declaration return Node_Id;
|
|
function P_Value_Declaration return Node_Id;
|
|
function P_Value_Forward_Declaration return Node_Id;
|
|
function P_Value_Spec return Node_Id;
|
|
|
|
package Expressions is new GNAT.Table (Node_Id, Natural, 1, 100, 10);
|
|
|
|
Preferences : constant array (T_Tilde .. T_Less_Less) of Natural
|
|
:= (T_Tilde => 0,
|
|
T_Percent => 1,
|
|
T_Slash => 2,
|
|
T_Star => 3,
|
|
T_Minus => 4,
|
|
T_Plus => 5,
|
|
T_Less_Less => 6,
|
|
T_Greater_Greater => 7,
|
|
T_Ampersand => 8,
|
|
T_Circumflex => 9,
|
|
T_Bar => 10);
|
|
|
|
-----------------------
|
|
-- Declare_Base_Type --
|
|
-----------------------
|
|
|
|
procedure Declare_Base_Type (L : Token_List_Type; K : Node_Kind) is
|
|
E : Node_Id;
|
|
begin
|
|
|
|
-- Create a fake node located at the beginning of the
|
|
-- specification (current token location).
|
|
|
|
E := New_Node (K, No_Location);
|
|
|
|
-- Accumulate token names and store node id as table info
|
|
|
|
Set_Str_To_Name_Buffer (Image (L (L'First)));
|
|
for I in L'First + 1 .. L'Last loop
|
|
Add_Char_To_Name_Buffer (' ');
|
|
Add_Str_To_Name_Buffer (Image (L (I)));
|
|
end loop;
|
|
Set_Name_Table_Info (Name_Find, Int (E));
|
|
end Declare_Base_Type;
|
|
|
|
------------------------
|
|
-- Is_Param_Type_Spec --
|
|
------------------------
|
|
|
|
-- (95) <param_type_spec> ::= <base_type_spec>
|
|
-- | <string_type>
|
|
-- | <wide_string_type>
|
|
-- | <scoped_name>
|
|
|
|
function Is_Param_Type_Spec (E : Node_Id) return Boolean is
|
|
begin
|
|
case Kind (E) is
|
|
when K_Float
|
|
| K_Double
|
|
| K_Long_Double
|
|
| K_Short
|
|
| K_Long
|
|
| K_Long_Long
|
|
| K_Unsigned_Short
|
|
| K_Unsigned_Long
|
|
| K_Unsigned_Long_Long
|
|
| K_Char
|
|
| K_Wide_Char
|
|
| K_Boolean
|
|
| K_Any
|
|
| K_Object
|
|
| K_Octet
|
|
| K_Value_Base
|
|
| K_String
|
|
| K_Wide_String
|
|
| K_Scoped_Name =>
|
|
return True;
|
|
|
|
when others =>
|
|
return False;
|
|
end case;
|
|
end Is_Param_Type_Spec;
|
|
|
|
--------------
|
|
-- Operator --
|
|
--------------
|
|
|
|
function Operator (E : Node_Id) return Operator_Type is
|
|
O : Operator_Id;
|
|
begin
|
|
O := Nodes.Operator (E);
|
|
return Operator_Type'Val (O);
|
|
end Operator;
|
|
|
|
-----------------------------
|
|
-- P_Attribute_Declaration --
|
|
-----------------------------
|
|
|
|
-- (85) <attr_dcl> ::= [ "readonly" ] "attribute"
|
|
-- <param_type_spec> <simple_declarator>
|
|
-- { "," <simple_declarator> }*
|
|
|
|
function P_Attribute_Declaration return Node_Id is
|
|
Attribute_Decl : Node_Id;
|
|
Attr_Type_Spec : Node_Id;
|
|
Is_Readonly : Boolean := False;
|
|
Declarators : Node_Id;
|
|
begin
|
|
Scan_Token; -- past "readonly" or "attribute"
|
|
|
|
if Token = T_Readonly then
|
|
Is_Readonly := True;
|
|
Scan_Token (T_Attribute);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
end if;
|
|
|
|
-- Read general type specifier
|
|
|
|
Attr_Type_Spec := P_Type_Spec;
|
|
if No (Attr_Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- Check that the type specifier follows the restriction of the
|
|
-- parameter type specifier.
|
|
|
|
if not Is_Param_Type_Spec (Attr_Type_Spec) then
|
|
Error_Loc (1) := Loc (Attr_Type_Spec);
|
|
DE ("incorrect attribute type spec");
|
|
return No_Node;
|
|
end if;
|
|
|
|
Declarators := P_Declarator_List;
|
|
if No (Declarators) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Attribute_Decl := New_Node (K_Attribute_Declaration,
|
|
Loc (Declarators));
|
|
Set_Is_Readonly (Attribute_Decl, Is_Readonly);
|
|
Set_Type_Spec (Attribute_Decl, Attr_Type_Spec);
|
|
Set_Declarators (Attribute_Decl, Declarators);
|
|
|
|
while Present (Declarators) loop
|
|
if Kind (Declarators) /= K_Simple_Declarator then
|
|
Error_Loc (1) := Loc (Declarators);
|
|
DE ("incorrect attribute declarator");
|
|
return No_Node;
|
|
end if;
|
|
Declarators := Next_Node (Declarators);
|
|
end loop;
|
|
|
|
return Attribute_Decl;
|
|
end P_Attribute_Declaration;
|
|
|
|
--------------------------
|
|
-- P_Complex_Declarator --
|
|
--------------------------
|
|
|
|
-- (52) <complex_declarator> ::= <array_declarator>
|
|
--
|
|
-- (83) <array_declarator> ::= <identifier> <fixed_array_size> +
|
|
-- (84) <fixed_array_size> ::= "[" <positive_int_const> "]"
|
|
|
|
function P_Complex_Declarator return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Array_Sizes : List_Id;
|
|
Array_Size : Node_Id;
|
|
begin
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Node := New_Node (K_Complex_Declarator, Loc (Identifier));
|
|
Associate (Node, Identifier);
|
|
|
|
Array_Sizes := New_List (K_Array_Size_List, Token_Location);
|
|
Set_Array_Sizes (Node, Array_Sizes);
|
|
|
|
loop
|
|
Scan_Token; -- past '['
|
|
|
|
Array_Size := P_Constant_Expression;
|
|
if No (Array_Size) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Append_Node_To_List (Array_Size, Array_Sizes);
|
|
|
|
Scan_Token (T_Right_Bracket);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
exit when Next_Token /= T_Left_Bracket;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Complex_Declarator;
|
|
|
|
----------------------------
|
|
-- P_Constant_Declaration --
|
|
----------------------------
|
|
|
|
-- (27) <const_dcl> ::= "const" <const_type> <identifier> "=" <const_exp>
|
|
|
|
function P_Constant_Declaration return Node_Id
|
|
is
|
|
Constant_Decl : Node_Id;
|
|
Const_Type_Spec : Node_Id;
|
|
Const_Expr : Node_Id;
|
|
begin
|
|
Scan_Token; -- past "const"
|
|
|
|
Const_Type_Spec := P_Constant_Type;
|
|
if No (Const_Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Constant_Decl := P_Simple_Declarator;
|
|
if No (Constant_Decl) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Set_Kind (Constant_Decl, K_Constant_Declaration);
|
|
Set_Type_Spec (Constant_Decl, Const_Type_Spec);
|
|
|
|
Scan_Token (T_Equal);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Const_Expr := P_Constant_Expression;
|
|
if No (Const_Expr) then
|
|
return No_Node;
|
|
end if;
|
|
Set_Expression (Constant_Decl, Const_Expr);
|
|
|
|
return Constant_Decl;
|
|
end P_Constant_Declaration;
|
|
|
|
---------------------------
|
|
-- P_Constant_Expression --
|
|
---------------------------
|
|
|
|
-- (29) <const_exp> ::= <or_expr>
|
|
-- (30) <or_expr> ::= <xor_expr>
|
|
-- | <or_expr> "|" <xor_expr>
|
|
|
|
-- (31) <xor_expr> ::= <and_expr>
|
|
-- | <xor_expr> "^" <and_expr>
|
|
|
|
-- (32) <and_expr> ::= <shift_expr>
|
|
-- | <and_expr> "&" <shift_expr>
|
|
|
|
-- (33) <shift_expr> ::= <add_expr>
|
|
-- | <shift_expr> ">>" <add_expr>
|
|
-- | <shift_expr> "<<" <add_expr>
|
|
|
|
-- (34) <add_expr> ::= <mult_expr>
|
|
-- | <add_expr> "+" <mult_expr>
|
|
-- | <add_expr> "-" <mult_expr>
|
|
|
|
-- (35) <mult_expr> ::= <unary_expr>
|
|
-- | <mult_expr> "*" <unary_expr>
|
|
-- | <mult_expr> "/" <unary_expr>
|
|
-- | <mult_expr> "%" <unary_expr>
|
|
|
|
-- (36) <unary_expr> ::= <unary_operator> <primary_expr>
|
|
-- | <primary_expr>
|
|
|
|
-- (37) <unary_operator> ::= "-"
|
|
-- | "+"
|
|
-- | "~"
|
|
|
|
-- (38) <primary_expr> ::= <scoped_name>
|
|
-- | <literal>
|
|
-- | "(" <const_exp> ")"
|
|
|
|
function P_Constant_Expression return Node_Id is
|
|
|
|
use Expressions;
|
|
|
|
-- There are two kinds of expressions. A binary operator has
|
|
-- two inner expressions (left and right). When the right
|
|
-- expression is assigned and not the left one, the operator is
|
|
-- an unary operator and this expression is considered as an
|
|
-- expression value. When both inner expressions are assigned,
|
|
-- this is also an expression value. An operator is a binary
|
|
-- operator when at least the right expression is not
|
|
-- assigned. An expression value can be an operator with at
|
|
-- least a right expression assigned or a literal or a scoped
|
|
-- name.
|
|
|
|
function Is_Expression_Completed return Boolean;
|
|
-- Return True when there are no more token to read to complete
|
|
-- the current expression.
|
|
|
|
function P_Expression_Part return Node_Id;
|
|
-- Return a node describing an expression. It is either a
|
|
-- binary operator (an operator with no right expression
|
|
-- assigned) or an expression value (a scoped name, a literal
|
|
-- or an expression with an unary operator - that is a binary
|
|
-- operator with a right inner expression and no left inner
|
|
-- expression - or an expression with both inner expressions
|
|
-- assigned). Note that whether an operator is a binary or
|
|
-- unary operator is resolved in this routine. For a unary
|
|
-- operator, we check that the previous token was a binary
|
|
-- operator.
|
|
|
|
function Is_Binary_Operator (E : Node_Id) return Boolean;
|
|
-- Return True when N is an operator with the right expression
|
|
-- still not assigned. Otherwise, an operator with a right
|
|
-- expression is a value expression.
|
|
|
|
function Is_Expression_Value (E : Node_Id) return Boolean;
|
|
-- Return True when N is not an operator (literal or scoped
|
|
-- name) or else when its right expression is assigned (unary
|
|
-- operator).
|
|
|
|
function Precede (L, R : Node_Id) return Boolean;
|
|
-- Does operator L precedes operator R
|
|
|
|
Exp_Err_Msg : constant String := "cannot parse expression";
|
|
-- Standard error message
|
|
|
|
-----------------------------
|
|
-- Is_Expression_Completed --
|
|
-----------------------------
|
|
|
|
function Is_Expression_Completed return Boolean
|
|
is
|
|
T : constant Token_Type := Next_Token;
|
|
begin
|
|
return T not in Literal_Type
|
|
and then T /= T_Identifier
|
|
and then T /= T_Colon_Colon
|
|
and then T /= T_Left_Paren
|
|
and then T not in Operator_Type;
|
|
end Is_Expression_Completed;
|
|
|
|
-------------------------
|
|
-- Is_Expression_Value --
|
|
-------------------------
|
|
|
|
function Is_Expression_Value (E : Node_Id) return Boolean is
|
|
begin
|
|
return Kind (E) = K_Literal
|
|
or else Kind (E) = K_Scoped_Name
|
|
or else Operator (E) not in Binary_Operator_Type
|
|
or else Present (Right_Expr (E));
|
|
end Is_Expression_Value;
|
|
|
|
------------------------
|
|
-- Is_Binary_Operator --
|
|
------------------------
|
|
|
|
function Is_Binary_Operator (E : Node_Id) return Boolean is
|
|
begin
|
|
return Kind (E) = K_Expression
|
|
and then Operator (E) in Binary_Operator_Type
|
|
and then No (Right_Expr (E));
|
|
end Is_Binary_Operator;
|
|
|
|
-----------------------
|
|
-- P_Expression_Part --
|
|
-----------------------
|
|
|
|
function P_Expression_Part return Node_Id is
|
|
Expression : Node_Id;
|
|
Right_Expr : Node_Id;
|
|
Previous_Token : Token_Type;
|
|
begin
|
|
case Next_Token is
|
|
when T_Identifier
|
|
| T_Colon_Colon =>
|
|
|
|
-- Look for a scoped name
|
|
|
|
Expression := P_Scoped_Name;
|
|
if No (Expression) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
when T_Left_Paren =>
|
|
|
|
-- Look for a parenthesized expression value
|
|
|
|
Scan_Token; -- past '('
|
|
Expression := P_Constant_Expression;
|
|
|
|
Scan_Token (T_Right_Paren);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
when T_Integer_Literal .. T_Wide_String_Literal =>
|
|
|
|
-- Look for a literal
|
|
|
|
Scan_Token; -- past literal
|
|
Expression := New_Node (K_Literal, Token_Location);
|
|
Set_Literal (Expression, Token_Name);
|
|
|
|
when T_Tilde .. T_Less_Less =>
|
|
|
|
-- Look for a binary/unary operator
|
|
|
|
Previous_Token := Token;
|
|
Scan_Token; -- past binary/unary operator
|
|
|
|
Expression := New_Node (K_Expression, Token_Location);
|
|
Set_Operator (Expression, Token);
|
|
|
|
-- Token is a real unary operator
|
|
|
|
if Token = T_Tilde
|
|
or else (Token in T_Minus .. T_Plus
|
|
and then not Is_Literal (Previous_Token)
|
|
and then not Is_Scoped_Name (Previous_Token)
|
|
and then Previous_Token /= T_Right_Paren)
|
|
then
|
|
case Next_Token is
|
|
when T_Identifier
|
|
| T_Colon_Colon
|
|
| T_Left_Paren
|
|
| T_Integer_Literal .. T_Wide_String_Literal =>
|
|
|
|
-- Look for an expression value (a scoped
|
|
-- name, a literal or a parenthesized
|
|
-- expression).
|
|
|
|
Right_Expr := P_Constant_Expression;
|
|
if No (Right_Expr) then
|
|
Error_Loc (1) := Loc (Expression);
|
|
DE (Exp_Err_Msg);
|
|
return No_Node;
|
|
end if;
|
|
Set_Right_Expr (Expression, Right_Expr);
|
|
|
|
when others =>
|
|
Unexpected_Token (Token, "expression");
|
|
return No_Node;
|
|
end case;
|
|
|
|
-- Cannot have two following operators except in the
|
|
-- special case above.
|
|
|
|
elsif Is_Operator (Previous_Token) then
|
|
Unexpected_Token (Token, "expression");
|
|
return No_Node;
|
|
end if;
|
|
|
|
when others =>
|
|
Error_Loc (1) := Token_Location;
|
|
DE (Exp_Err_Msg);
|
|
return No_Node;
|
|
end case;
|
|
|
|
return Expression;
|
|
end P_Expression_Part;
|
|
|
|
-------------
|
|
-- Precede --
|
|
-------------
|
|
|
|
function Precede (L, R : Node_Id) return Boolean is
|
|
Op_L : constant Token_Type := Operator (L);
|
|
Op_R : constant Token_Type := Operator (R);
|
|
begin
|
|
return Preferences (Op_L) < Preferences (Op_R);
|
|
end Precede;
|
|
|
|
Expr : Node_Id;
|
|
First : Natural;
|
|
|
|
begin
|
|
|
|
-- Read enough expressions to push as first expression a binary
|
|
-- operator with no right expression
|
|
|
|
Expr := P_Expression_Part;
|
|
if No (Expr) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- We must have first an expression value
|
|
|
|
if Is_Binary_Operator (Expr) then
|
|
Error_Loc (1) := Loc (Expr);
|
|
DE (Exp_Err_Msg);
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- We have only one expression value
|
|
|
|
if Is_Expression_Completed then
|
|
return Expr;
|
|
end if;
|
|
|
|
Increment_Last;
|
|
Table (Last) := Expr;
|
|
First := Last;
|
|
|
|
Expr := P_Expression_Part;
|
|
if No (Expr) then
|
|
Set_Last (First - 1);
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- We must have a binary operator as the first expression is an
|
|
-- expression value.
|
|
|
|
if not Is_Binary_Operator (Expr) then
|
|
Error_Loc (1) := Loc (Expr);
|
|
DE (Exp_Err_Msg);
|
|
Set_Last (First - 1);
|
|
return No_Node;
|
|
end if;
|
|
|
|
Set_Left_Expr (Expr, Table (Last));
|
|
Table (Last) := Expr;
|
|
|
|
-- Push expressions in stack and check that the top of the
|
|
-- stack consists in one or more binary operators with no
|
|
-- right expr and zero or one expression value.
|
|
|
|
while not Is_Expression_Completed loop
|
|
Expr := P_Expression_Part;
|
|
if No (Expr) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Increment_Last;
|
|
Table (Last) := Expr;
|
|
|
|
-- Check that this new expression is not a binary operator
|
|
-- when the previous one is a binary operator with no right
|
|
-- expression.
|
|
|
|
if First < Last
|
|
and then Is_Binary_Operator (Expr)
|
|
and then No (Left_Expr (Expr))
|
|
and then Is_Binary_Operator (Table (Last - 1))
|
|
then
|
|
Error_Loc (1) := Loc (Expr);
|
|
DE (Exp_Err_Msg);
|
|
Set_Last (First - 1);
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- Check whether we have a sequence of a binary operator
|
|
-- (left operator), an expression value and another binary
|
|
-- operator (right operator). In this case, if the left
|
|
-- operator has a better precedence than the right one, we
|
|
-- can reduce the global expression by assigning the
|
|
-- expression value to the right expression of the left
|
|
-- operator. Then as the left operator has already a left
|
|
-- expression, it becomes an expression value which can be
|
|
-- assign to the left expression of the right operation.
|
|
-- Recompute the size of the expression stack.
|
|
|
|
while First + 1 < Last
|
|
and then Is_Expression_Value (Table (Last - 1))
|
|
and then Precede (Table (Last - 2), Expr)
|
|
loop
|
|
Set_Right_Expr (Table (Last - 2), Table (Last - 1));
|
|
Set_Left_Expr (Table (Last), Table (Last - 2));
|
|
Table (Last - 2) := Table (Last);
|
|
Set_Last (Last - 2);
|
|
end loop;
|
|
end loop;
|
|
|
|
-- The last expression is not a value. We cannot reduce the
|
|
-- global expression
|
|
|
|
if Is_Binary_Operator (Table (Last)) then
|
|
Error_Loc (1) := Loc (Table (Last));
|
|
DE (Exp_Err_Msg);
|
|
Set_Last (First - 1);
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- Reduce the global expression
|
|
|
|
while First < Last loop
|
|
if No (Left_Expr (Table (Last - 1))) then
|
|
Set_Right_Expr (Table (Last - 1), Table (Last));
|
|
Set_Left_Expr (Table (Last - 1), Table (Last - 2));
|
|
Table (Last - 2) := Table (Last - 1);
|
|
Set_Last (Last - 2);
|
|
|
|
else
|
|
Set_Right_Expr (Table (Last - 1), Table (Last));
|
|
Set_Last (Last - 1);
|
|
end if;
|
|
end loop;
|
|
|
|
Expr := Table (First);
|
|
Set_Last (First - 1);
|
|
|
|
return Expr;
|
|
end P_Constant_Expression;
|
|
|
|
---------------------
|
|
-- P_Constant_Type --
|
|
---------------------
|
|
|
|
-- (28) <const_type> ::= <floating_pt_type>
|
|
-- | <integer_type>
|
|
-- | <char_type>
|
|
-- | <wide_char_type>
|
|
-- | <boolean_type>
|
|
-- | <octet_type>
|
|
-- | <string_type>
|
|
-- | <wide_string_type>
|
|
-- | <fixed_pt_const_type>
|
|
-- | <scoped_name>
|
|
|
|
function P_Constant_Type return Node_Id is
|
|
Const_Type : Node_Id;
|
|
State : Location;
|
|
begin
|
|
|
|
-- Use P_Simple_Type_Spec and reject incorrect type specifiers.
|
|
|
|
Save_Lexer (State);
|
|
Const_Type := P_Simple_Type_Spec;
|
|
case Kind (Const_Type) is
|
|
when K_Any
|
|
| K_Object
|
|
| K_Value_Base
|
|
| K_Sequence_Type
|
|
| K_Fixed_Point_Type =>
|
|
Restore_Lexer (State);
|
|
Unexpected_Token (Next_Token, "type specifier");
|
|
return No_Node;
|
|
|
|
when others =>
|
|
return Const_Type;
|
|
end case;
|
|
end P_Constant_Type;
|
|
|
|
------------------
|
|
-- P_Declarator --
|
|
------------------
|
|
|
|
-- (50) <declarator> ::= <simple_declarator>
|
|
-- | <complex_declarator>
|
|
-- (51) <simple_declarator> ::= <identifier>
|
|
-- (52) <complex_declarator> ::= <array_declarator>
|
|
--
|
|
-- (83) <array_declarator> ::= <identifier> <fixed_array_size> +
|
|
-- (84) <fixed_array_size> ::= "[" <positive_int_const> "]"
|
|
|
|
function P_Declarator return Node_Id is
|
|
State : Location;
|
|
|
|
begin
|
|
Save_Lexer (State);
|
|
if No (P_Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if Next_Token = T_Left_Bracket then
|
|
Restore_Lexer (State);
|
|
return P_Complex_Declarator;
|
|
|
|
else
|
|
Restore_Lexer (State);
|
|
return P_Simple_Declarator;
|
|
end if;
|
|
end P_Declarator;
|
|
|
|
-----------------------
|
|
-- P_Declarator_List --
|
|
-----------------------
|
|
|
|
-- (49) <declarators> ::= <declarator> { "," <declarator> }
|
|
|
|
function P_Declarator_List return Node_Id is
|
|
First : Node_Id := No_Node;
|
|
Previous : Node_Id := No_Node;
|
|
Current : Node_Id;
|
|
begin
|
|
loop
|
|
Current := P_Declarator;
|
|
if No (Current) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if No (First) then
|
|
First := Current;
|
|
end if;
|
|
|
|
if Present (Previous) then
|
|
Set_Next_Node (Previous, Current);
|
|
end if;
|
|
exit when Next_Token /= T_Comma;
|
|
Scan_Token; -- past ','
|
|
|
|
Previous := Current;
|
|
end loop;
|
|
|
|
return First;
|
|
end P_Declarator_List;
|
|
|
|
------------------
|
|
-- P_Definition --
|
|
------------------
|
|
|
|
-- (2) <definition> ::= <type_dcl> ";"
|
|
-- | <const_dcl> ";"
|
|
-- | <except_dcl> ";"
|
|
-- | <interface> ";"
|
|
-- | <module> ";"
|
|
-- | <value> ";"
|
|
|
|
function P_Definition return Node_Id is
|
|
Definition : Node_Id := No_Node;
|
|
State : Location;
|
|
begin
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
case Token is
|
|
when T_Typedef
|
|
| T_Struct
|
|
| T_Union
|
|
| T_Enum
|
|
| T_Native =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Type_Declaration;
|
|
|
|
when T_Const =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Constant_Declaration;
|
|
|
|
when T_Exception =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Exception_Declaration;
|
|
|
|
when T_Abstract =>
|
|
Scan_Token ((T_Interface, T_Value_Type));
|
|
if Token = T_Interface then
|
|
Restore_Lexer (State);
|
|
Definition := P_Interface;
|
|
|
|
elsif Token = T_Value_Type then
|
|
Restore_Lexer (State);
|
|
Definition := P_Value;
|
|
end if;
|
|
|
|
when T_Interface =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Interface;
|
|
|
|
when T_Module =>
|
|
Restore_Lexer (State);
|
|
Definition := Node_Id (P_Module);
|
|
|
|
when T_Value_Type
|
|
| T_Custom =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Value;
|
|
|
|
when T_Pragma =>
|
|
Restore_Lexer (State);
|
|
Definition := P_Pragma;
|
|
|
|
when others =>
|
|
Unexpected_Token (Token, "definition");
|
|
end case;
|
|
|
|
-- The definition is successfully parsed
|
|
|
|
if Present (Definition) then
|
|
Save_Lexer (State);
|
|
Scan_Token (T_Semi_Colon);
|
|
if Token = T_Error then
|
|
Definition := No_Node;
|
|
end if;
|
|
end if;
|
|
|
|
if No (Definition) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Semi_Colon);
|
|
end if;
|
|
|
|
return Definition;
|
|
end P_Definition;
|
|
|
|
------------------------
|
|
-- P_Enumeration_Type --
|
|
------------------------
|
|
|
|
-- (78) <enum_type> ::= "enum" <identifier>
|
|
-- "{" <enumerator> { "," <enumerator> } "}"
|
|
--
|
|
-- (79) <enumerator> ::= <identifier>
|
|
|
|
function P_Enumeration_Type return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Enumerator : Node_Id;
|
|
Enumerators : List_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "enum"
|
|
Node := New_Node (K_Enumeration_Type, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Enumerators := New_List (K_Enumerator_List, Token_Location);
|
|
Set_Enumerators (Node, Enumerators);
|
|
|
|
loop
|
|
-- Save lexer state in order to skip the enumerator list on error
|
|
|
|
Save_Lexer (State);
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Enumerator := New_Node (K_Simple_Declarator, Loc (Identifier));
|
|
Associate (Enumerator, Identifier);
|
|
|
|
Append_Node_To_List (Enumerator, Enumerators);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Comma, T_Right_Brace));
|
|
if Token /= T_Comma then
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
end if;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Enumeration_Type;
|
|
|
|
-----------------------------
|
|
-- P_Exception_Declaration --
|
|
-----------------------------
|
|
|
|
-- (86) <except_dcl> ::= "exception" <identifier> "{" <member>* "}"
|
|
|
|
function P_Exception_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Member : Node_Id;
|
|
Members : List_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "exception"
|
|
Node := New_Node (K_Exception_Declaration, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Members := New_List (K_Member_List, Token_Location);
|
|
Set_Members (Node, Members);
|
|
|
|
loop
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token; -- past '}'
|
|
exit;
|
|
end if;
|
|
|
|
-- Save lexer state to skip exception member list on error
|
|
|
|
Save_Lexer (State);
|
|
Member := P_Member;
|
|
if No (Member) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Member, Members);
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Exception_Declaration;
|
|
|
|
--------------
|
|
-- P_Export --
|
|
--------------
|
|
|
|
-- (9) <export> ::= <type_dcl> ";"
|
|
-- | <const_dcl> ";"
|
|
-- | <except_dcl> ";"
|
|
-- | <attr_dcl> ";"
|
|
-- | <op_dcl> ";"
|
|
|
|
function P_Export return Node_Id is
|
|
State : Location;
|
|
Export : Node_Id;
|
|
|
|
begin
|
|
|
|
-- Save lexer state to skip declaration on error
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
case Token is
|
|
when T_Const =>
|
|
Restore_Lexer (State);
|
|
Export := P_Constant_Declaration;
|
|
|
|
when T_Exception =>
|
|
Restore_Lexer (State);
|
|
Export := P_Exception_Declaration;
|
|
|
|
when T_Attribute
|
|
| T_Readonly =>
|
|
Restore_Lexer (State);
|
|
Export := P_Attribute_Declaration;
|
|
|
|
when T_Typedef
|
|
| T_Struct
|
|
| T_Union
|
|
| T_Enum
|
|
| T_Native =>
|
|
Restore_Lexer (State);
|
|
Export := P_Type_Declaration;
|
|
|
|
when others =>
|
|
Restore_Lexer (State);
|
|
Export := P_Operation_Declaration;
|
|
end case;
|
|
|
|
if Present (Export) then
|
|
Save_Lexer (State);
|
|
Scan_Token (T_Semi_Colon);
|
|
if Token = T_Error then
|
|
Export := No_Node;
|
|
end if;
|
|
end if;
|
|
|
|
if No (Export) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Semi_Colon);
|
|
end if;
|
|
|
|
return Export;
|
|
end P_Export;
|
|
|
|
------------------------
|
|
-- P_Fixed_Point_Type --
|
|
------------------------
|
|
|
|
-- (96) <fixed_pt_type> ::= "fixed" "<" <positive_int_const> ","
|
|
-- <positive_int_const> ">"
|
|
--
|
|
-- (97) <fixed_pt_const_type> ::= "fixed"
|
|
|
|
function P_Fixed_Point_Type return Node_Id is
|
|
Node : Node_Id;
|
|
|
|
begin
|
|
Scan_Token; -- past "fixed"
|
|
Node := New_Node (K_Fixed_Point_Type, Token_Location);
|
|
|
|
if Next_Token = T_Less then
|
|
Scan_Token; -- past '<'
|
|
|
|
Scan_Token (T_Integer_Literal);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Set_N_Digits (Node, Token_Name);
|
|
|
|
Scan_Token (T_Comma);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Scan_Token (T_Integer_Literal);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Set_N_Delta (Node, Token_Name);
|
|
|
|
Scan_Token (T_Greater);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
end if;
|
|
|
|
return Node;
|
|
end P_Fixed_Point_Type;
|
|
|
|
------------------
|
|
-- P_Identifier --
|
|
------------------
|
|
|
|
function P_Identifier return Node_Id is
|
|
Identifier : Node_Id;
|
|
begin
|
|
Scan_Token (T_Identifier);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Identifier := New_Node (K_Identifier, Token_Location);
|
|
Set_IDL_Name (Identifier, Token_Name);
|
|
Set_Name (Identifier, To_Lower (Token_Name));
|
|
return Identifier;
|
|
end P_Identifier;
|
|
|
|
-------------------------------
|
|
-- P_Initializer_Declaration --
|
|
-------------------------------
|
|
|
|
-- (23) <init_dcl> ::= "factory" <identifier>
|
|
-- "(" [ <init_param_decls> ] ")" ";"
|
|
-- (24) <init_param_decls> ::= <init_param_decl>
|
|
-- { "," <init_param_decl> }*
|
|
-- (25) <init_param_decl> ::= <init_param_attribute> <param_type_spec>
|
|
-- <simple_declarator>
|
|
|
|
function P_Initializer_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Parameters : List_Id;
|
|
Parameter : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "factory"
|
|
Node := New_Node (K_Initializer_Declaration, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Left_Paren);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Parameters := New_List (K_Initializer_Parameter_List, Token_Location);
|
|
Set_Parameters (Node, Parameters);
|
|
|
|
loop
|
|
-- Check the parameter mode is "in". Then parse a general
|
|
-- parameter declaration.
|
|
|
|
Save_Lexer (State);
|
|
if Next_Token = T_In then
|
|
Parameter := P_Parameter_Declaration;
|
|
if No (Parameter) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Parameter, Parameters);
|
|
end if;
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Right_Paren, T_Comma));
|
|
if Token /= T_Comma then
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
end if;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Initializer_Declaration;
|
|
|
|
-----------------
|
|
-- P_Interface --
|
|
-----------------
|
|
|
|
-- (4) <interface> ::= <interface_dcl>
|
|
-- | <forward_dcl>
|
|
|
|
function P_Interface return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Is_Abstract : Boolean := False;
|
|
State : Location;
|
|
Fwd_Loc : Location;
|
|
|
|
begin
|
|
Save_Lexer (State);
|
|
|
|
Scan_Token; -- past "abstract" or "interface"
|
|
Fwd_Loc := Token_Location;
|
|
if Token = T_Abstract then
|
|
Is_Abstract := True;
|
|
Scan_Token; -- past "interface"
|
|
end if;
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
case Next_Token is
|
|
when T_Semi_Colon =>
|
|
Node := New_Node (K_Forward_Interface_Declaration, Fwd_Loc);
|
|
Associate (Node, Identifier);
|
|
Set_Is_Abstract (Node, Is_Abstract);
|
|
|
|
when T_Left_Brace
|
|
| T_Colon =>
|
|
Restore_Lexer (State);
|
|
return P_Interface_Declaration;
|
|
|
|
when others =>
|
|
return No_Node;
|
|
end case;
|
|
|
|
return Node;
|
|
end P_Interface;
|
|
|
|
-----------------------------
|
|
-- P_Interface_Declaration --
|
|
-----------------------------
|
|
|
|
-- (5) <interface_dcl> ::= <interface_header> "{" <interface_body> "}"
|
|
-- (7) <interface_header> ::=
|
|
-- [ "abstract" | "local" ] "interface" <identifier>
|
|
-- [ <interface_inheritance_spec> ]
|
|
-- (8) <interface_body> ::= <export> *
|
|
-- (10) <interface_inheritance_spec>::= ":" <interface_name>
|
|
-- { "," <interface_name> } *
|
|
|
|
function P_Interface_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Interface_Body : List_Id;
|
|
Export : Node_Id;
|
|
Interface_Spec : List_Id;
|
|
Interface_Name : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "abstract" or "interface"
|
|
Node := New_Node (K_Interface_Declaration, Token_Location);
|
|
|
|
if Token = T_Abstract then
|
|
Set_Is_Abstract (Node, True);
|
|
Scan_Token; -- past "interface"
|
|
end if;
|
|
|
|
Identifier := P_Identifier;
|
|
Associate (Node, Identifier);
|
|
|
|
-- Parse interface inheritance specifier
|
|
|
|
if Next_Token = T_Colon then
|
|
Interface_Spec := New_List (K_Interface_Name_List, Token_Location);
|
|
Set_Interface_Spec (Node, Interface_Spec);
|
|
|
|
Scan_Token; -- past ':'
|
|
|
|
loop
|
|
Interface_Name := P_Interface_Name;
|
|
if No (Interface_Name) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Append_Node_To_List (Interface_Name, Interface_Spec);
|
|
|
|
exit when Next_Token /= T_Comma;
|
|
Scan_Token; -- past ','
|
|
end loop;
|
|
end if;
|
|
|
|
-- Parse interface body
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Interface_Body := New_List (K_Interface_Body, Token_Location);
|
|
Set_Interface_Body (Node, Interface_Body);
|
|
|
|
loop
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token; -- past '}'
|
|
exit;
|
|
end if;
|
|
|
|
-- Parse export. Save lexer state to skip interface body on
|
|
-- error.
|
|
|
|
Save_Lexer (State);
|
|
Export := P_Export;
|
|
if No (Export) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Export, Interface_Body);
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Interface_Declaration;
|
|
|
|
----------------------
|
|
-- P_Interface_Name --
|
|
----------------------
|
|
|
|
-- (11) <interface_name> ::= <scoped_name>
|
|
|
|
function P_Interface_Name return Node_Id is
|
|
begin
|
|
return P_Scoped_Name;
|
|
end P_Interface_Name;
|
|
|
|
--------------
|
|
-- P_Member --
|
|
--------------
|
|
|
|
-- (71) <member> ::= <type_spec> <declarators> ";"
|
|
-- (49) <declarators> ::= <declarator> { "," <declarator> }
|
|
|
|
function P_Member return Node_Id is
|
|
Member : Node_Id;
|
|
Declarators : Node_Id;
|
|
Type_Spec : Node_Id;
|
|
State : Location;
|
|
begin
|
|
-- Parse type specifier. Save lexer state to skip declaration
|
|
-- on error.
|
|
|
|
Save_Lexer (State);
|
|
Type_Spec := P_Type_Spec;
|
|
if No (Type_Spec) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Semi_Colon);
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- Parse declarators. Save lexer state to skip declarators on
|
|
-- error.
|
|
|
|
Save_Lexer (State);
|
|
Declarators := P_Declarator_List;
|
|
if No (Declarators) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Semi_Colon);
|
|
return No_Node;
|
|
end if;
|
|
|
|
Member := New_Node (K_Member, Loc (Declarators));
|
|
Set_Type_Spec (Member, Type_Spec);
|
|
Set_Declarators (Member, Declarators);
|
|
|
|
Scan_Token (T_Semi_Colon);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
return Member;
|
|
end P_Member;
|
|
|
|
--------------
|
|
-- P_Module --
|
|
--------------
|
|
|
|
-- (3) <module> ::= "module" <identifier> "{" <definition> + "}"
|
|
|
|
function P_Module return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Definitions : List_Id;
|
|
Definition : Node_Id;
|
|
|
|
begin
|
|
Scan_Token; -- past "module"
|
|
Node := New_Node (K_Module, Token_Location);
|
|
|
|
-- Save module declaration location since we may have to reopen
|
|
-- a previous declaration.
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Definitions := New_List (K_Definition_List, Token_Location);
|
|
Set_Definitions (Node, Definitions);
|
|
|
|
loop
|
|
Definition := P_Definition;
|
|
if Present (Definition) then
|
|
Append_Node_To_List (Definition, Definitions);
|
|
end if;
|
|
|
|
case Next_Token is
|
|
when T_Right_Brace =>
|
|
Scan_Token; -- past '}'
|
|
exit;
|
|
|
|
when T_EOF =>
|
|
exit;
|
|
|
|
when others =>
|
|
null;
|
|
end case;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Module;
|
|
|
|
--------------------
|
|
-- P_No_Such_Node --
|
|
--------------------
|
|
|
|
function P_No_Such_Node return Node_Id is
|
|
begin
|
|
Scan_Token;
|
|
Error_Loc (1) := Token_Location;
|
|
DE ("not implemented");
|
|
return No_Node;
|
|
end P_No_Such_Node;
|
|
|
|
-----------------------------
|
|
-- P_Operation_Declaration --
|
|
-----------------------------
|
|
|
|
-- (87) <op_dcl> ::= [ <op_attribute> ] <op_type_spec>
|
|
-- <identifier> <parameter_dcls>
|
|
-- [ <raises_expr> ] [ <context_expr> ]
|
|
--
|
|
-- (88) <op_attribute> ::= "oneway"
|
|
-- (89) <op_type_spec> ::= <param_type_spec>
|
|
-- | "void"
|
|
--
|
|
-- (90) <parameter_dcls> ::= "(" <param_dcl> { "," <param_dcl> } ")"
|
|
-- | "(" ")"
|
|
--
|
|
-- (91) <param_dcl> ::= <param_attribute> <param_type_spec>
|
|
-- <simple_declarator>
|
|
--
|
|
-- (92) <param_attribute> ::= "in"
|
|
-- | "out"
|
|
-- | "inout"
|
|
--
|
|
-- (93) <raises_expr> ::= "raises" "(" <scoped_name>
|
|
-- { "," <scoped_name> } ")"
|
|
--
|
|
-- (94) <context_expr> ::= "context" "(" <string_literal>
|
|
-- { "," <string_literal> } ")"
|
|
|
|
function P_Operation_Declaration return Node_Id is
|
|
function P_Context_List return List_Id;
|
|
function P_Exception_List return List_Id;
|
|
|
|
--------------------
|
|
-- P_Context_List --
|
|
--------------------
|
|
|
|
-- (94) <context_expr> ::= "context" "(" <string_literal>
|
|
-- { "," <string_literal> } ")"
|
|
|
|
function P_Context_List return List_Id is
|
|
Context_List : List_Id;
|
|
String_Literal : Node_Id;
|
|
State : Location;
|
|
begin
|
|
Scan_Token; -- past "context"
|
|
Scan_Token (T_Left_Paren);
|
|
if Token = T_Error then
|
|
return No_List;
|
|
end if;
|
|
|
|
Context_List := New_List (K_Context_List, Token_Location);
|
|
loop
|
|
-- Parse string literal. Save lexer state to skip
|
|
-- literals on error.
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_String_Literal, T_Wide_String_Literal));
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
exit;
|
|
end if;
|
|
|
|
String_Literal := New_Node (K_Literal, Token_Location);
|
|
Set_Literal (String_Literal, Token_Name);
|
|
|
|
Append_Node_To_List (String_Literal, Context_List);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Right_Paren, T_Comma));
|
|
if Token /= T_Comma then
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
end if;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Context_List;
|
|
end P_Context_List;
|
|
|
|
----------------------
|
|
-- P_Exception_List --
|
|
----------------------
|
|
|
|
-- (93) <raises_expr> ::= "raises" "(" <scoped_name>
|
|
-- { "," <scoped_name> } ")"
|
|
|
|
function P_Exception_List return List_Id is
|
|
Exception_List : List_Id;
|
|
Scoped_Name : Node_Id;
|
|
State : Location;
|
|
begin
|
|
Scan_Token; -- past "raises"
|
|
Scan_Token (T_Left_Paren);
|
|
if Token = T_Error then
|
|
return No_List;
|
|
end if;
|
|
|
|
Exception_List := New_List (K_Exception_List, Token_Location);
|
|
loop
|
|
Save_Lexer (State);
|
|
Scoped_Name := P_Scoped_Name;
|
|
if No (Scoped_Name) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Scoped_Name, Exception_List);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Comma, T_Right_Paren));
|
|
if Token /= T_Comma then
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
end if;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Exception_List;
|
|
end P_Exception_List;
|
|
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Parameter : Node_Id;
|
|
Parameters : List_Id;
|
|
Param_Type_Spec : Node_Id;
|
|
Contexts : List_Id;
|
|
Exceptions : List_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
Node := New_Node (K_Operation_Declaration, Token_Location);
|
|
|
|
if Token = T_Oneway then
|
|
Set_Is_Oneway (Node, True);
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
end if;
|
|
|
|
if Token = T_Void then
|
|
Param_Type_Spec := Resolve_Base_Type ((1 => T_Void));
|
|
|
|
else
|
|
Restore_Lexer (State);
|
|
|
|
Param_Type_Spec := P_Simple_Type_Spec;
|
|
if No (Param_Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if not Is_Param_Type_Spec (Param_Type_Spec) then
|
|
Error_Loc (1) := Loc (Param_Type_Spec);
|
|
DE ("incorrect param type spec");
|
|
return No_Node;
|
|
end if;
|
|
end if;
|
|
Set_Type_Spec (Node, Param_Type_Spec);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Left_Paren);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Parameters := New_List (K_Parameter_List, Token_Location);
|
|
Set_Parameters (Node, Parameters);
|
|
|
|
if Next_Token = T_Right_Paren then
|
|
Scan_Token; -- past ')'
|
|
|
|
else
|
|
Save_Lexer (State);
|
|
loop
|
|
Parameter := P_Parameter_Declaration;
|
|
if No (Parameter) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Parameter, Parameters);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Right_Paren, T_Comma));
|
|
if Token /= T_Comma then
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
end if;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
|
|
if Next_Token = T_Raises then
|
|
Exceptions := P_Exception_List;
|
|
if Exceptions = No_List then
|
|
return No_Node;
|
|
end if;
|
|
Set_Exceptions (Node, Exceptions);
|
|
end if;
|
|
|
|
if Next_Token = T_Context then
|
|
Contexts := P_Context_List;
|
|
if Contexts = No_List then
|
|
return No_Node;
|
|
end if;
|
|
Set_Contexts (Node, Contexts);
|
|
end if;
|
|
|
|
return Node;
|
|
end P_Operation_Declaration;
|
|
|
|
-----------------------------
|
|
-- P_Parameter_Declaration --
|
|
-----------------------------
|
|
|
|
-- (91) <param_dcl> ::= <param_attribute> <param_type_spec>
|
|
-- <simple_declarator>
|
|
--
|
|
-- (92) <param_attribute> ::= "in"
|
|
-- | "out"
|
|
-- | "inout"
|
|
|
|
function P_Parameter_Declaration return Node_Id is
|
|
Param_Declaration : Node_Id;
|
|
Param_Declarator : Node_Id;
|
|
Param_Type_Spec : Node_Id;
|
|
Param_Mode : Token_Type;
|
|
Param_Location : Location;
|
|
|
|
begin
|
|
Scan_Token ((T_In, T_Inout, T_Out));
|
|
Param_Location := Token_Location;
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Param_Mode := Token;
|
|
|
|
Param_Type_Spec := P_Simple_Type_Spec;
|
|
if not Is_Param_Type_Spec (Param_Type_Spec) then
|
|
Error_Loc (1) := Loc (Param_Type_Spec);
|
|
DE ("incorrect param type spec");
|
|
return No_Node;
|
|
end if;
|
|
|
|
Param_Declarator := P_Simple_Declarator;
|
|
if No (Param_Declarator) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Param_Declaration :=
|
|
New_Node (K_Parameter_Declaration, Param_Location);
|
|
Set_Parameter_Mode (Param_Declaration, Param_Mode);
|
|
Set_Type_Spec (Param_Declaration, Param_Type_Spec);
|
|
Set_Declarator (Param_Declaration, Param_Declarator);
|
|
|
|
return Param_Declaration;
|
|
end P_Parameter_Declaration;
|
|
|
|
-------------------
|
|
-- P_Scoped_Name --
|
|
-------------------
|
|
|
|
-- (12) <scoped_name> ::= <identifier>
|
|
-- | "::" <identifier>
|
|
-- | <scoped_name> "::" <identifier>
|
|
|
|
function P_Scoped_Name return Node_Id is
|
|
Scoped_Name : Node_Id := No_Node;
|
|
Parent : Node_Id := No_Node;
|
|
Identifier : Node_Id;
|
|
|
|
begin
|
|
-- Scoped name starts with a '::'
|
|
|
|
if Next_Token = T_Colon_Colon then
|
|
Scan_Token; -- past '::'
|
|
-- Identifier := New_Node (K_Identifier, Token_Location);
|
|
-- Set_IDL_Name (Identifier, Root_Name);
|
|
-- Set_Name (Identifier, Root_Name);
|
|
-- Scoped_Name := New_Node (K_Scoped_Name, Token_Location);
|
|
-- Associate (Scoped_Name, Identifier);
|
|
Scoped_Name := No_Node;
|
|
end if;
|
|
|
|
-- start loop with an identifier
|
|
|
|
loop
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Parent := Scoped_Name;
|
|
Scoped_Name := New_Node (K_Scoped_Name, Token_Location);
|
|
Associate (Scoped_Name, Identifier);
|
|
Set_Parent (Scoped_Name, Parent);
|
|
|
|
exit when Next_Token /= T_Colon_Colon;
|
|
Scan_Token; -- past '::'
|
|
end loop;
|
|
|
|
return Scoped_Name;
|
|
end P_Scoped_Name;
|
|
|
|
---------------------
|
|
-- P_Sequence_Type --
|
|
---------------------
|
|
|
|
-- (80) <sequence_type> ::= "sequence" "<" <simple_type_spec> ","
|
|
-- <positive_int_const> ">"
|
|
-- | "sequence" "<" <simple_type_spec> ">"
|
|
|
|
function P_Sequence_Type return Node_Id is
|
|
Node : Node_Id;
|
|
Seq_Type_Spec : Node_Id;
|
|
Seq_Level : Natural;
|
|
|
|
begin
|
|
Scan_Token; -- past "sequence"
|
|
Node := New_Node (K_Sequence_Type, Token_Location);
|
|
|
|
Scan_Token (T_Less);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Sequencing_Level := Sequencing_Level + 1;
|
|
Seq_Level := Sequencing_Level;
|
|
|
|
Seq_Type_Spec := P_Type_Spec;
|
|
if No (Seq_Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
Set_Type_Spec (Node, Seq_Type_Spec);
|
|
|
|
if Seq_Level > Sequencing_Level then
|
|
return Node;
|
|
end if;
|
|
|
|
if Sequencing_Level > 1 then
|
|
Scan_Token ((T_Comma, T_Greater, T_Greater_Greater));
|
|
else
|
|
Scan_Token ((T_Comma, T_Greater));
|
|
end if;
|
|
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if Token = T_Comma then
|
|
Scan_Token (T_Integer_Literal);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Set_Max_Size (Node, Token_Name);
|
|
|
|
if Sequencing_Level > 1 then
|
|
Scan_Token ((T_Greater, T_Greater_Greater));
|
|
else
|
|
Scan_Token (T_Greater);
|
|
end if;
|
|
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
-- A maximum size of zero stands for no size
|
|
|
|
else
|
|
Set_Max_Size (Node, No_Name);
|
|
end if;
|
|
|
|
if Token = T_Greater_Greater then
|
|
Sequencing_Level := Sequencing_Level - 2;
|
|
else
|
|
Sequencing_Level := Sequencing_Level - 1;
|
|
end if;
|
|
|
|
return Node;
|
|
end P_Sequence_Type;
|
|
|
|
-------------------------
|
|
-- P_Simple_Declarator --
|
|
-------------------------
|
|
|
|
-- (51) <simple_declarator> ::= <identifier>
|
|
|
|
function P_Simple_Declarator return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
|
|
begin
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Node := New_Node (K_Simple_Declarator, Loc (Identifier));
|
|
Associate (Node, Identifier);
|
|
|
|
return Node;
|
|
end P_Simple_Declarator;
|
|
|
|
------------------------
|
|
-- P_Simple_Type_Spec --
|
|
------------------------
|
|
|
|
-- (45) <simple_type_spec> ::= <base_type_spec>
|
|
-- | <template_type_spec>
|
|
-- | <scoped_name>
|
|
--
|
|
-- (46) <base_type_spec> ::= <floating_pt_type>
|
|
-- | <integer_type>
|
|
-- | <char_type>
|
|
-- | <wide_char_type>
|
|
-- | <boolean_type>
|
|
-- | <octet_type>
|
|
-- | <any_type>
|
|
-- | <object_type>
|
|
-- | <value_base_type>
|
|
--
|
|
-- (47) <template_type_spec> ::= <sequence_type>
|
|
-- | <string_type>
|
|
-- | <wide_string_type>
|
|
-- | <fixed_pt_type>
|
|
|
|
function P_Simple_Type_Spec return Node_Id is
|
|
State : Location;
|
|
List : Token_List_Type (1 .. 3) := (others => T_Error);
|
|
Size : Natural := 0;
|
|
|
|
procedure Push_Base_Type_Token (T : Token_Type);
|
|
-- Push token in the list above. This token is either T_Float,
|
|
-- T_Double, T_Short, T_Long, T_Unsigned, T_Char, T_Wchar or T_Octet.
|
|
|
|
function Resolve_Base_Type return Node_Id;
|
|
|
|
--------------------------
|
|
-- Push_Base_Type_Token --
|
|
--------------------------
|
|
|
|
procedure Push_Base_Type_Token (T : Token_Type) is
|
|
begin
|
|
Size := Size + 1;
|
|
List (Size) := T;
|
|
end Push_Base_Type_Token;
|
|
|
|
-----------------------
|
|
-- Resolve_Base_Type --
|
|
-----------------------
|
|
|
|
function Resolve_Base_Type return Node_Id is
|
|
begin
|
|
return Resolve_Base_Type (List (1 .. Size));
|
|
end Resolve_Base_Type;
|
|
|
|
begin
|
|
Size := 0;
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
Push_Base_Type_Token (Token);
|
|
case Token is
|
|
when T_Long =>
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
if Token = T_Double
|
|
or else Token = T_Long
|
|
then
|
|
Push_Base_Type_Token (Token);
|
|
else
|
|
Restore_Lexer (State);
|
|
end if;
|
|
return Resolve_Base_Type;
|
|
|
|
when T_Short
|
|
| T_Float
|
|
| T_Double
|
|
| T_Char
|
|
| T_Wchar
|
|
| T_Boolean
|
|
| T_Octet
|
|
| T_Any
|
|
| T_Object
|
|
| T_Value_Base =>
|
|
return Resolve_Base_Type;
|
|
|
|
when T_Unsigned =>
|
|
Scan_Token ((T_Short, T_Long));
|
|
Push_Base_Type_Token (Token);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
|
|
elsif Token = T_Long then
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
if Token = T_Long then
|
|
Push_Base_Type_Token (Token);
|
|
else
|
|
Restore_Lexer (State);
|
|
end if;
|
|
end if;
|
|
return Resolve_Base_Type;
|
|
|
|
when T_String
|
|
| T_Wstring =>
|
|
Restore_Lexer (State);
|
|
return P_String_Type;
|
|
|
|
when T_Fixed =>
|
|
Restore_Lexer (State);
|
|
return P_Fixed_Point_Type;
|
|
|
|
when T_Identifier
|
|
| T_Colon_Colon =>
|
|
Restore_Lexer (State);
|
|
return P_Scoped_Name;
|
|
|
|
when T_Sequence =>
|
|
Restore_Lexer (State);
|
|
return P_Sequence_Type;
|
|
|
|
when others =>
|
|
return No_Node;
|
|
end case;
|
|
end P_Simple_Type_Spec;
|
|
|
|
---------------------
|
|
-- P_Specification --
|
|
---------------------
|
|
|
|
-- (1) <specification> ::= <definition> +
|
|
|
|
function P_Specification return Node_Id is
|
|
Node : Node_Id;
|
|
Definitions : List_Id;
|
|
Definition : Node_Id;
|
|
|
|
begin
|
|
Node := New_Node (K_Specification, Token_Location);
|
|
Definitions := New_List (K_Definition_List, Token_Location);
|
|
Set_Definitions (Node, Definitions);
|
|
|
|
loop
|
|
Definition := P_Definition;
|
|
if Present (Definition) then
|
|
Append_Node_To_List (Definition, Definitions);
|
|
end if;
|
|
exit when Next_Token = T_EOF;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Specification;
|
|
|
|
--------------------
|
|
-- P_State_Member --
|
|
--------------------
|
|
|
|
-- (22) <state_member> ::= ( "public" | "private" )
|
|
-- <type_spec> <declarators> ";"
|
|
-- (49) <declarators> ::= <declarator> { "," <declarator> }
|
|
|
|
function P_State_Member return Node_Id is
|
|
Declarator : Node_Id;
|
|
Type_Spec : Node_Id;
|
|
State_Member : Node_Id := No_Node;
|
|
Is_Public : Boolean := False;
|
|
begin
|
|
Scan_Token; -- past "public" or "private"
|
|
if Token = T_Public then
|
|
Is_Public := True;
|
|
end if;
|
|
|
|
Type_Spec := P_Type_Spec;
|
|
if No (Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Declarator := P_Declarator_List;
|
|
if No (Declarator) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
while Present (Declarator) loop
|
|
Set_Kind (Declarator, K_State_Member);
|
|
Set_Type_Spec (Declarator, Type_Spec);
|
|
Set_Is_Public (Declarator, Is_Public);
|
|
if No (State_Member) then
|
|
State_Member := Declarator;
|
|
end if;
|
|
Declarator := Next_Node (Declarator);
|
|
end loop;
|
|
|
|
return State_Member;
|
|
end P_State_Member;
|
|
|
|
-------------------
|
|
-- P_String_Type --
|
|
-------------------
|
|
|
|
-- (81) <string_type> ::= "string" "<" <positive_int_const> ">"
|
|
-- | "string"
|
|
--
|
|
-- (82) <wide_string_type> ::= "wstring" "<" <positive_int_const> ">"
|
|
-- | "wstring"
|
|
|
|
function P_String_Type return Node_Id is
|
|
Node : Node_Id;
|
|
begin
|
|
Scan_Token;
|
|
if Token = T_String then
|
|
Node := New_Node (K_String, Token_Location);
|
|
else
|
|
Node := New_Node (K_Wide_String, Token_Location);
|
|
end if;
|
|
|
|
if Next_Token = T_Less then
|
|
Scan_Token; -- past '<'
|
|
|
|
Scan_Token (T_Integer_Literal);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
Set_Max_Size (Node, Token_Name);
|
|
|
|
Scan_Token (T_Greater);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
else
|
|
Set_Max_Size (Node, No_Name);
|
|
end if;
|
|
|
|
return Node;
|
|
end P_String_Type;
|
|
|
|
----------------------
|
|
-- P_Structure_Type --
|
|
----------------------
|
|
|
|
-- (69) <struct_type> ::= "struct" <identifier> "{" <member_list> "}"
|
|
-- (70) <member_list> ::= <member> +
|
|
|
|
function P_Structure_Type return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Members : List_Id;
|
|
Member : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "struct";
|
|
Node := New_Node (K_Structure_Type, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Members := New_List (K_Member_List, Token_Location);
|
|
Set_Members (Node, Members);
|
|
|
|
Scan_Token; -- past '{'
|
|
|
|
loop
|
|
Save_Lexer (State);
|
|
Member := P_Member;
|
|
if No (Member) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Member, Members);
|
|
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Structure_Type;
|
|
|
|
------------------------
|
|
-- P_Type_Declaration --
|
|
------------------------
|
|
|
|
-- (42) <type_dcl> ::= "typedef" <type_declarator>
|
|
-- | <struct_type>
|
|
-- | <union_type>
|
|
-- | <enum_type>
|
|
-- | "native" <simple_declarator>
|
|
-- | <constr_forward_decl>
|
|
-- (43) <type_declarator> ::= <type_spec> <declarators>
|
|
|
|
function P_Type_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id := No_Node;
|
|
Type_Spec : Node_Id;
|
|
Declarator : Node_Id;
|
|
Declarators : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
|
|
case Token is
|
|
when T_Typedef =>
|
|
Type_Spec := P_Type_Spec;
|
|
if No (Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Declarators := P_Declarator_List;
|
|
if No (Declarators) then
|
|
return No_Node;
|
|
end if;
|
|
Node := New_Node (K_Type_Declaration, State);
|
|
Set_Type_Spec (Node, Type_Spec);
|
|
Set_Declarators (Node, Declarators);
|
|
|
|
when T_Native =>
|
|
|
|
Declarator := P_Simple_Declarator;
|
|
if No (Declarator) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Node := New_Node (K_Native_Type, State);
|
|
Set_Declarator (Node, Declarator);
|
|
|
|
when T_Struct =>
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if Next_Token = T_Semi_Colon then
|
|
Node := New_Node (K_Forward_Structure_Type, State);
|
|
Associate (Node, Identifier);
|
|
|
|
else
|
|
Restore_Lexer (State);
|
|
return P_Structure_Type;
|
|
end if;
|
|
|
|
when T_Union =>
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
if Next_Token = T_Semi_Colon then
|
|
Node := New_Node (K_Forward_Union_Type, State);
|
|
Associate (Node, Identifier);
|
|
|
|
else
|
|
Restore_Lexer (State);
|
|
return P_Union_Type;
|
|
end if;
|
|
|
|
when T_Enum =>
|
|
Restore_Lexer (State);
|
|
return P_Enumeration_Type;
|
|
|
|
when others =>
|
|
return No_Node;
|
|
end case;
|
|
|
|
return Node;
|
|
end P_Type_Declaration;
|
|
|
|
-----------------
|
|
-- P_Type_Spec --
|
|
-----------------
|
|
|
|
-- (44) <type_spec> ::= <simple_type_spec>
|
|
-- | <constr_type_spec>
|
|
--
|
|
-- (45) <simple_type_spec> ::= <base_type_spec>
|
|
-- | <template_type_spec>
|
|
-- | <scoped_name>
|
|
--
|
|
-- (46) <base_type_spec> ::= <floating_pt_type>
|
|
-- | <integer_type>
|
|
-- | <char_type>
|
|
-- | <wide_char_type>
|
|
-- | <boolean_type>
|
|
-- | <octet_type>
|
|
-- | <any_type>
|
|
-- | <object_type>
|
|
-- | <value_base_type>
|
|
--
|
|
-- (47) <template_type_spec> ::= <sequence_type>
|
|
-- | <string_type>
|
|
-- | <wide_string_type>
|
|
-- | <fixed_pt_type>
|
|
--
|
|
-- (48) <constr_type_spec> ::= <struct_type>
|
|
-- | <union_type>
|
|
-- | <enum_type>
|
|
|
|
function P_Type_Spec return Node_Id is
|
|
begin
|
|
case Next_Token is
|
|
when T_Struct =>
|
|
return P_Structure_Type;
|
|
|
|
when T_Enum =>
|
|
return P_Enumeration_Type;
|
|
|
|
when T_Union =>
|
|
return P_Union_Type;
|
|
|
|
when others =>
|
|
return P_Simple_Type_Spec;
|
|
end case;
|
|
end P_Type_Spec;
|
|
|
|
------------------
|
|
-- P_Union_Type --
|
|
------------------
|
|
|
|
-- (72) <union_type> ::= "union" <identifier> "switch"
|
|
-- "(" <switch_type_spec> ")"
|
|
-- "{" <switch_body> "}"
|
|
--
|
|
-- (73) <switch_type_spec> ::= <integer_type>
|
|
-- | <char_type>
|
|
-- | <boolean_type>
|
|
-- | <enum_type>
|
|
-- | <scoped_name>
|
|
--
|
|
-- (74) <switch_body> ::= <case> +
|
|
-- (75) <case> ::= <case_label> + <element_spec> ";"
|
|
-- (76) <case_label> ::= "case" <const_exp> ":"
|
|
-- | "default" ":"
|
|
--
|
|
-- (77) <element_spec> ::= <type_spec> <declarator>
|
|
|
|
function P_Union_Type return Node_Id is
|
|
function Is_Switch_Type_Spec (K : Node_Kind) return Boolean;
|
|
|
|
--------------------
|
|
-- Is_Switch_Spec --
|
|
--------------------
|
|
|
|
-- (73) <switch_type_spec> ::= <integer_type>
|
|
-- | <char_type>
|
|
-- | <boolean_type>
|
|
-- | <enum_type>
|
|
-- | <scoped_name>
|
|
|
|
function Is_Switch_Type_Spec (K : Node_Kind) return Boolean is
|
|
begin
|
|
case K is
|
|
when K_Short
|
|
| K_Long
|
|
| K_Long_Long
|
|
| K_Unsigned_Short
|
|
| K_Unsigned_Long
|
|
| K_Unsigned_Long_Long
|
|
| K_Char
|
|
| K_Boolean
|
|
| K_Enumeration_Type
|
|
| K_Scoped_Name =>
|
|
return True;
|
|
|
|
when others =>
|
|
return False;
|
|
end case;
|
|
end Is_Switch_Type_Spec;
|
|
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Switch_Type_Spec : Node_Id;
|
|
Switch_Type_Body : List_Id;
|
|
Switch_Alt_Decl : Node_Id;
|
|
Element_Type_Spec : Node_Id;
|
|
Element_Declarator : Node_Id;
|
|
Element : Node_Id;
|
|
Case_Labels : List_Id;
|
|
Case_Label : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "union"
|
|
Node := New_Node (K_Union_Type, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Scan_Token (T_Switch);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Scan_Token (T_Left_Paren);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Save_Lexer (State);
|
|
Switch_Type_Spec := P_Type_Spec;
|
|
if Present (Switch_Type_Spec)
|
|
and then not Is_Switch_Type_Spec (Kind (Switch_Type_Spec))
|
|
then
|
|
Error_Loc (1) := Loc (Switch_Type_Spec);
|
|
DE ("unexpected switch type spec");
|
|
Switch_Type_Spec := No_Node;
|
|
end if;
|
|
|
|
if No (Switch_Type_Spec) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
|
|
else
|
|
Save_Lexer (State);
|
|
Scan_Token (T_Right_Paren);
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Paren);
|
|
end if;
|
|
end if;
|
|
Set_Switch_Type_Spec (Node, Switch_Type_Spec);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Switch_Type_Body := New_List (K_Switch_Type_Body, Token_Location);
|
|
Set_Switch_Type_Body (Node, Switch_Type_Body);
|
|
|
|
Switch_Alternative_Declaration :
|
|
loop
|
|
Save_Lexer (State);
|
|
Scan_Token ((T_Default, T_Case));
|
|
Switch_Alt_Decl := New_Node (K_Switch_Alternative, Token_Location);
|
|
Case_Labels := New_List (K_Case_Label_List, Token_Location);
|
|
Set_Labels (Switch_Alt_Decl, Case_Labels);
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
|
|
Case_Label_List :
|
|
loop
|
|
if Token = T_Case then
|
|
Save_Lexer (State);
|
|
Case_Label := P_Constant_Expression;
|
|
if No (Case_Label) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
Append_Node_To_List (Case_Label, Case_Labels);
|
|
end if;
|
|
|
|
case Next_Token is
|
|
when T_Case
|
|
| T_Default =>
|
|
Scan_Token;
|
|
exit Case_Label_List when Token = T_Default;
|
|
|
|
when others =>
|
|
exit Case_Label_List;
|
|
end case;
|
|
end loop Case_Label_List;
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token (T_Colon);
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
|
|
Save_Lexer (State);
|
|
Element_Type_Spec := P_Type_Spec;
|
|
if No (Element_Type_Spec) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
|
|
Save_Lexer (State);
|
|
Element_Declarator := P_Declarator;
|
|
if No (Element_Declarator) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
Element := New_Node (K_Element, Loc (Element_Type_Spec));
|
|
Set_Type_Spec (Element, Element_Type_Spec);
|
|
Set_Declarator (Element, Element_Declarator);
|
|
|
|
Set_Element (Switch_Alt_Decl, Element);
|
|
|
|
Append_Node_To_List (Switch_Alt_Decl, Switch_Type_Body);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token (T_Semi_Colon);
|
|
if Token = T_Error then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit Switch_Alternative_Declaration;
|
|
end if;
|
|
|
|
exit Switch_Alternative_Declaration when Next_Token = T_Right_Brace;
|
|
end loop Switch_Alternative_Declaration;
|
|
|
|
Scan_Token; -- past '}'
|
|
|
|
return Node;
|
|
end P_Union_Type;
|
|
|
|
-------------
|
|
-- P_Value --
|
|
-------------
|
|
|
|
-- (13) <value> ::= <value_dcl>
|
|
-- | <value_abs_dcl>
|
|
-- | <value_box_dcl>
|
|
-- | <value_forward_dcl>)
|
|
|
|
function P_Value return Node_Id is
|
|
State : Location;
|
|
Value_Abs : Boolean := False;
|
|
|
|
begin
|
|
Save_Lexer (State);
|
|
|
|
Scan_Token; -- past "abstract" or "custom" or "valuetype"
|
|
if Token = T_Abstract then
|
|
Value_Abs := True;
|
|
Scan_Token; -- past "valuetype"
|
|
elsif Token = T_Custom then
|
|
Scan_Token; -- past "valuetype"
|
|
end if;
|
|
|
|
if No (P_Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Scan_Token;
|
|
case Token is
|
|
when T_Semi_Colon =>
|
|
Restore_Lexer (State);
|
|
return P_Value_Forward_Declaration;
|
|
|
|
when T_Custom =>
|
|
Restore_Lexer (State);
|
|
return P_Value_Declaration;
|
|
|
|
when T_Colon | T_Left_Brace | T_Supports =>
|
|
Restore_Lexer (State);
|
|
if Value_Abs then
|
|
return P_Value_Abstract_Declaration;
|
|
else
|
|
return P_Value_Declaration;
|
|
end if;
|
|
|
|
when others =>
|
|
Restore_Lexer (State);
|
|
return P_Value_Box_Declaration;
|
|
end case;
|
|
end P_Value;
|
|
|
|
----------------------------------
|
|
-- P_Value_Abstract_Declaration --
|
|
----------------------------------
|
|
|
|
-- (16) <value_abs_dcl> ::= "abstract" "valuetype" <identifier>
|
|
-- [ <value_inheritance_spec> ] "{" <export>* "}"
|
|
|
|
function P_Value_Abstract_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Value_Spec : Node_Id;
|
|
Value_Body : List_Id;
|
|
Export : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "abstract"
|
|
Node := New_Node (K_Abstract_Value_Declaration, Token_Location);
|
|
|
|
Scan_Token; -- past "valuetype"
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Value_Spec := P_Value_Spec;
|
|
Set_Value_Spec (Node, Value_Spec);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Value_Body := New_List (K_Value_Body, Token_Location);
|
|
Set_Value_Body (Node, Value_Body);
|
|
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token;
|
|
|
|
else
|
|
loop
|
|
Save_Lexer (State);
|
|
Export := P_Export;
|
|
if No (Export) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Export, Value_Body);
|
|
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token;
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
end if;
|
|
|
|
return Node;
|
|
end P_Value_Abstract_Declaration;
|
|
|
|
-----------------------------
|
|
-- P_Value_Box_Declaration --
|
|
-----------------------------
|
|
|
|
-- (15) <value_box_dcl> ::= "valuetype" <identifier> <type_spec>
|
|
|
|
function P_Value_Box_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Type_Spec : Node_Id;
|
|
|
|
begin
|
|
Scan_Token; -- past "valuetype"
|
|
Node := New_Node (K_Value_Box_Declaration, Token_Location);
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Type_Spec := P_Type_Spec;
|
|
if No (Type_Spec) then
|
|
return No_Node;
|
|
end if;
|
|
Set_Type_Spec (Node, Type_Spec);
|
|
|
|
return Node;
|
|
end P_Value_Box_Declaration;
|
|
|
|
-------------------------
|
|
-- P_Value_Declaration --
|
|
-------------------------
|
|
|
|
-- (17) <value_dcl> ::= <value_header> "{" <value_element>* "}"
|
|
-- (18) <value_header> ::= [" custom" ] "valuetype" <identifier>
|
|
-- [ <value_inheritance_spec> ]
|
|
--
|
|
-- (20) <value_name> ::= <scoped_name>
|
|
-- (21) <value_element> ::= <export> | <state_member> | <init_dcl>
|
|
|
|
function P_Value_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
Value_Spec : Node_Id;
|
|
Value_Body : List_Id;
|
|
Value_Element : Node_Id;
|
|
State : Location;
|
|
|
|
begin
|
|
Scan_Token; -- past "custom" or "valuetype"
|
|
Node := New_Node (K_Value_Declaration, Token_Location);
|
|
|
|
if Token = T_Custom then
|
|
Set_Is_Custom (Node, True);
|
|
|
|
Scan_Token (T_Value_Type);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
end if;
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
Value_Spec := P_Value_Spec;
|
|
Set_Value_Spec (Node, Value_Spec);
|
|
|
|
Scan_Token (T_Left_Brace);
|
|
if Token = T_Error then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Value_Body := New_List (K_Value_Body, Token_Location);
|
|
Set_Value_Body (Node, Value_Body);
|
|
|
|
loop
|
|
Save_Lexer (State);
|
|
case Next_Token is
|
|
when T_Factory =>
|
|
Value_Element := P_Initializer_Declaration;
|
|
|
|
when T_Public | T_Private =>
|
|
Value_Element := P_State_Member;
|
|
|
|
when others =>
|
|
Value_Element := P_Export;
|
|
end case;
|
|
|
|
if No (Value_Element) then
|
|
Restore_Lexer (State);
|
|
Skip_Declaration (T_Right_Brace);
|
|
exit;
|
|
end if;
|
|
|
|
Append_Node_To_List (Value_Element, Value_Body);
|
|
|
|
if Next_Token = T_Right_Brace then
|
|
Scan_Token; -- past '}'
|
|
exit;
|
|
end if;
|
|
end loop;
|
|
|
|
return Node;
|
|
end P_Value_Declaration;
|
|
|
|
---------------------------------
|
|
-- P_Value_Forward_Declaration --
|
|
---------------------------------
|
|
|
|
-- (14) <value_forward_dcl> ::= [ "abstract" ] "valuetype" <identifier>
|
|
|
|
function P_Value_Forward_Declaration return Node_Id is
|
|
Identifier : Node_Id;
|
|
Node : Node_Id;
|
|
|
|
begin
|
|
Scan_Token; -- past "valuetype" or "abstract"
|
|
Node := New_Node (K_Value_Forward_Declaration, Token_Location);
|
|
|
|
if Token = T_Abstract then
|
|
Set_Is_Abstract (Node, True);
|
|
Scan_Token (T_Value_Type);
|
|
end if;
|
|
|
|
Identifier := P_Identifier;
|
|
if No (Identifier) then
|
|
return No_Node;
|
|
end if;
|
|
Associate (Node, Identifier);
|
|
|
|
return Node;
|
|
end P_Value_Forward_Declaration;
|
|
|
|
------------------
|
|
-- P_Value_Spec --
|
|
------------------
|
|
|
|
-- (19) <value_inheritance_spec> ::=
|
|
-- [ ":" [ "truncatable" ] <value_name>
|
|
-- { "," <value_name> }* ]
|
|
-- [ "supports" <interface_name>
|
|
-- { "," <interface_name> }* ]
|
|
|
|
function P_Value_Spec return Node_Id is
|
|
Value_Spec : Node_Id := No_Node;
|
|
Value_Names : List_Id;
|
|
Interface_Names : List_Id;
|
|
Scoped_Name : Node_Id;
|
|
Interface_Name : Node_Id;
|
|
State : Location;
|
|
begin
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
|
|
Value_Spec := New_Node (K_Value_Spec, Token_Location);
|
|
|
|
if Token = T_Colon then
|
|
if Next_Token = T_Truncatable then
|
|
Scan_Token; -- past "truncatable"
|
|
Set_Is_Truncatable (Value_Spec, True);
|
|
end if;
|
|
|
|
Value_Names := New_List (K_Value_Name_List, Token_Location);
|
|
Set_Value_Names (Value_Spec, Value_Names);
|
|
|
|
loop
|
|
Scoped_Name := P_Scoped_Name;
|
|
if No (Scoped_Name) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Append_Node_To_List (Scoped_Name, Value_Names);
|
|
|
|
exit when Next_Token /= T_Comma;
|
|
Scan_Token; -- past ','
|
|
end loop;
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
end if;
|
|
|
|
if Token = T_Supports then
|
|
Interface_Names := New_List (K_Interface_Name_List, Token_Location);
|
|
Set_Interface_Names (Value_Spec, Interface_Names);
|
|
|
|
loop
|
|
Interface_Name := P_Interface_Name;
|
|
if No (Interface_Name) then
|
|
return No_Node;
|
|
end if;
|
|
|
|
Append_Node_To_List (Interface_Name, Interface_Names);
|
|
|
|
Save_Lexer (State);
|
|
Scan_Token;
|
|
exit when Token /= T_Comma;
|
|
end loop;
|
|
end if;
|
|
|
|
Restore_Lexer (State);
|
|
|
|
return Value_Spec;
|
|
end P_Value_Spec;
|
|
|
|
--------------------
|
|
-- Parameter_Mode --
|
|
--------------------
|
|
|
|
function Parameter_Mode (E : Node_Id) return Mode_Type is
|
|
M : Mode_Id;
|
|
begin
|
|
M := Parameter_Mode (E);
|
|
return Mode_Type'Val (M);
|
|
end Parameter_Mode;
|
|
|
|
-------------
|
|
-- Process --
|
|
-------------
|
|
|
|
procedure Process (Root : out Node_Id) is
|
|
begin
|
|
-- (53) <floating_pt_type> ::= "float"
|
|
-- | "double"
|
|
-- | "long" "double"
|
|
|
|
Declare_Base_Type ((1 => T_Float), K_Float);
|
|
Declare_Base_Type ((1 => T_Double), K_Double);
|
|
Declare_Base_Type ((T_Long, T_Double), K_Long_Double);
|
|
|
|
-- (54) <integer_type> ::= <signed_int>
|
|
-- | <unsigned_int>
|
|
--
|
|
-- (55) <signed_int> ::= <signed_short_int>
|
|
-- | <signed_long_int>
|
|
-- | <signed_longlong_int>
|
|
--
|
|
-- (56) <signed_short_int> ::= "short"
|
|
-- (57) <signed_long_int> ::= "long"
|
|
-- (58) <signed_longlong_int> ::= "long" "long"
|
|
-- (59) <unsigned_int> ::= <unsigned_short_int>
|
|
-- | <unsigned_long_int>
|
|
-- | <unsigned_longlong_int>
|
|
--
|
|
-- (60) <unsigned_short_int> ::= "unsigned" "short"
|
|
-- (61) <unsigned_long_int> ::= "unsigned" "long"
|
|
-- (62) <unsigned_longlong_int> ::= "unsigned" "long" "long"
|
|
|
|
Declare_Base_Type ((1 => T_Short), K_Short);
|
|
Declare_Base_Type ((1 => T_Long), K_Long);
|
|
Declare_Base_Type ((T_Long, T_Long), K_Long_Long);
|
|
Declare_Base_Type ((T_Unsigned, T_Short), K_Unsigned_Short);
|
|
Declare_Base_Type ((T_Unsigned, T_Long), K_Unsigned_Long);
|
|
Declare_Base_Type ((T_Unsigned, T_Long, T_Long), K_Unsigned_Long_Long);
|
|
|
|
-- (63) <char_type> ::= "char"
|
|
-- (64) <wide_char_type> ::= "wchar"
|
|
|
|
Declare_Base_Type ((1 => T_Char), K_Char);
|
|
Declare_Base_Type ((1 => T_Wchar), K_Wide_Char);
|
|
|
|
Declare_Base_Type ((1 => T_String), K_String);
|
|
Declare_Base_Type ((1 => T_Wstring), K_Wide_String);
|
|
|
|
-- (65) <boolean_type> ::= "boolean"
|
|
-- (66) <octet_type> ::= "octet"
|
|
-- (67) <any_type> ::= "any"
|
|
-- (68) <object_type> ::= "Object"
|
|
|
|
Declare_Base_Type ((1 => T_Boolean), K_Boolean);
|
|
Declare_Base_Type ((1 => T_Octet), K_Octet);
|
|
Declare_Base_Type ((1 => T_Any), K_Any);
|
|
Declare_Base_Type ((1 => T_Object), K_Object);
|
|
Declare_Base_Type ((1 => T_Value_Base), K_Value_Base);
|
|
|
|
-- 89) <op_type_spec> ::= <param_type_spec>
|
|
-- | "void"
|
|
|
|
Declare_Base_Type ((1 => T_Void), K_Void);
|
|
|
|
Root := P_Specification;
|
|
end Process;
|
|
|
|
-----------------------
|
|
-- Resolve_Base_Type --
|
|
-----------------------
|
|
|
|
function Resolve_Base_Type (L : Token_List_Type) return Node_Id is
|
|
begin
|
|
Set_Str_To_Name_Buffer (Image (L (L'First)));
|
|
for I in L'First + 1 .. L'Last loop
|
|
Add_Char_To_Name_Buffer (' ');
|
|
Add_Str_To_Name_Buffer (Image (L (I)));
|
|
end loop;
|
|
return Node_Id (Get_Name_Table_Info (Name_Find));
|
|
end Resolve_Base_Type;
|
|
|
|
------------------
|
|
-- Set_Operator --
|
|
------------------
|
|
|
|
procedure Set_Operator (E : Node_Id; O : Operator_Type) is
|
|
B : Byte;
|
|
begin
|
|
B := Operator_Type'Pos (O);
|
|
Set_Operator (E, Operator_Id (B));
|
|
end Set_Operator;
|
|
|
|
------------------------
|
|
-- Set_Parameter_Mode --
|
|
------------------------
|
|
|
|
procedure Set_Parameter_Mode (E : Node_Id; M : Mode_Type) is
|
|
B : Byte;
|
|
begin
|
|
B := Mode_Type'Pos (M);
|
|
Set_Parameter_Mode (E, Mode_Id (B));
|
|
end Set_Parameter_Mode;
|
|
|
|
end Parser;
|