-------------------------------------------- ------------------------------------ -- -- -- 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;