-------------------------------------------- ------------------------------------ -- -- -- OCARINA COMPONENTS -- -- -- -- O C A R I N A . A A D L . P A R S E R -- -- -- -- B o d y -- -- -- -- Copyright (C) 2004-2006, 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 Namet; with Ocarina.Nodes; with Ocarina.Nutils; with Ocarina.Parser; with Ocarina.AADL.Lexer; with Ocarina.AADL.Parser.Namespaces; package body Ocarina.AADL.Parser is ---------- -- Init -- ---------- procedure Init is begin Ocarina.Parser.Register_Parser (".aadl", Process'Access); end Init; ------------------ -- P_Items_List -- ------------------ -- ( { Item }+ | none_statement ) function P_Items_List (Func : P_Item_Function_Ptr; Container : Node_Id; Code : Parsing_Code) return Integer is use Locations; use Tokens; use Lexer; use Ocarina.Nodes; use Ocarina.Nutils; Loc : Location; Nb_Items : Integer := 0; Item : Node_Id; begin Save_Lexer (Loc); Scan_Token; if Token = T_None then if not P_None_Statement then return -1; end if; else Restore_Lexer (Loc); loop Save_Lexer (Loc); Item := Func.all (Container); if Present (Item) then Nb_Items := Nb_Items + 1; else -- Error when parsing item, restore lexer Restore_Lexer (Loc); if Nb_Items = 0 then -- list must contain at least one element, {Item}+ Nb_Items := -1; DPE (Code, EMC_List_Is_Empty); end if; exit; end if; end loop; end if; return Nb_Items; end P_Items_List; function P_Items_List (Func : P_Item_Function_Ptr; Container : Node_Id; Code : Parsing_Code) return List_Id is use Locations; use Tokens; use Lexer; use Ocarina.Nodes; use Ocarina.Nutils; Loc : Location; Items : List_Id; Item : Node_Id; begin Save_Lexer (Loc); Scan_Token; Items := New_List (K_List_Id, Token_Location); if Token = T_None then if not P_None_Statement then return No_List; end if; else Restore_Lexer (Loc); loop Save_Lexer (Loc); Item := Func.all (Container); if Present (Item) then Append_Node_To_List (Item, Items); else -- Error when parsing item, restore lexer Restore_Lexer (Loc); if Is_Empty (Items) then -- list must contain at least one element, { Item }+ DPE (Code, EMC_List_Is_Empty); end if; exit; end if; end loop; end if; return Items; end P_Items_List; ------------------ -- P_Items_List -- ------------------ function P_Items_List (Func : P_Refinable_Item_Function_Ptr; Container : Node_Id; Refinable : Boolean; Code : Parsing_Code; At_Least_One : Boolean := True) return Integer is use Locations; use Tokens; use Lexer; use Ocarina.Nodes; use Ocarina.Nutils; Loc : Location; Item : Node_Id; Items : Integer := 0; begin Save_Lexer (Loc); Scan_Token; if Token = T_None then if not P_None_Statement then return -1; end if; else Restore_Lexer (Loc); loop Save_Lexer (Loc); Item := Func.all (Container, Refinable); if Present (Item) then Items := Items + 1; else -- Error when parsing item, restore lexer Restore_Lexer (Loc); if At_Least_One and then Items = 0 then -- list must contain at least one element, {Item}+ DPE (Code, EMC_List_Is_Empty); Items := -1; end if; exit; end if; end loop; end if; return Items; end P_Items_List; ------------------ -- P_Items_List -- ------------------ -- ( { Item Separator }* Item ) or ( { Item }* Item Delimiter ) function P_Items_List (Func : P_Item_Function_Ptr; Container : Node_Id; Delimiter : Ocarina.AADL.Tokens.Token_Type; Is_Delimited : Boolean) return List_Id is use Locations; use Tokens; use Lexer; use Ocarina.Nodes; use Ocarina.Nutils; Item : Node_Id; Items : List_Id; Loc : Location; begin Items := New_List (K_List_Id, Token_Location); loop Item := Func.all (Container); if Present (Item) then Append_Node_To_List (Item, Items); else if Is_Delimited then -- Error when parsing item, ignores tokens ---> Delimiter; quit Skip_Tokens (Delimiter); end if; return No_List; end if; Save_Lexer (Loc); Scan_Token; if Is_Delimited then exit when Token = Delimiter; Restore_Lexer (Loc); elsif Token /= Delimiter then Restore_Lexer (Loc); exit; end if; end loop; Set_Loc (Node_Id (Items), Ocarina.Nodes.Loc (First_Node (Items))); return Items; end P_Items_List; ------------------ -- P_Items_List -- ------------------ -- ( [ { Item Separator }* Item Delimiter ) ] ) function P_Items_List (Func : P_Item_Function_Ptr; Container : Node_Id; Separator : Ocarina.AADL.Tokens.Token_Type; Delimiter : Ocarina.AADL.Tokens.Token_Type; Code : Parsing_Code) return List_Id is use Lexer; use Tokens; Items : List_Id; begin Items := P_Items_List (Func => Func, Container => Container, Delimiter => Separator, Is_Delimited => False); if No (Items) then -- Error when parsing items list, ignores tokens ---> -- Delimiter; quit Skip_Tokens (Delimiter); return No_List; end if; Scan_Token; if Token = Delimiter then return Items; else DPE (Code, (Separator, Delimiter)); Skip_Tokens (Delimiter); return No_List; end if; end P_Items_List; ---------------------- -- P_None_Statement -- ---------------------- -- none_statement ::= none ; function P_None_Statement return Boolean is use Locations; use Tokens; use Lexer; Loc : Location; begin Save_Lexer (Loc); Scan_Token; if Token = T_Semicolon then return True; else DPE (PC_None_Statement, T_Semicolon); Restore_Lexer (Loc); return False; end if; end P_None_Statement; ------------- -- Process -- ------------- function Process (File_Name : String; AADL_Root : Node_Id) return Node_Id is use Namet; use Ocarina.AADL.Parser.Namespaces; File_Id : Name_Id; begin Set_Str_To_Name_Buffer (File_Name); if Name_Len = 0 then return No_Node; end if; File_Id := Name_Find; if File_Id = No_Name then return No_Node; end if; if not Ocarina.AADL.Lexer.Process (File_Id) then return No_Node; else return P_AADL_Specification (AADL_Root); end if; end Process; end Ocarina.AADL.Parser;