---------------------------------------------- ------- ----------------------------- -- -- -- OCARINA COMPONENTS -- -- -- -- OCARINA.AADL.PARSER.COMPONENTS.CONNECTIONS -- -- -- -- B o d y -- -- -- -- Copyright (C) 2004-2007, GET-Telecom Paris. -- -- -- -- Ocarina is free software; you can redistribute it and/or modify -- -- it under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 2, or (at your option) any -- -- later version. Ocarina 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 distributed with Ocarina; see file COPYING. -- -- If not, write to the Free Software Foundation, 51 Franklin Street, Fifth -- -- Floor, Boston, MA 02111-1301, 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. -- -- -- -- Ocarina is maintained by the Ocarina team -- -- (ocarina-users@listes.enst.fr) -- -- -- ------------------------------------------------------------------------------ with Locations; with Ocarina.Nodes; with Ocarina.AADL.Lexer; with Ocarina.AADL.Tokens; with Ocarina.AADL.Parser.Identifiers; with Ocarina.AADL.Parser.Components.Modes; with Ocarina.AADL.Parser.Properties; with Ocarina.Builder.Components.Connections; with Ocarina.Entities.Components.Connections; package body Ocarina.AADL.Parser.Components.Connections is ------------------ -- P_Connection -- ------------------ -- connection ::= -- port_connection | parameter_connection | access_connection -- connection_refinement ::= port_connection_refinement -- | parameter_connection_refinement -- | access_connection_refinement -- port_connection ::= data_connection | event_connection -- | event_data_connection | port_group_connection -- data_connection ::= [ defining_data_connection_identifier :] -- data port source_unique_port_identifier -- ( immediate_connection_symbol | delayed_connection_symbol ) -- destination_unique_port_identifier -- [ { { property_association }+ } ] [ in_modes_and_transitions ] ; -- immediate_connection_symbol ::= ->> -- delayed_connection_symbol ::= -> -- event_connection ::= [ defining_event_connection_identifier :] -- event port source_unique_port_identifier -- -> destination_unique_port_identifier -- [ { { property_association }+ } ] [ in_modes_and_transitions ] ; -- event_data_connection ::= [ defining_event_data_connection_identifier :] -- event data port source_unique_port_identifier -- -> destination_unique_port_identifier -- [ { { property_association }+ } ] [ in_modes_and_transitions ] ; -- port_group_connection ::= [ defining_port_group_connection_identifier :] -- port group source_unique_port_group_identifier -- -> destination_unique_port_group_identifier -- [ { { property_association }+ } ] [ in_modes_and_transitions ] ; -- port_connection_refinement ::= -- connection_identifier : refined to -- ( data port | event port | event data port | port group ) -- ( ( { { property_association }+ } [ in_modes_and_transitions ] ) -- | in_modes_and_transitions ) ; -- parameter_connection ::= [ defining_parameter_connection_identifier :] -- parameter source_unique_parameter_identifier -- -> destination_unique_parameter_identifier -- [ { { property_association }+ } ] [ in_modes ] ; -- parameter_connection_refinement ::= -- connection_identifier : refined to parameter -- { { property_association }+ } [ in_modes ] ; -- access_connection ::= [ access_connection_identifier :] -- ( bus | data ) access unique_access provider_identifier -- -> unique_access_requirer_identifier -- [ { { property_association }+ } ] [ in_modes ] ; -- access_connection_refinement ::= -- connection_identifier : refined to ( bus | data ) access -- { { property_association }+ } [ in_modes ] ; function P_Connection (Container : Types.node_id; Refinable : Boolean) return Types.node_id is use Locations; use Ocarina.Nodes; use Lexer; use Tokens; use Ocarina.AADL.Parser.Identifiers; use Ocarina.AADL.Parser.Components.Modes; use Ocarina.AADL.Parser.Properties; use Ocarina.Builder.Components.Connections; use Ocarina.Entities.Components.Connections; Connection : node_id; Identifier : node_id; Is_Refinement : Boolean; Category : connection_type; Source : node_id := No_Node; Destination : node_id := No_Node; In_Modes : node_id; OK : Boolean; Code : parsing_code; Loc : location; Start_Loc : location := No_Location; Properties_Loc : location; begin P_Identifier_Refined_To (Refinable_To_RT (Refinable), True, pc_connection, pc_connection_refinement, t_semicolon, Identifier, Is_Refinement, OK); if not OK then return No_Node; end if; if Present (Identifier) then Start_Loc := Ocarina.Nodes.Loc (Identifier); -- update Start_Loc end if; if Is_Refinement then Code := pc_connection_refinement; else Code := pc_connection; end if; -- parsing connection category Save_Lexer (Loc); Scan_Token; if Start_Loc = No_Location then Start_Loc := Token_Location; end if; case Token is when t_data => -- data_connection or access_connection Scan_Token; case Token is when t_port => -- data_connection Category := ct_data; if Is_Refinement then Code := pc_data_connection_refinement; else Code := pc_data_connection; end if; when t_access => -- access_connection Category := ct_access_data; if Is_Refinement then Code := pc_access_connection_refinement; else Code := pc_access_connection; end if; when others => DPE (Code, (t_port, t_access)); Skip_Tokens (t_semicolon); return No_Node; end case; when t_event => -- event_connection or event_data_connection Scan_Token; case Token is when t_data => -- event_data_connection if Is_Refinement then Code := pc_event_data_connection_refinement; else Code := pc_event_data_connection; end if; Scan_Token; if Token /= t_port then DPE (Code, t_port); Skip_Tokens (t_semicolon); return No_Node; end if; Category := ct_event_data; when t_port => -- event_connection Category := ct_event; if Is_Refinement then Code := pc_event_connection_refinement; else Code := pc_event_connection; end if; when others => DPE (Code, (t_data, t_port)); Skip_Tokens (t_semicolon); return No_Node; end case; when t_port => -- port_group_connection if Is_Refinement then Code := pc_port_group_connection_refinement; else Code := pc_port_group_connection; end if; Scan_Token; if Token /= t_group then DPE (Code, t_group); Skip_Tokens (t_semicolon); return No_Node; end if; Category := ct_port_group; when t_parameter => -- parameter_connection Category := ct_parameter; if Is_Refinement then Code := pc_parameter_connection_refinement; else Code := pc_parameter_connection; end if; when t_bus => -- access_connection if Is_Refinement then Code := pc_access_connection_refinement; else Code := pc_access_connection; end if; Scan_Token; if Token /= t_access then DPE (Code, t_access); Skip_Tokens (t_semicolon); return No_Node; end if; Category := ct_access_bus; when t_subprogram => -- subprogram access (not in AADL 1.0) if Is_Refinement then Code := pc_access_connection_refinement; else Code := pc_access_connection; end if; Scan_Token; if Token /= t_access then DPE (Code, t_access); Skip_Tokens (t_semicolon); return No_Node; end if; Category := ct_access_subprogram; when others => if Present (Identifier) then DPE (Code, (t_data, t_event, t_bus, t_port, t_parameter)); Skip_Tokens (t_semicolon); return No_Node; else -- nothing was parsed, try to parse other stuff Restore_Lexer (Loc); return No_Node; end if; end case; -- parse connection source et destination if not Is_Refinement then Source := P_Entity_Reference (Code); if No (Source) then Skip_Tokens (t_semicolon); return No_Node; end if; Scan_Token; if Token /= t_connection then if Token = t_delayed_connection and then Category = ct_data then Category := ct_data_delayed; else if Category = ct_data then DPE (Code, (t_connection, t_delayed_connection)); else DPE (Code, t_connection); end if; Skip_Tokens (t_semicolon); return No_Node; end if; end if; Destination := P_Entity_Reference (Code); if No (Destination) then Skip_Tokens (t_semicolon); return No_Node; end if; end if; -- parse properties and in_modes Save_Lexer (Properties_Loc); -- We save the location of the properties, as we have to parse -- it later (after the connection node has been created) Connection := Add_New_Connection (Loc => Start_Loc, Name => Identifier, Comp_Impl => Container, Category => Category, Destination => Destination, Source => Source, Is_Refinement => Is_Refinement, In_Modes => No_Node); OK := P_Property_Associations (Connection, True, pat_simple, Code); if not OK then Skip_Tokens (t_semicolon); return No_Node; end if; Save_Lexer (Loc); Scan_Token; if No (Ocarina.Nodes.Properties (Connection)) then -- Property_Associations are not defined, -- In_Modes_And_Transitions must exist if Is_Refinement = TRUE if Is_Refinement and then Token /= t_in then DPE (Code, (t_in, t_left_curly_bracket)); Skip_Tokens (t_semicolon); return No_Node; end if; end if; if Token = t_in then case Category is when ct_data | ct_data_delayed | ct_event_data | ct_event | ct_port_group => In_Modes := P_In_Modes (pc_in_modes_and_transitions); when ct_parameter | ct_access_bus | ct_access_data | ct_access_subprogram => In_Modes := P_In_Modes (pc_in_modes); end case; if No (In_Modes) then -- error when parsing In_Modes, quit Skip_Tokens (t_semicolon); return No_Node; else Set_In_Modes (Connection, In_Modes); end if; else In_Modes := No_Node; Restore_Lexer (Loc); end if; Save_Lexer (Loc); Scan_Token; if Token /= t_semicolon then DPE (Code, t_semicolon); Restore_Lexer (Loc); return No_Node; end if; Save_Lexer (Loc); Restore_Lexer (Properties_Loc); Restore_Lexer (Loc); return Connection; end P_Connection; end Ocarina.AADL.Parser.Components.Connections;