-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset 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 3, or (at your option) any later
-- version. The SPARK toolset 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 the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (SP_Parser_Actions)
procedure Scan_Action_Table
  (State_No      : in     SP_Productions.Valid_States;
   Index         : in out Action_Index;
   Parse_Act     :    out SP_Parse_Act;
   Action_Symbol :    out SP_Symbols.SP_Terminal)
is
   Index_Pair             : Packed_PAT_Index_Pair;
   Table_Index, Max_Index : PAT_Index;
   Packed_Result          : Packed_Sym_Action_Pair;
begin
   Index_Pair  := State_Table (State_No);
   Table_Index := PAT_Index (Index_Pair mod PAT_Index_Size);
   Max_Index   := PAT_Index (Index_Pair / PAT_Index_Size);
   if Action_Index (Max_Index - Table_Index) < Index then
      Action_Symbol := SP_Symbols.SPEND;
      Parse_Act     := Error_Action;
   else
      Table_Index   := PAT_Index (Natural (Table_Index) + Natural (Index));
      Index         := Index + 1;
      Action_Symbol := SP_Symbols.SP_Terminal'Val ((Parse_Action_Table (Table_Index) / Term_Sym) mod Term_Sym_Lim);
      Packed_Result := Parse_Action_Table (Table_Index);

      case SP_Action_Kind'Val ((Packed_Result / Act) mod Act_Lim) is
         when Shift =>
            Parse_Act :=
              SP_Parse_Act'
              (Act     => Shift,
               State   => SP_Productions.SP_State ((Packed_Result / State) mod State_Lim),
               Symbol  => No_Sym,
               Red_By  => No_Red,
               Prod_No => No_Prod);
         when Reduce =>
            Parse_Act :=
              SP_Parse_Act'
              (Reduce,
               SP_Productions.No_State,
               SP_Symbols.SP_Symbol'Val ((Packed_Result / Symbol) mod Symbol_Lim + First_Non_Terminal),
               SP_Productions.SP_Right ((Packed_Result / Red_By) mod Red_By_Lim),
               0);
         when Accpt =>
            Parse_Act := Accept_Action;
         when Error => -- can never have this option
            Parse_Act := Error_Action;
      end case;
   end if;
end Scan_Action_Table;
