------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             P R J . S T R T                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2001-2004 Free Software Foundation, Inc.          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT 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 GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Err_Vars;  use Err_Vars;
with Namet;     use Namet;
with Prj.Attr;  use Prj.Attr;
with Prj.Err;   use Prj.Err;
with Prj.Tree;  use Prj.Tree;
with Scans;     use Scans;
with Snames;
with Table;
with Types;     use Types;
with Uintp;     use Uintp;

package body Prj.Strt is

   type Choice_String is record
      The_String   : Name_Id;
      Already_Used : Boolean := False;
   end record;
   --  The string of a case label, and an indication that it has already
   --  been used (to avoid duplicate case labels).

   Choices_Initial   : constant := 10;
   Choices_Increment : constant := 50;

   Choice_Node_Low_Bound  : constant := 0;
   Choice_Node_High_Bound : constant := 099_999_999;
   --  In practice, infinite

   type Choice_Node_Id is
     range Choice_Node_Low_Bound .. Choice_Node_High_Bound;

   First_Choice_Node_Id : constant Choice_Node_Id :=
     Choice_Node_Low_Bound;

   package Choices is
      new Table.Table (Table_Component_Type => Choice_String,
                       Table_Index_Type     => Choice_Node_Id,
                       Table_Low_Bound      => First_Choice_Node_Id,
                       Table_Initial        => Choices_Initial,
                       Table_Increment      => Choices_Increment,
                       Table_Name           => "Prj.Strt.Choices");
   --  Used to store the case labels and check that there is no duplicate.

   package Choice_Lasts is
      new Table.Table (Table_Component_Type => Choice_Node_Id,
                       Table_Index_Type     => Nat,
                       Table_Low_Bound      => 1,
                       Table_Initial        => 10,
                       Table_Increment      => 100,
                       Table_Name           => "Prj.Strt.Choice_Lasts");
   --  Used to store the indices of the choices in table Choices,
   --  to distinguish nested case constructions.

   Choice_First : Choice_Node_Id := 0;
   --  Index in table Choices of the first case label of the current
   --  case construction. Zero means no current case construction.

   type Name_Location is record
      Name     : Name_Id := No_Name;
      Location : Source_Ptr := No_Location;
   end record;
   --  Store the identifier and the location of a simple name

   package Names is
      new Table.Table (Table_Component_Type => Name_Location,
                       Table_Index_Type     => Nat,
                       Table_Low_Bound      => 1,
                       Table_Initial        => 10,
                       Table_Increment      => 100,
                       Table_Name           => "Prj.Strt.Names");
   --  Used to accumulate the single names of a name

   procedure Add (This_String : Name_Id);
   --  Add a string to the case label list, indicating that it has not
   --  yet been used.

   procedure Add_To_Names (NL : Name_Location);
   --  Add one single names to table Names

   procedure External_Reference (External_Value : out Project_Node_Id);
   --  Parse an external reference. Current token is "external".

   procedure Attribute_Reference
     (Reference       : out Project_Node_Id;
      First_Attribute : Attribute_Node_Id;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id);
   --  Parse an attribute reference. Current token is an apostrophe.

   procedure Terms
     (Term            : out Project_Node_Id;
      Expr_Kind       : in out Variable_Kind;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id;
      Optional_Index  : Boolean);
   --  Recursive procedure to parse one term or several terms concatenated
   --  using "&".

   ---------
   -- Add --
   ---------

   procedure Add (This_String : Name_Id) is
   begin
      Choices.Increment_Last;
      Choices.Table (Choices.Last) :=
        (The_String   => This_String,
         Already_Used => False);
   end Add;

   ------------------
   -- Add_To_Names --
   ------------------

   procedure Add_To_Names (NL : Name_Location) is
   begin
      Names.Increment_Last;
      Names.Table (Names.Last) := NL;
   end Add_To_Names;

   -------------------------
   -- Attribute_Reference --
   -------------------------

   procedure Attribute_Reference
     (Reference       : out Project_Node_Id;
      First_Attribute : Attribute_Node_Id;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id)
   is
      Current_Attribute : Attribute_Node_Id := First_Attribute;

   begin
      --  Declare the node of the attribute reference

      Reference :=  Default_Project_Node (Of_Kind => N_Attribute_Reference);
      Set_Location_Of (Reference, To => Token_Ptr);
      Scan; --  past apostrophe

      --  Body may be an attribute name

      if Token = Tok_Body then
         Token      := Tok_Identifier;
         Token_Name := Snames.Name_Body;
      end if;

      Expect (Tok_Identifier, "identifier");

      if Token = Tok_Identifier then
         Set_Name_Of (Reference, To => Token_Name);

         --  Check if the identifier is one of the attribute identifiers in the
         --  context (package or project level attributes).

         Current_Attribute :=
           Attribute_Node_Id_Of (Token_Name, Starting_At => First_Attribute);

         --  If the identifier is not allowed, report an error

         if Current_Attribute = Empty_Attribute then
            Error_Msg_Name_1 := Token_Name;
            Error_Msg ("unknown attribute %", Token_Ptr);
            Reference := Empty_Node;

            --  Scan past the attribute name

            Scan;

         else
            --  Give its characteristics to this attribute reference

            Set_Project_Node_Of (Reference, To => Current_Project);
            Set_Package_Node_Of (Reference, To => Current_Package);
            Set_Expression_Kind_Of
              (Reference, To => Variable_Kind_Of (Current_Attribute));
            Set_Case_Insensitive
              (Reference, To => Attribute_Kind_Of (Current_Attribute) =
                                          Case_Insensitive_Associative_Array);

            --  Scan past the attribute name

            Scan;

            --  If the attribute is an associative array, get the index

            if Attribute_Kind_Of (Current_Attribute) /= Single then
               Expect (Tok_Left_Paren, "`(`");

               if Token = Tok_Left_Paren then
                  Scan;
                  Expect (Tok_String_Literal, "literal string");

                  if Token = Tok_String_Literal then
                     Set_Associative_Array_Index_Of
                       (Reference, To => Token_Name);
                     Scan;
                     Expect (Tok_Right_Paren, "`)`");

                     if Token = Tok_Right_Paren then
                        Scan;
                     end if;
                  end if;
               end if;
            end if;
         end if;

         --  Change name of obsolete attributes

         if Reference /= Empty_Node then
            case Name_Of (Reference) is
               when Snames.Name_Specification =>
                  Set_Name_Of (Reference, To => Snames.Name_Spec);

               when Snames.Name_Specification_Suffix =>
                  Set_Name_Of (Reference, To => Snames.Name_Spec_Suffix);

               when Snames.Name_Implementation =>
                  Set_Name_Of (Reference, To => Snames.Name_Body);

               when Snames.Name_Implementation_Suffix =>
                  Set_Name_Of (Reference, To => Snames.Name_Body_Suffix);

               when others =>
                  null;
            end case;
         end if;
      end if;
   end Attribute_Reference;

   ---------------------------
   -- End_Case_Construction --
   ---------------------------

   procedure End_Case_Construction
     (Check_All_Labels   : Boolean;
      Case_Location      : Source_Ptr)
   is
      Non_Used : Natural := 0;
      First_Non_Used : Choice_Node_Id := First_Choice_Node_Id;
   begin
      --  First, if Check_All_Labels is True, check if all values
      --  of the string type have been used.

      if Check_All_Labels then
         for Choice in Choice_First .. Choices.Last loop
               if not Choices.Table (Choice).Already_Used then
                  Non_Used := Non_Used + 1;

                  if Non_Used = 1 then
                     First_Non_Used := Choice;
                  end if;
               end if;
         end loop;

         --  If only one is not used, report a single warning for this value

         if Non_Used = 1 then
            Error_Msg_Name_1 := Choices.Table (First_Non_Used).The_String;
            Error_Msg ("?value { is not used as label", Case_Location);

         --  If several are not used, report a warning for each one of them

         elsif Non_Used > 1 then
            Error_Msg
              ("?the following values are not used as labels:",
               Case_Location);

            for Choice in First_Non_Used .. Choices.Last loop
               if not Choices.Table (Choice).Already_Used then
                  Error_Msg_Name_1 := Choices.Table (Choice).The_String;
                  Error_Msg ("\?{", Case_Location);
               end if;
            end loop;
         end if;
      end if;

      --  If this is the only case construction, empty the tables

      if Choice_Lasts.Last = 1 then
         Choice_Lasts.Set_Last (0);
         Choices.Set_Last (First_Choice_Node_Id);
         Choice_First := 0;

      elsif Choice_Lasts.Last = 2 then
         --  This is the second case onstruction, set the tables to the first

         Choice_Lasts.Set_Last (1);
         Choices.Set_Last (Choice_Lasts.Table (1));
         Choice_First := 1;

      else
         --  This is the 3rd or more case construction, set the tables to the
         --  previous one.

         Choice_Lasts.Decrement_Last;
         Choices.Set_Last (Choice_Lasts.Table (Choice_Lasts.Last));
         Choice_First := Choice_Lasts.Table (Choice_Lasts.Last - 1) + 1;
      end if;
   end End_Case_Construction;

   ------------------------
   -- External_Reference --
   ------------------------

   procedure External_Reference (External_Value : out Project_Node_Id) is
      Field_Id : Project_Node_Id := Empty_Node;

   begin
      External_Value :=
        Default_Project_Node (Of_Kind       => N_External_Value,
                              And_Expr_Kind => Single);
      Set_Location_Of (External_Value, To => Token_Ptr);

      --  The current token is External

      --  Get the left parenthesis

      Scan;
      Expect (Tok_Left_Paren, "`(`");

      --  Scan past the left parenthesis

      if Token = Tok_Left_Paren then
         Scan;
      end if;

      --  Get the name of the external reference

      Expect (Tok_String_Literal, "literal string");

      if Token = Tok_String_Literal then
         Field_Id :=
           Default_Project_Node (Of_Kind       => N_Literal_String,
                                 And_Expr_Kind => Single);
         Set_String_Value_Of (Field_Id, To => Token_Name);
         Set_External_Reference_Of (External_Value, To => Field_Id);

         --  Scan past the first argument

         Scan;

         case Token is

            when Tok_Right_Paren =>

               --  Scan past the right parenthesis
               Scan;

            when Tok_Comma =>

               --  Scan past the comma

               Scan;

               Expect (Tok_String_Literal, "literal string");

               --  Get the default

               if Token = Tok_String_Literal then
                  Field_Id :=
                    Default_Project_Node (Of_Kind       => N_Literal_String,
                                          And_Expr_Kind => Single);
                  Set_String_Value_Of (Field_Id, To => Token_Name);
                  Set_External_Default_Of (External_Value, To => Field_Id);
                  Scan;
                  Expect (Tok_Right_Paren, "`)`");
               end if;

               --  Scan past the right parenthesis
               if Token = Tok_Right_Paren then
                  Scan;
               end if;

            when others =>
               Error_Msg ("`,` or `)` expected", Token_Ptr);
         end case;
      end if;
   end External_Reference;

   -----------------------
   -- Parse_Choice_List --
   -----------------------

   procedure Parse_Choice_List (First_Choice : out Project_Node_Id) is
      Current_Choice : Project_Node_Id := Empty_Node;
      Next_Choice    : Project_Node_Id := Empty_Node;
      Choice_String  : Name_Id         := No_Name;
      Found          : Boolean         := False;

   begin
      --  Declare the node of the first choice

      First_Choice :=
        Default_Project_Node (Of_Kind       => N_Literal_String,
                              And_Expr_Kind => Single);

      --  Initially Current_Choice is the same as First_Choice

      Current_Choice := First_Choice;

      loop
         Expect (Tok_String_Literal, "literal string");
         exit when Token /= Tok_String_Literal;
         Set_Location_Of (Current_Choice, To => Token_Ptr);
         Choice_String := Token_Name;

         --  Give the string value to the current choice

         Set_String_Value_Of (Current_Choice, To => Choice_String);

         --  Check if the label is part of the string type and if it has not
         --  been already used.

         Found := False;
         for Choice in Choice_First .. Choices.Last loop
            if Choices.Table (Choice).The_String = Choice_String then
               --  This label is part of the string type

               Found := True;

               if Choices.Table (Choice).Already_Used then
                  --  But it has already appeared in a choice list for this
                  --  case construction; report an error.

                  Error_Msg_Name_1 := Choice_String;
                  Error_Msg ("duplicate case label {", Token_Ptr);
               else
                  Choices.Table (Choice).Already_Used := True;
               end if;

               exit;
            end if;
         end loop;

         --  If the label is not part of the string list, report an error

         if not Found then
            Error_Msg_Name_1 := Choice_String;
            Error_Msg ("illegal case label {", Token_Ptr);
         end if;

         --  Scan past the label

         Scan;

         --  If there is no '|', we are done

         if Token = Tok_Vertical_Bar then
            --  Otherwise, declare the node of the next choice, link it to
            --  Current_Choice and set Current_Choice to this new node.

            Next_Choice :=
              Default_Project_Node (Of_Kind       => N_Literal_String,
                                    And_Expr_Kind => Single);
            Set_Next_Literal_String (Current_Choice, To => Next_Choice);
            Current_Choice := Next_Choice;
            Scan;
         else
            exit;
         end if;
      end loop;
   end Parse_Choice_List;

   ----------------------
   -- Parse_Expression --
   ----------------------

   procedure Parse_Expression
     (Expression      : out Project_Node_Id;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id;
      Optional_Index  : Boolean)
   is
      First_Term      : Project_Node_Id := Empty_Node;
      Expression_Kind : Variable_Kind := Undefined;

   begin
      --  Declare the node of the expression

      Expression := Default_Project_Node (Of_Kind => N_Expression);
      Set_Location_Of (Expression, To => Token_Ptr);

      --  Parse the term or terms of the expression

      Terms (Term            => First_Term,
             Expr_Kind       => Expression_Kind,
             Current_Project => Current_Project,
             Current_Package => Current_Package,
             Optional_Index  => Optional_Index);

      --  Set the first term and the expression kind

      Set_First_Term (Expression, To => First_Term);
      Set_Expression_Kind_Of (Expression, To => Expression_Kind);
   end Parse_Expression;

   ----------------------------
   -- Parse_String_Type_List --
   ----------------------------

   procedure Parse_String_Type_List (First_String : out Project_Node_Id) is
      Last_String  : Project_Node_Id := Empty_Node;
      Next_String  : Project_Node_Id := Empty_Node;
      String_Value : Name_Id         := No_Name;

   begin
      --  Declare the node of the first string

      First_String :=
        Default_Project_Node (Of_Kind       => N_Literal_String,
                              And_Expr_Kind => Single);

      --  Initially, Last_String is the same as First_String

      Last_String := First_String;

      loop
         Expect (Tok_String_Literal, "literal string");
         exit when Token /= Tok_String_Literal;
         String_Value := Token_Name;

         --  Give its string value to Last_String

         Set_String_Value_Of (Last_String, To => String_Value);
         Set_Location_Of (Last_String, To => Token_Ptr);

         --  Now, check if the string is already part of the string type

         declare
            Current : Project_Node_Id := First_String;

         begin
            while Current /= Last_String loop
               if String_Value_Of (Current) = String_Value then
                  --  This is a repetition, report an error

                  Error_Msg_Name_1 := String_Value;
                  Error_Msg ("duplicate value { in type", Token_Ptr);
                  exit;
               end if;

               Current := Next_Literal_String (Current);
            end loop;
         end;

         --  Scan past the literal string

         Scan;

         --  If there is no comma following the literal string, we are done

         if Token /= Tok_Comma then
            exit;

         else
            --  Declare the next string, link it to Last_String and set
            --  Last_String to its node.

            Next_String :=
              Default_Project_Node (Of_Kind       => N_Literal_String,
                                    And_Expr_Kind => Single);
            Set_Next_Literal_String (Last_String, To => Next_String);
            Last_String := Next_String;
            Scan;
         end if;
      end loop;
   end Parse_String_Type_List;

   ------------------------------
   -- Parse_Variable_Reference --
   ------------------------------

   procedure Parse_Variable_Reference
     (Variable        : out Project_Node_Id;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id)
   is
      Current_Variable : Project_Node_Id := Empty_Node;

      The_Package : Project_Node_Id := Current_Package;
      The_Project : Project_Node_Id := Current_Project;

      Specified_Project : Project_Node_Id   := Empty_Node;
      Specified_Package : Project_Node_Id   := Empty_Node;
      Look_For_Variable : Boolean           := True;
      First_Attribute   : Attribute_Node_Id := Empty_Attribute;
      Variable_Name     : Name_Id;

   begin
      Names.Init;

      loop
         Expect (Tok_Identifier, "identifier");

         if Token /= Tok_Identifier then
            Look_For_Variable := False;
            exit;
         end if;

         Add_To_Names (NL => (Name => Token_Name, Location => Token_Ptr));
         Scan;
         exit when Token /= Tok_Dot;
         Scan;
      end loop;

      if Look_For_Variable then

         if Token = Tok_Apostrophe then

            --  Attribute reference

            case Names.Last is
               when 0 =>

                  --  Cannot happen

                  null;

               when 1 =>
                  --  This may be a project name or a package name.
                  --  Project name have precedence.

                  --  First, look if it can be a package name

                  First_Attribute :=
                    First_Attribute_Of
                      (Package_Node_Id_Of (Names.Table (1).Name));

                  --  Now, look if it can be a project name

                  The_Project := Imported_Or_Extended_Project_Of
                    (Current_Project, Names.Table (1).Name);

                  if The_Project = Empty_Node then
                     --  If it is neither a project name nor a package name,
                     --  report an error

                     if First_Attribute = Empty_Attribute then
                        Error_Msg_Name_1 := Names.Table (1).Name;
                        Error_Msg ("unknown project %",
                                   Names.Table (1).Location);
                        First_Attribute := Attribute_First;

                     else
                        --  If it is a package name, check if the package
                        --  has already been declared in the current project.

                        The_Package := First_Package_Of (Current_Project);

                        while The_Package /= Empty_Node
                          and then Name_Of (The_Package) /=
                          Names.Table (1).Name
                        loop
                           The_Package :=
                             Next_Package_In_Project (The_Package);
                        end loop;

                        --  If it has not been already declared, report an
                        --  error.

                        if The_Package = Empty_Node then
                           Error_Msg_Name_1 := Names.Table (1).Name;
                           Error_Msg ("package % not yet defined",
                                      Names.Table (1).Location);
                        end if;
                     end if;

                  else
                     --  It is a project name

                     First_Attribute := Attribute_First;
                     The_Package     := Empty_Node;
                  end if;

               when others =>

                  --  We have either a project name made of several simple
                  --  names (long project), or a project name (short project)
                  --  followed by a package name. The long project name has
                  --  precedence.

                  declare
                     Short_Project : Name_Id;
                     Long_Project  : Name_Id;

                  begin
                     --  Clear the Buffer

                     Buffer_Last := 0;

                     --  Get the name of the short project

                     for Index in 1 .. Names.Last - 1 loop
                        Add_To_Buffer
                          (Get_Name_String (Names.Table (Index).Name));

                        if Index /= Names.Last - 1 then
                           Add_To_Buffer (".");
                        end if;
                     end loop;

                     Name_Len := Buffer_Last;
                     Name_Buffer (1 .. Buffer_Last) :=
                       Buffer (1 .. Buffer_Last);
                     Short_Project := Name_Find;

                     --  Now, add the last simple name to get the name of the
                     --  long project.

                     Add_To_Buffer (".");
                     Add_To_Buffer
                       (Get_Name_String (Names.Table (Names.Last).Name));
                     Name_Len := Buffer_Last;
                     Name_Buffer (1 .. Buffer_Last) :=
                       Buffer (1 .. Buffer_Last);
                     Long_Project := Name_Find;

                     --  Check if the long project is imported or extended

                     The_Project := Imported_Or_Extended_Project_Of
                                      (Current_Project, Long_Project);

                     --  If the long project exists, then this is the prefix
                     --  of the attribute.

                     if The_Project /= Empty_Node then
                        First_Attribute := Attribute_First;
                        The_Package     := Empty_Node;

                     else
                        --  Otherwise, check if the short project is imported
                        --  or extended.

                        The_Project := Imported_Or_Extended_Project_Of
                                         (Current_Project, Short_Project);

                        --  If the short project does not exist, we report an
                        --  error.

                        if The_Project = Empty_Node then
                           Error_Msg_Name_1 := Long_Project;
                           Error_Msg_Name_2 := Short_Project;
                           Error_Msg ("unknown projects % or %",
                                      Names.Table (1).Location);
                           The_Package := Empty_Node;
                           First_Attribute := Attribute_First;

                        else
                           --  Now, we check if the package has been declared
                           --  in this project.

                           The_Package := First_Package_Of (The_Project);
                           while The_Package /= Empty_Node
                             and then Name_Of (The_Package) /=
                             Names.Table (Names.Last).Name
                           loop
                              The_Package :=
                                Next_Package_In_Project (The_Package);
                           end loop;

                           --  If it has not, then we report an error

                           if The_Package = Empty_Node then
                              Error_Msg_Name_1 :=
                                Names.Table (Names.Last).Name;
                              Error_Msg_Name_2 := Short_Project;
                              Error_Msg ("package % not declared in project %",
                                         Names.Table (Names.Last).Location);
                              First_Attribute := Attribute_First;

                           else
                              --  Otherwise, we have the correct project and
                              --  package.

                              First_Attribute :=
                                First_Attribute_Of
                                  (Package_Id_Of (The_Package));
                           end if;
                        end if;
                     end if;
                  end;
            end case;

            Attribute_Reference
              (Variable,
               Current_Project => The_Project,
               Current_Package => The_Package,
               First_Attribute => First_Attribute);
            return;
         end if;
      end if;

      Variable :=
        Default_Project_Node (Of_Kind => N_Variable_Reference);

      if Look_For_Variable then
         case Names.Last is
            when 0 =>

               --  Cannot happen

               null;

            when 1 =>

               --  Simple variable name

               Set_Name_Of (Variable, To => Names.Table (1).Name);

            when 2 =>

               --  Variable name with a simple name prefix that can be
               --  a project name or a package name. Project names have
               --  priority over package names.

               Set_Name_Of (Variable, To => Names.Table (2).Name);

               --  Check if it can be a package name

               The_Package := First_Package_Of (Current_Project);

               while The_Package /= Empty_Node
                 and then Name_Of (The_Package) /= Names.Table (1).Name
               loop
                  The_Package := Next_Package_In_Project (The_Package);
               end loop;

               --  Now look for a possible project name

               The_Project := Imported_Or_Extended_Project_Of
                                (Current_Project, Names.Table (1).Name);

               if The_Project /= Empty_Node then
                  Specified_Project := The_Project;

               elsif The_Package = Empty_Node then
                  Error_Msg_Name_1 := Names.Table (1).Name;
                  Error_Msg ("unknown package or project %",
                             Names.Table (1).Location);
                  Look_For_Variable := False;

               else
                  Specified_Package := The_Package;
               end if;

            when others =>

               --  Variable name with a prefix that is either a project name
               --  made of several simple names, or a project name followed
               --  by a package name.

               Set_Name_Of (Variable, To => Names.Table (Names.Last).Name);

               declare
                  Short_Project : Name_Id;
                  Long_Project  : Name_Id;

               begin
                  --  First, we get the two possible project names

                  --  Clear the buffer

                  Buffer_Last := 0;

                  --  Add all the simple names, except the last two

                  for Index in 1 .. Names.Last - 2 loop
                     Add_To_Buffer
                       (Get_Name_String (Names.Table (Index).Name));

                     if Index /= Names.Last - 2 then
                        Add_To_Buffer (".");
                     end if;
                  end loop;

                  Name_Len := Buffer_Last;
                  Name_Buffer (1 .. Name_Len) := Buffer (1 .. Buffer_Last);
                  Short_Project := Name_Find;

                  --  Add the simple name before the name of the variable

                  Add_To_Buffer (".");
                  Add_To_Buffer
                    (Get_Name_String (Names.Table (Names.Last - 1).Name));
                  Name_Len := Buffer_Last;
                  Name_Buffer (1 .. Name_Len) := Buffer (1 .. Buffer_Last);
                  Long_Project := Name_Find;

                  --  Check if the prefix is the name of an imported or
                  --  extended project.

                  The_Project := Imported_Or_Extended_Project_Of
                                   (Current_Project, Long_Project);

                  if The_Project /= Empty_Node then
                     Specified_Project := The_Project;

                  else
                     --  Now check if the prefix may be a project name followed
                     --  by a package name.

                     --  First check for a possible project name

                     The_Project := Imported_Or_Extended_Project_Of
                                   (Current_Project, Short_Project);

                     if The_Project = Empty_Node then
                        --  Unknown prefix, report an error

                        Error_Msg_Name_1 := Long_Project;
                        Error_Msg_Name_2 := Short_Project;
                        Error_Msg ("unknown projects % or %",
                                   Names.Table (1).Location);
                        Look_For_Variable := False;

                     else
                        Specified_Project := The_Project;

                        --  Now look for the package in this project

                        The_Package := First_Package_Of (The_Project);

                        while The_Package /= Empty_Node
                          and then Name_Of (The_Package) /=
                                              Names.Table (Names.Last - 1).Name
                        loop
                           The_Package :=
                             Next_Package_In_Project (The_Package);
                        end loop;

                        if The_Package = Empty_Node then
                           --  The package does not vexist, report an error

                           Error_Msg_Name_1 := Names.Table (2).Name;
                           Error_Msg ("unknown package %",
                                   Names.Table (Names.Last - 1).Location);
                           Look_For_Variable := False;

                        else
                           Specified_Package := The_Package;
                        end if;
                     end if;
                  end if;
               end;
         end case;
      end if;

      if Look_For_Variable then
         Variable_Name := Name_Of (Variable);
         Set_Project_Node_Of (Variable, To => Specified_Project);
         Set_Package_Node_Of (Variable, To => Specified_Package);

         if Specified_Project /= Empty_Node then
            The_Project := Specified_Project;

         else
            The_Project := Current_Project;
         end if;

         Current_Variable := Empty_Node;

         --  Look for this variable

         --  If a package was specified, check if the variable has been
         --  declared in this package.

         if Specified_Package /= Empty_Node then
            Current_Variable := First_Variable_Of (Specified_Package);

            while Current_Variable /= Empty_Node
              and then
              Name_Of (Current_Variable) /= Variable_Name
            loop
               Current_Variable := Next_Variable (Current_Variable);
            end loop;

         else
            --  Otherwise, if no project has been specified and we are in
            --  a package, first check if the variable has been declared in
            --  the package.

            if Specified_Project = Empty_Node
              and then Current_Package /= Empty_Node
            then
               Current_Variable := First_Variable_Of (Current_Package);

               while Current_Variable /= Empty_Node
                 and then Name_Of (Current_Variable) /= Variable_Name
               loop
                  Current_Variable := Next_Variable (Current_Variable);
               end loop;
            end if;

            --  If we have not found the variable in the package, check if the
            --  variable has been declared in the project.

            if Current_Variable = Empty_Node then
               Current_Variable := First_Variable_Of (The_Project);

               while Current_Variable /= Empty_Node
                 and then Name_Of (Current_Variable) /= Variable_Name
               loop
                  Current_Variable := Next_Variable (Current_Variable);
               end loop;
            end if;
         end if;

         --  If the variable was not found, report an error

         if Current_Variable = Empty_Node then
            Error_Msg_Name_1 := Variable_Name;
            Error_Msg
              ("unknown variable %", Names.Table (Names.Last).Location);
         end if;
      end if;

      if Current_Variable /= Empty_Node then
         Set_Expression_Kind_Of
           (Variable, To => Expression_Kind_Of (Current_Variable));

         if Kind_Of (Current_Variable) = N_Typed_Variable_Declaration then
            Set_String_Type_Of
              (Variable, To => String_Type_Of (Current_Variable));
         end if;
      end if;

      --  If the variable is followed by a left parenthesis, report an error
      --  but attempt to scan the index.

      if Token = Tok_Left_Paren then
         Error_Msg ("\variables cannot be associative arrays", Token_Ptr);
         Scan;
         Expect (Tok_String_Literal, "literal string");

         if Token = Tok_String_Literal then
            Scan;
            Expect (Tok_Right_Paren, "`)`");

            if Token = Tok_Right_Paren then
               Scan;
            end if;
         end if;
      end if;
   end Parse_Variable_Reference;

   ---------------------------------
   -- Start_New_Case_Construction --
   ---------------------------------

   procedure Start_New_Case_Construction (String_Type  : Project_Node_Id) is
      Current_String : Project_Node_Id;

   begin
      --  Set Choice_First, depending on whether is the first case
      --  construction or not.

      if Choice_First = 0 then
         Choice_First := 1;
         Choices.Set_Last (First_Choice_Node_Id);
      else
         Choice_First := Choices.Last + 1;
      end if;

      --  Add to table Choices the literal of the string type

      if String_Type /= Empty_Node then
         Current_String := First_Literal_String (String_Type);

         while Current_String /= Empty_Node loop
            Add (This_String => String_Value_Of (Current_String));
            Current_String := Next_Literal_String (Current_String);
         end loop;
      end if;

      --  Set the value of the last choice in table Choice_Lasts

      Choice_Lasts.Increment_Last;
      Choice_Lasts.Table (Choice_Lasts.Last) := Choices.Last;

   end Start_New_Case_Construction;

   -----------
   -- Terms --
   -----------

   procedure Terms
     (Term            : out Project_Node_Id;
      Expr_Kind       : in out Variable_Kind;
      Current_Project : Project_Node_Id;
      Current_Package : Project_Node_Id;
      Optional_Index  : Boolean)
   is
      Next_Term          : Project_Node_Id := Empty_Node;
      Term_Id            : Project_Node_Id := Empty_Node;
      Current_Expression : Project_Node_Id := Empty_Node;
      Next_Expression    : Project_Node_Id := Empty_Node;
      Current_Location   : Source_Ptr      := No_Location;
      Reference          : Project_Node_Id := Empty_Node;

   begin
      --  Declare a new node for the term

      Term := Default_Project_Node (Of_Kind => N_Term);
      Set_Location_Of (Term, To => Token_Ptr);

      case Token is
         when Tok_Left_Paren =>

            --  If we have a left parenthesis and we don't know the expression
            --  kind, then this is a string list.

            case Expr_Kind is
               when Undefined =>
                  Expr_Kind := List;

               when List =>
                  null;

               when Single =>

                  --  If we already know that this is a single string, report
                  --  an error, but set the expression kind to string list to
                  --  avoid several errors.

                  Expr_Kind := List;
                  Error_Msg
                    ("literal string list cannot appear in a string",
                     Token_Ptr);
            end case;

            --  Declare a new node for this literal string list

            Term_Id := Default_Project_Node
              (Of_Kind => N_Literal_String_List,
               And_Expr_Kind => List);
            Set_Current_Term (Term, To => Term_Id);
            Set_Location_Of (Term, To => Token_Ptr);

            --  Scan past the left parenthesis

            Scan;

            --  If the left parenthesis is immediately followed by a right
            --  parenthesis, the literal string list is empty.

            if Token = Tok_Right_Paren then
               Scan;

            else
               --  Otherwise, we parse the expression(s) in the literal string
               --  list.

               loop
                  Current_Location := Token_Ptr;
                  Parse_Expression (Expression      => Next_Expression,
                                    Current_Project => Current_Project,
                                    Current_Package => Current_Package,
                                    Optional_Index  => Optional_Index);

                  --  The expression kind is String list, report an error

                  if Expression_Kind_Of (Next_Expression) = List then
                     Error_Msg ("single expression expected",
                                Current_Location);
                  end if;

                  --  If Current_Expression is empty, it means that the
                  --  expression is the first in the string list.

                  if Current_Expression = Empty_Node then
                     Set_First_Expression_In_List
                       (Term_Id, To => Next_Expression);
                  else
                     Set_Next_Expression_In_List
                       (Current_Expression, To => Next_Expression);
                  end if;

                  Current_Expression := Next_Expression;

                  --  If there is a comma, continue with the next expression

                  exit when Token /= Tok_Comma;
                  Scan; -- past the comma
               end loop;

               --  We expect a closing right parenthesis

               Expect (Tok_Right_Paren, "`)`");

               if Token = Tok_Right_Paren then
                  Scan;
               end if;
            end if;

         when Tok_String_Literal =>

            --  If we don't know the expression kind (first term), then it is
            --  a simple string.

            if Expr_Kind = Undefined then
               Expr_Kind := Single;
            end if;

            --  Declare a new node for the string literal

            Term_Id := Default_Project_Node (Of_Kind => N_Literal_String);
            Set_Current_Term (Term, To => Term_Id);
            Set_String_Value_Of (Term_Id, To => Token_Name);

            --  Scan past the string literal

            Scan;

            --  Check for possible index expression

            if Token = Tok_At then
               if not Optional_Index then
                  Error_Msg ("index not allowed here", Token_Ptr);
                  Scan;

                  if Token = Tok_Integer_Literal then
                     Scan;
                  end if;

               --  Set the index value

               else
                  Scan;
                  Expect (Tok_Integer_Literal, "integer literal");

                  if Token = Tok_Integer_Literal then
                     declare
                        Index : constant Int := UI_To_Int (Int_Literal_Value);
                     begin
                        if Index = 0 then
                           Error_Msg ("index cannot be zero", Token_Ptr);
                        else
                           Set_Source_Index_Of (Term_Id, To => Index);
                        end if;
                     end;

                     Scan;
                  end if;
               end if;
            end if;

         when Tok_Identifier =>
            Current_Location := Token_Ptr;

            --  Get the variable or attribute reference

            Parse_Variable_Reference
              (Variable        => Reference,
               Current_Project => Current_Project,
               Current_Package => Current_Package);
            Set_Current_Term (Term, To => Reference);

            if Reference /= Empty_Node then

               --  If we don't know the expression kind (first term), then it
               --  has the kind of the variable or attribute reference.

               if Expr_Kind = Undefined then
                  Expr_Kind := Expression_Kind_Of (Reference);

               elsif Expr_Kind = Single
                 and then Expression_Kind_Of (Reference) = List
               then
                  --  If the expression is a single list, and the reference is
                  --  a string list, report an error, and set the expression
                  --  kind to string list to avoid multiple errors.

                  Expr_Kind := List;
                  Error_Msg
                    ("list variable cannot appear in single string expression",
                     Current_Location);
               end if;
            end if;

         when Tok_Project =>

            --  project can appear in an expression as the prefix of an
            --  attribute reference of the current project.

            Current_Location := Token_Ptr;
            Scan;
            Expect (Tok_Apostrophe, "`'`");

            if Token = Tok_Apostrophe then
               Attribute_Reference
                 (Reference       => Reference,
                  First_Attribute => Prj.Attr.Attribute_First,
                  Current_Project => Current_Project,
                  Current_Package => Empty_Node);
               Set_Current_Term (Term, To => Reference);
            end if;

            --  Same checks as above for the expression kind

            if Reference /= Empty_Node then
               if Expr_Kind = Undefined then
                  Expr_Kind := Expression_Kind_Of (Reference);

               elsif Expr_Kind = Single
                 and then Expression_Kind_Of (Reference) = List
               then
                  Error_Msg
                    ("lists cannot appear in single string expression",
                     Current_Location);
               end if;
            end if;

         when Tok_External =>
            --  An external reference is always a single string

            if Expr_Kind = Undefined then
               Expr_Kind := Single;
            end if;

            External_Reference (External_Value => Reference);
            Set_Current_Term (Term, To => Reference);

         when others =>
            Error_Msg ("cannot be part of an expression", Token_Ptr);
            Term := Empty_Node;
            return;
      end case;

      --  If there is an '&', call Terms recursively

      if Token = Tok_Ampersand then

         --  Scan past the '&'

         Scan;

         Terms (Term            => Next_Term,
                Expr_Kind       => Expr_Kind,
                Current_Project => Current_Project,
                Current_Package => Current_Package,
                Optional_Index  => Optional_Index);

         --  And link the next term to this term

         Set_Next_Term (Term, To => Next_Term);
      end if;
   end Terms;

end Prj.Strt;
