-----------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              P A R . C H 4                               --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 1992-2021, 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 3,  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 COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

pragma Style_Checks (All_Checks);
--  Turn off subprogram body ordering check. Subprograms are in order
--  by RM section rather than alphabetical

with Stringt; use Stringt;

separate (Par)
package body Ch4 is

   --  Attributes that cannot have arguments

   Is_Parameterless_Attribute : constant Attribute_Class_Array :=
     (Attribute_Base         => True,
      Attribute_Body_Version => True,
      Attribute_Class        => True,
      Attribute_External_Tag => True,
      Attribute_Img          => True,
      Attribute_Loop_Entry   => True,
      Attribute_Old          => True,
      Attribute_Result       => True,
      Attribute_Stub_Type    => True,
      Attribute_Version      => True,
      Attribute_Type_Key     => True,
      others                 => False);
   --  This map contains True for parameterless attributes that return a string
   --  or a type. For those attributes, a left parenthesis after the attribute
   --  should not be analyzed as the beginning of a parameters list because it
   --  may denote a slice operation (X'Img (1 .. 2)) or a type conversion
   --  (X'Class (Y)).

   --  Note: Loop_Entry is in this list because, although it can take an
   --  optional argument (the loop name), we can't distinguish that at parse
   --  time from the case where no loop name is given and a legitimate index
   --  expression is present. So we parse the argument as an indexed component
   --  and the semantic analysis sorts out this syntactic ambiguity based on
   --  the type and form of the expression.

   --  Note that this map designates the minimum set of attributes where a
   --  construct in parentheses that is not an argument can appear right
   --  after the attribute. For attributes like 'Size, we do not put them
   --  in the map. If someone writes X'Size (3), that's illegal in any case,
   --  but we get a better error message by parsing the (3) as an illegal
   --  argument to the attribute, rather than some meaningless junk that
   --  follows the attribute.

   -----------------------
   -- Local Subprograms --
   -----------------------

   function P_Aggregate_Or_Paren_Expr               return Node_Id;
   function P_Allocator                             return Node_Id;
   function P_Case_Expression_Alternative           return Node_Id;
   function P_Iterated_Component_Association        return Node_Id;
   function P_Record_Or_Array_Component_Association return Node_Id;
   function P_Factor                                return Node_Id;
   function P_Primary                               return Node_Id;
   function P_Relation                              return Node_Id;
   function P_Term                                  return Node_Id;
   function P_Declare_Expression                    return Node_Id;
   function P_Reduction_Attribute_Reference (S : Node_Id)
      return Node_Id;

   function P_Binary_Adding_Operator                return Node_Kind;
   function P_Logical_Operator                      return Node_Kind;
   function P_Multiplying_Operator                  return Node_Kind;
   function P_Relational_Operator                   return Node_Kind;
   function P_Unary_Adding_Operator                 return Node_Kind;

   procedure Bad_Range_Attribute (Loc : Source_Ptr);
   --  Called to place complaint about bad range attribute at the given
   --  source location. Terminates by raising Error_Resync.

   procedure Check_Bad_Exp;
   --  Called after scanning a**b, posts error if ** detected

   procedure P_Membership_Test (N : Node_Id);
   --  N is the node for a N_In or N_Not_In node whose right operand has not
   --  yet been processed. It is called just after scanning out the IN keyword.
   --  On return, either Right_Opnd or Alternatives is set, as appropriate.

   function P_Range_Attribute_Reference (Prefix_Node : Node_Id) return Node_Id;
   --  Scan a range attribute reference. The caller has scanned out the
   --  prefix. The current token is known to be an apostrophe and the
   --  following token is known to be RANGE.

   function P_Case_Expression return Node_Id;
   --  Scans out a case expression. Called with Token pointing to the CASE
   --  keyword, and returns pointing to the terminating right parent,
   --  semicolon, or comma, but does not consume this terminating token.

   function P_Unparen_Cond_Expr_Etc return Node_Id;
   --  This function is called with Token pointing to IF, CASE, FOR, or
   --  DECLARE, in a context that allows a conditional (if or case) expression,
   --  a quantified expression, an iterated component association, or a declare
   --  expression, if it is surrounded by parentheses. If not surrounded by
   --  parentheses, the expression is still returned, but an error message is
   --  issued.

   -------------------------
   -- Bad_Range_Attribute --
   -------------------------

   procedure Bad_Range_Attribute (Loc : Source_Ptr) is
   begin
      Error_Msg ("range attribute cannot be used in expression!", Loc);
      Resync_Expression;
   end Bad_Range_Attribute;

   -------------------
   -- Check_Bad_Exp --
   -------------------

   procedure Check_Bad_Exp is
   begin
      if Token = Tok_Double_Asterisk then
         Error_Msg_SC ("parenthesization required for '*'*");
         Scan; -- past **
         Discard_Junk_Node (P_Primary);
         Check_Bad_Exp;
      end if;
   end Check_Bad_Exp;

   --------------------------
   -- 4.1  Name (also 6.4) --
   --------------------------

   --  NAME ::=
   --    DIRECT_NAME        | EXPLICIT_DEREFERENCE
   --  | INDEXED_COMPONENT  | SLICE
   --  | SELECTED_COMPONENT | ATTRIBUTE
   --  | TYPE_CONVERSION    | FUNCTION_CALL
   --  | CHARACTER_LITERAL  | TARGET_NAME

   --  DIRECT_NAME ::= IDENTIFIER | OPERATOR_SYMBOL

   --  PREFIX ::= NAME | IMPLICIT_DEREFERENCE

   --  EXPLICIT_DEREFERENCE ::= NAME . all

   --  IMPLICIT_DEREFERENCE ::= NAME

   --  INDEXED_COMPONENT ::= PREFIX (EXPRESSION {, EXPRESSION})

   --  SLICE ::= PREFIX (DISCRETE_RANGE)

   --  SELECTED_COMPONENT ::= PREFIX . SELECTOR_NAME

   --  SELECTOR_NAME ::= IDENTIFIER | CHARACTER_LITERAL | OPERATOR_SYMBOL

   --  ATTRIBUTE_REFERENCE ::= PREFIX ' ATTRIBUTE_DESIGNATOR

   --  ATTRIBUTE_DESIGNATOR ::=
   --    IDENTIFIER [(static_EXPRESSION)]
   --  | access | delta | digits

   --  FUNCTION_CALL ::=
   --    function_NAME
   --  | function_PREFIX ACTUAL_PARAMETER_PART

   --  ACTUAL_PARAMETER_PART ::=
   --    (PARAMETER_ASSOCIATION {,PARAMETER_ASSOCIATION})

   --  PARAMETER_ASSOCIATION ::=
   --    [formal_parameter_SELECTOR_NAME =>] EXPLICIT_ACTUAL_PARAMETER

   --  EXPLICIT_ACTUAL_PARAMETER ::= EXPRESSION | variable_NAME

   --  TARGET_NAME ::= @   (AI12-0125-3: abbreviation for LHS)

   --  Note: syntactically a procedure call looks just like a function call,
   --  so this routine is in practice used to scan out procedure calls as well.

   --  On return, Expr_Form is set to either EF_Name or EF_Simple_Name

   --  Error recovery: can raise Error_Resync

   --  Note: if on return Token = Tok_Apostrophe, then the apostrophe must be
   --  followed by either a left paren (qualified expression case), or by
   --  range (range attribute case). All other uses of apostrophe (i.e. all
   --  other attributes) are handled in this routine.

   --  Error recovery: can raise Error_Resync

   function P_Name return Node_Id is
      Scan_State  : Saved_Scan_State;
      Name_Node   : Node_Id;
      Prefix_Node : Node_Id;
      Ident_Node  : Node_Id;
      Expr_Node   : Node_Id;
      Range_Node  : Node_Id;
      Arg_Node    : Node_Id;

      Arg_List  : List_Id := No_List; -- kill junk warning
      Attr_Name : Name_Id := No_Name; -- kill junk warning

   begin
      --  Case of not a name

      if Token not in Token_Class_Name then

         --  If it looks like start of expression, complain and scan expression

         if Token in Token_Class_Literal
           or else Token = Tok_Left_Paren
         then
            Error_Msg_SC ("name expected");
            return P_Expression;

         --  Otherwise some other junk, not much we can do

         else
            Error_Msg_AP ("name expected");
            raise Error_Resync;
         end if;
      end if;

      --  Loop through designators in qualified name
      --  AI12-0125 : target_name

      if Token = Tok_At_Sign then
         Scan_Reserved_Identifier (Force_Msg => False);

         if Present (Current_Assign_Node) then
            Set_Has_Target_Names (Current_Assign_Node);
         end if;
      end if;

      Name_Node := Token_Node;

      loop
         Scan; -- past designator
         exit when Token /= Tok_Dot;
         Save_Scan_State (Scan_State); -- at dot
         Scan; -- past dot

         --  If we do not have another designator after the dot, then join
         --  the normal circuit to handle a dot extension (may be .all or
         --  character literal case). Otherwise loop back to scan the next
         --  designator.

         if Token not in Token_Class_Desig then
            goto Scan_Name_Extension_Dot;
         else
            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Selected_Component, Prev_Token_Ptr);
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Selector_Name (Name_Node, Token_Node);
         end if;
      end loop;

      --  We have now scanned out a qualified designator. If the last token is
      --  an operator symbol, then we certainly do not have the Snam case, so
      --  we can just use the normal name extension check circuit

      if Prev_Token = Tok_Operator_Symbol then
         goto Scan_Name_Extension;
      end if;

      --  We have scanned out a qualified simple name, check for name
      --  extension.  Note that we know there is no dot here at this stage,
      --  so the only possible cases of name extension are apostrophe followed
      --  by '(' or '['.

      if Token = Tok_Apostrophe then
         Save_Scan_State (Scan_State); -- at apostrophe
         Scan; -- past apostrophe

         --  Qualified expression in Ada 2012 mode (treated as a name)

         if Ada_Version >= Ada_2012
           and then Token in Tok_Left_Paren | Tok_Left_Bracket
         then
            goto Scan_Name_Extension_Apostrophe;

         --  If left paren not in Ada 2012, then it is not part of the name,
         --  since qualified expressions are not names in prior versions of
         --  Ada, so return with Token backed up to point to the apostrophe.
         --  The treatment for the range attribute is similar (we do not
         --  consider x'range to be a name in this grammar).

         elsif Token = Tok_Left_Paren or else Token = Tok_Range then
            Restore_Scan_State (Scan_State); -- to apostrophe
            Expr_Form := EF_Simple_Name;
            return Name_Node;

         --  Otherwise we have the case of a name extended by an attribute

         else
            goto Scan_Name_Extension_Apostrophe;
         end if;

      --  Check case of qualified simple name extended by a left parenthesis

      elsif Token = Tok_Left_Paren then
         Scan; -- past left paren
         goto Scan_Name_Extension_Left_Paren;

      --  Otherwise the qualified simple name is not extended, so return

      else
         Expr_Form := EF_Simple_Name;
         return Name_Node;
      end if;

      --  Loop scanning past name extensions. A label is used for control
      --  transfer for this loop for ease of interfacing with the finite state
      --  machine in the parenthesis scanning circuit, and also to allow for
      --  passing in control to the appropriate point from the above code.

      <<Scan_Name_Extension>>

         --  Character literal used as name cannot be extended. Also this
         --  cannot be a call, since the name for a call must be a designator.
         --  Return in these cases, or if there is no name extension

         if Token not in Token_Class_Namext
           or else Prev_Token = Tok_Char_Literal
         then
            Expr_Form := EF_Name;
            return Name_Node;
         end if;

      --  Merge here when we know there is a name extension

      <<Scan_Name_Extension_OK>>

         if Token = Tok_Left_Paren then
            Scan; -- past left paren
            goto Scan_Name_Extension_Left_Paren;

         elsif Token = Tok_Apostrophe then
            Save_Scan_State (Scan_State); -- at apostrophe
            Scan; -- past apostrophe
            goto Scan_Name_Extension_Apostrophe;

         else -- Token = Tok_Dot
            Save_Scan_State (Scan_State); -- at dot
            Scan; -- past dot
            goto Scan_Name_Extension_Dot;
         end if;

      --  Case of name extended by dot (selection), dot is already skipped
      --  and the scan state at the point of the dot is saved in Scan_State.

      <<Scan_Name_Extension_Dot>>

         --  Explicit dereference case

         if Token = Tok_All then
            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Explicit_Dereference, Token_Ptr);
            Set_Prefix (Name_Node, Prefix_Node);
            Scan; -- past ALL
            goto Scan_Name_Extension;

         --  Selected component case

         elsif Token in Token_Class_Name then
            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Selected_Component, Prev_Token_Ptr);
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Selector_Name (Name_Node, Token_Node);
            Scan; -- past selector
            goto Scan_Name_Extension;

         --  Reserved identifier as selector

         elsif Is_Reserved_Identifier then
            Scan_Reserved_Identifier (Force_Msg => False);
            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Selected_Component, Prev_Token_Ptr);
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Selector_Name (Name_Node, Token_Node);
            Scan; -- past identifier used as selector
            goto Scan_Name_Extension;

         --  If dot is at end of line and followed by nothing legal,
         --  then assume end of name and quit (dot will be taken as
         --  an incorrect form of some other punctuation by our caller).

         elsif Token_Is_At_Start_Of_Line then
            Restore_Scan_State (Scan_State);
            return Name_Node;

         --  Here if nothing legal after the dot

         else
            Error_Msg_AP ("selector expected");
            raise Error_Resync;
         end if;

      --  Here for an apostrophe as name extension. The scan position at the
      --  apostrophe has already been saved, and the apostrophe scanned out.

      <<Scan_Name_Extension_Apostrophe>>

         Scan_Apostrophe : declare
            function Apostrophe_Should_Be_Semicolon return Boolean;
            --  Checks for case where apostrophe should probably be
            --  a semicolon, and if so, gives appropriate message,
            --  resets the scan pointer to the apostrophe, changes
            --  the current token to Tok_Semicolon, and returns True.
            --  Otherwise returns False.

            ------------------------------------
            -- Apostrophe_Should_Be_Semicolon --
            ------------------------------------

            function Apostrophe_Should_Be_Semicolon return Boolean is
            begin
               if Token_Is_At_Start_Of_Line then
                  Restore_Scan_State (Scan_State); -- to apostrophe
                  Error_Msg_SC ("|""''"" should be "";""");
                  Token := Tok_Semicolon;
                  return True;
               else
                  return False;
               end if;
            end Apostrophe_Should_Be_Semicolon;

         --  Start of processing for Scan_Apostrophe

         begin
            --  Check for qualified expression case in Ada 2012 mode

            if Ada_Version >= Ada_2012
              and then Token in Tok_Left_Paren | Tok_Left_Bracket
            then
               Name_Node := P_Qualified_Expression (Name_Node);
               goto Scan_Name_Extension;

            --  If range attribute after apostrophe, then return with Token
            --  pointing to the apostrophe. Note that in this case the prefix
            --  need not be a simple name (cases like A.all'range). Similarly
            --  if there is a left paren after the apostrophe, then we also
            --  return with Token pointing to the apostrophe (this is the
            --  aggregate case, or some error case).

            elsif Token = Tok_Range or else Token = Tok_Left_Paren then
               Restore_Scan_State (Scan_State); -- to apostrophe
               Expr_Form := EF_Name;
               return Name_Node;

            --  Here for cases where attribute designator is an identifier

            elsif Token = Tok_Identifier then
               Attr_Name := Token_Name;

               if not Is_Attribute_Name (Attr_Name) then
                  if Apostrophe_Should_Be_Semicolon then
                     Expr_Form := EF_Name;
                     return Name_Node;

                  --  Here for a bad attribute name

                  else
                     Signal_Bad_Attribute;
                     Scan; -- past bad identifier

                     if Token = Tok_Left_Paren then
                        Scan; -- past left paren

                        loop
                           Discard_Junk_Node (P_Expression_If_OK);
                           exit when not Comma_Present;
                        end loop;

                        T_Right_Paren;
                     end if;

                     return Error;
                  end if;
               end if;

               if Style_Check then
                  Style.Check_Attribute_Name (False);
               end if;

            --  Here for case of attribute designator is not an identifier

            else
               if Token = Tok_Delta then
                  Attr_Name := Name_Delta;

               elsif Token = Tok_Digits then
                  Attr_Name := Name_Digits;

               elsif Token = Tok_Access then
                  Attr_Name := Name_Access;

               elsif Token = Tok_Mod and then Ada_Version >= Ada_95 then
                  Attr_Name := Name_Mod;

               elsif Apostrophe_Should_Be_Semicolon then
                  Expr_Form := EF_Name;
                  return Name_Node;

               else
                  Error_Msg_AP ("attribute designator expected");
                  raise Error_Resync;
               end if;

               if Style_Check then
                  Style.Check_Attribute_Name (True);
               end if;
            end if;

            --  We come here with an OK attribute scanned, and corresponding
            --  Attribute identifier node stored in Ident_Node.

            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Attribute_Reference, Prev_Token_Ptr);
            Scan; -- past attribute designator
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Attribute_Name (Name_Node, Attr_Name);

            --  Scan attribute arguments/designator. We skip this if we know
            --  that the attribute cannot have an argument (see documentation
            --  of Is_Parameterless_Attribute for further details).

            if Token = Tok_Left_Paren
              and then not
                Is_Parameterless_Attribute (Get_Attribute_Id (Attr_Name))
            then
               --  Attribute Update contains an array or record association
               --  list which provides new values for various components or
               --  elements. The list is parsed as an aggregate, and we get
               --  better error handling by knowing that in the parser.

               if Attr_Name = Name_Update then
                  Set_Expressions (Name_Node, New_List);
                  Append (P_Aggregate, Expressions (Name_Node));

               --  All other cases of parsing attribute arguments

               else
                  Set_Expressions (Name_Node, New_List);
                  Scan; -- past left paren

                  loop
                     declare
                        Expr : constant Node_Id := P_Expression_If_OK;
                        Rnam : Node_Id;

                     begin
                        --  Case of => for named notation

                        if Token = Tok_Arrow then

                           --  Named notation allowed only for the special
                           --  case of System'Restriction_Set (No_Dependence =>
                           --  unit_NAME), in which case construct a parameter
                           --  assocation node and append to the arguments.

                           if Attr_Name = Name_Restriction_Set
                             and then Nkind (Expr) = N_Identifier
                             and then Chars (Expr) = Name_No_Dependence
                           then
                              Scan; -- past arrow
                              Rnam := P_Name;
                              Append_To (Expressions (Name_Node),
                                Make_Parameter_Association (Sloc (Rnam),
                                  Selector_Name             => Expr,
                                  Explicit_Actual_Parameter => Rnam));
                              exit;

                           --  For all other cases named notation is illegal

                           else
                              Error_Msg_SC
                                ("named parameters not permitted "
                                 & "for attributes");
                              Scan; -- past junk arrow
                           end if;

                        --  Here for normal case (not => for named parameter)

                        else
                           --  Special handling for 'Image in Ada 2012, where
                           --  the attribute can be parameterless and its value
                           --  can be the prefix of a slice. Rewrite name as a
                           --  slice, Expr is its low bound.

                           if Token = Tok_Dot_Dot
                             and then Attr_Name = Name_Image
                             and then Ada_Version >= Ada_2012
                           then
                              Set_Expressions (Name_Node, No_List);
                              Prefix_Node := Name_Node;
                              Name_Node :=
                                New_Node (N_Slice, Sloc (Prefix_Node));
                              Set_Prefix (Name_Node, Prefix_Node);
                              Range_Node := New_Node (N_Range, Token_Ptr);
                              Set_Low_Bound (Range_Node, Expr);
                              Scan; -- past ..
                              Expr_Node := P_Expression;
                              Check_Simple_Expression (Expr_Node);
                              Set_High_Bound (Range_Node, Expr_Node);
                              Set_Discrete_Range (Name_Node, Range_Node);
                              T_Right_Paren;

                              goto Scan_Name_Extension;

                           else
                              Append (Expr, Expressions (Name_Node));
                              exit when not Comma_Present;
                           end if;
                        end if;
                     end;
                  end loop;

                  T_Right_Paren;
               end if;
            end if;

            goto Scan_Name_Extension;
         end Scan_Apostrophe;

      --  Here for left parenthesis extending name (left paren skipped)

      <<Scan_Name_Extension_Left_Paren>>

         --  We now have to scan through a list of items, terminated by a
         --  right parenthesis. The scan is handled by a finite state
         --  machine. The possibilities are:

         --   (discrete_range)

         --      This is a slice. This case is handled in LP_State_Init

         --   (expression, expression, ..)

         --      This is interpreted as an indexed component, i.e. as a
         --      case of a name which can be extended in the normal manner.
         --      This case is handled by LP_State_Name or LP_State_Expr.

         --      Note: if and case expressions (without an extra level of
         --      parentheses) are permitted in this context).

         --   (..., identifier => expression , ...)

         --      If there is at least one occurrence of identifier => (but
         --      none of the other cases apply), then we have a call.

         --  Test for Id => case

         if Token = Tok_Identifier then
            Save_Scan_State (Scan_State); -- at Id
            Scan; -- past Id

            --  Test for => (allow := as an error substitute)

            if Token = Tok_Arrow or else Token = Tok_Colon_Equal then
               Restore_Scan_State (Scan_State); -- to Id
               Arg_List := New_List;
               goto LP_State_Call;

            else
               Restore_Scan_State (Scan_State); -- to Id
            end if;
         end if;

         --  Here we have an expression after all

         Expr_Node := P_Expression_Or_Range_Attribute_If_OK;

         --  Check cases of discrete range for a slice

         --  First possibility: Range_Attribute_Reference

         if Expr_Form = EF_Range_Attr then
            Range_Node := Expr_Node;

         --  Second possibility: Simple_expression .. Simple_expression

         elsif Token = Tok_Dot_Dot then
            Check_Simple_Expression (Expr_Node);
            Range_Node := New_Node (N_Range, Token_Ptr);
            Set_Low_Bound (Range_Node, Expr_Node);
            Scan; -- past ..
            Expr_Node := P_Expression;
            Check_Simple_Expression (Expr_Node);
            Set_High_Bound (Range_Node, Expr_Node);

         --  Third possibility: Type_name range Range

         elsif Token = Tok_Range then
            if Expr_Form /= EF_Simple_Name then
               Error_Msg_SC ("subtype mark must precede RANGE");
               raise Error_Resync;
            end if;

            Range_Node := P_Subtype_Indication (Expr_Node);

         --  Otherwise we just have an expression. It is true that we might
         --  have a subtype mark without a range constraint but this case
         --  is syntactically indistinguishable from the expression case.

         else
            Arg_List := New_List;
            goto LP_State_Expr;
         end if;

         --  Fall through here with unmistakable Discrete range scanned,
         --  which means that we definitely have the case of a slice. The
         --  Discrete range is in Range_Node.

         if Token = Tok_Comma then
            Error_Msg_SC ("slice cannot have more than one dimension");
            raise Error_Resync;

         elsif Token /= Tok_Right_Paren then
            if Token = Tok_Arrow then

               --  This may be an aggregate that is missing a qualification

               Error_Msg_SC
                 ("context of aggregate must be a qualified expression");
               raise Error_Resync;

            else
               T_Right_Paren;
               raise Error_Resync;
            end if;

         else
            Scan; -- past right paren
            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Slice, Sloc (Prefix_Node));
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Discrete_Range (Name_Node, Range_Node);

            --  An operator node is legal as a prefix to other names,
            --  but not for a slice.

            if Nkind (Prefix_Node) = N_Operator_Symbol then
               Error_Msg_N ("illegal prefix for slice", Prefix_Node);
            end if;

            --  If we have a name extension, go scan it

            if Token in Token_Class_Namext then
               goto Scan_Name_Extension_OK;

            --  Otherwise return (a slice is a name, but is not a call)

            else
               Expr_Form := EF_Name;
               return Name_Node;
            end if;
         end if;

      --  In LP_State_Expr, we have scanned one or more expressions, and
      --  so we have a call or an indexed component which is a name. On
      --  entry we have the expression just scanned in Expr_Node and
      --  Arg_List contains the list of expressions encountered so far

      <<LP_State_Expr>>
         Append (Expr_Node, Arg_List);

         if Token = Tok_Arrow then
            Error_Msg
              ("expect identifier in parameter association", Sloc (Expr_Node));
            Scan;  -- past arrow

         elsif not Comma_Present then
            T_Right_Paren;

            Prefix_Node := Name_Node;
            Name_Node := New_Node (N_Indexed_Component, Sloc (Prefix_Node));
            Set_Prefix (Name_Node, Prefix_Node);
            Set_Expressions (Name_Node, Arg_List);

            goto Scan_Name_Extension;
         end if;

         --  Comma present (and scanned out), test for identifier => case
         --  Test for identifier => case

         if Token = Tok_Identifier then
            Save_Scan_State (Scan_State); -- at Id
            Scan; -- past Id

            --  Test for => (allow := as error substitute)

            if Token = Tok_Arrow or else Token = Tok_Colon_Equal then
               Restore_Scan_State (Scan_State); -- to Id
               goto LP_State_Call;

            --  Otherwise it's just an expression after all, so backup

            else
               Restore_Scan_State (Scan_State); -- to Id
            end if;
         end if;

         --  Here we have an expression after all, so stay in this state

         Expr_Node := P_Expression_If_OK;
         goto LP_State_Expr;

      --  LP_State_Call corresponds to the situation in which at least one
      --  instance of Id => Expression has been encountered, so we know that
      --  we do not have a name, but rather a call. We enter it with the
      --  scan pointer pointing to the next argument to scan, and Arg_List
      --  containing the list of arguments scanned so far.

      <<LP_State_Call>>

         --  Test for case of Id => Expression (named parameter)

         if Token = Tok_Identifier then
            Save_Scan_State (Scan_State); -- at Id
            Ident_Node := Token_Node;
            Scan; -- past Id

            --  Deal with => (allow := as incorrect substitute)

            if Token = Tok_Arrow or else Token = Tok_Colon_Equal then
               Arg_Node := New_Node (N_Parameter_Association, Prev_Token_Ptr);
               Set_Selector_Name (Arg_Node, Ident_Node);
               T_Arrow;
               Set_Explicit_Actual_Parameter (Arg_Node, P_Expression);
               Append (Arg_Node, Arg_List);

               --  If a comma follows, go back and scan next entry

               if Comma_Present then
                  goto LP_State_Call;

               --  Otherwise we have the end of a call

               else
                  Prefix_Node := Name_Node;
                  Name_Node := New_Node (N_Function_Call, Sloc (Prefix_Node));
                  Set_Name (Name_Node, Prefix_Node);
                  Set_Parameter_Associations (Name_Node, Arg_List);
                  T_Right_Paren;

                  if Token in Token_Class_Namext then
                     goto Scan_Name_Extension_OK;

                  --  This is a case of a call which cannot be a name

                  else
                     Expr_Form := EF_Name;
                     return Name_Node;
                  end if;
               end if;

            --  Not named parameter: Id started an expression after all

            else
               Restore_Scan_State (Scan_State); -- to Id
            end if;
         end if;

         --  Here if entry did not start with Id => which means that it
         --  is a positional parameter, which is not allowed, since we
         --  have seen at least one named parameter already.

         Error_Msg_SC
            ("positional parameter association " &
              "not allowed after named one");

         Expr_Node := P_Expression_If_OK;

         --  Leaving the '>' in an association is not unusual, so suggest
         --  a possible fix.

         if Nkind (Expr_Node) = N_Op_Eq then
            Error_Msg_N ("\maybe `='>` was intended", Expr_Node);
         end if;

         --  We go back to scanning out expressions, so that we do not get
         --  multiple error messages when several positional parameters
         --  follow a named parameter.

         goto LP_State_Expr;

         --  End of treatment for name extensions starting with left paren

      --  End of loop through name extensions

   end P_Name;

   --  This function parses a restricted form of Names which are either
   --  designators, or designators preceded by a sequence of prefixes
   --  that are direct names.

   --  Error recovery: cannot raise Error_Resync

   function P_Function_Name return Node_Id is
      Designator_Node : Node_Id;
      Prefix_Node     : Node_Id;
      Selector_Node   : Node_Id;
      Dot_Sloc        : Source_Ptr := No_Location;

   begin
      --  Prefix_Node is set to the gathered prefix so far, Empty means that
      --  no prefix has been scanned. This allows us to build up the result
      --  in the required right recursive manner.

      Prefix_Node := Empty;

      --  Loop through prefixes

      loop
         Designator_Node := Token_Node;

         if Token not in Token_Class_Desig then
            return P_Identifier; -- let P_Identifier issue the error message

         else -- Token in Token_Class_Desig
            Scan; -- past designator
            exit when Token /= Tok_Dot;
         end if;

         --  Here at a dot, with token just before it in Designator_Node

         if No (Prefix_Node) then
            Prefix_Node := Designator_Node;
         else
            Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
            Set_Prefix (Selector_Node, Prefix_Node);
            Set_Selector_Name (Selector_Node, Designator_Node);
            Prefix_Node := Selector_Node;
         end if;

         Dot_Sloc := Token_Ptr;
         Scan; -- past dot
      end loop;

      --  Fall out of the loop having just scanned a designator

      if No (Prefix_Node) then
         return Designator_Node;
      else
         Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
         Set_Prefix (Selector_Node, Prefix_Node);
         Set_Selector_Name (Selector_Node, Designator_Node);
         return Selector_Node;
      end if;

   exception
      when Error_Resync =>
         return Error;
   end P_Function_Name;

   --  This function parses a restricted form of Names which are either
   --  identifiers, or identifiers preceded by a sequence of prefixes
   --  that are direct names.

   --  Error recovery: cannot raise Error_Resync

   function P_Qualified_Simple_Name return Node_Id is
      Designator_Node : Node_Id;
      Prefix_Node     : Node_Id;
      Selector_Node   : Node_Id;
      Dot_Sloc        : Source_Ptr := No_Location;

   begin
      --  Prefix node is set to the gathered prefix so far, Empty means that
      --  no prefix has been scanned. This allows us to build up the result
      --  in the required right recursive manner.

      Prefix_Node := Empty;

      --  Loop through prefixes

      loop
         Designator_Node := Token_Node;

         if Token = Tok_Identifier then
            Scan; -- past identifier
            exit when Token /= Tok_Dot;

         elsif Token not in Token_Class_Desig then
            return P_Identifier; -- let P_Identifier issue the error message

         else
            Scan; -- past designator

            if Token /= Tok_Dot then
               Error_Msg_SP ("identifier expected");
               return Error;
            end if;
         end if;

         --  Here at a dot, with token just before it in Designator_Node

         if No (Prefix_Node) then
            Prefix_Node := Designator_Node;
         else
            Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
            Set_Prefix (Selector_Node, Prefix_Node);
            Set_Selector_Name (Selector_Node, Designator_Node);
            Prefix_Node := Selector_Node;
         end if;

         Dot_Sloc := Token_Ptr;
         Scan; -- past dot
      end loop;

      --  Fall out of the loop having just scanned an identifier

      if No (Prefix_Node) then
         return Designator_Node;
      else
         Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
         Set_Prefix (Selector_Node, Prefix_Node);
         Set_Selector_Name (Selector_Node, Designator_Node);
         return Selector_Node;
      end if;

   exception
      when Error_Resync =>
         return Error;
   end P_Qualified_Simple_Name;

   --  This procedure differs from P_Qualified_Simple_Name only in that it
   --  raises Error_Resync if any error is encountered. It only returns after
   --  scanning a valid qualified simple name.

   --  Error recovery: can raise Error_Resync

   function P_Qualified_Simple_Name_Resync return Node_Id is
      Designator_Node : Node_Id;
      Prefix_Node     : Node_Id;
      Selector_Node   : Node_Id;
      Dot_Sloc        : Source_Ptr := No_Location;

   begin
      Prefix_Node := Empty;

      --  Loop through prefixes

      loop
         Designator_Node := Token_Node;

         if Token = Tok_Identifier then
            Scan; -- past identifier
            exit when Token /= Tok_Dot;

         elsif Token not in Token_Class_Desig then
            Discard_Junk_Node (P_Identifier); -- to issue the error message
            raise Error_Resync;

         else
            Scan; -- past designator

            if Token /= Tok_Dot then
               Error_Msg_SP ("identifier expected");
               raise Error_Resync;
            end if;
         end if;

         --  Here at a dot, with token just before it in Designator_Node

         if No (Prefix_Node) then
            Prefix_Node := Designator_Node;
         else
            Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
            Set_Prefix (Selector_Node, Prefix_Node);
            Set_Selector_Name (Selector_Node, Designator_Node);
            Prefix_Node := Selector_Node;
         end if;

         Dot_Sloc := Token_Ptr;
         Scan; -- past period
      end loop;

      --  Fall out of the loop having just scanned an identifier

      if No (Prefix_Node) then
         return Designator_Node;
      else
         Selector_Node := New_Node (N_Selected_Component, Dot_Sloc);
         Set_Prefix (Selector_Node, Prefix_Node);
         Set_Selector_Name (Selector_Node, Designator_Node);
         return Selector_Node;
      end if;
   end P_Qualified_Simple_Name_Resync;

   ----------------------
   -- 4.1  Direct_Name --
   ----------------------

   --  Parsed by P_Name and other functions in section 4.1

   -----------------
   -- 4.1  Prefix --
   -----------------

   --  Parsed by P_Name (4.1)

   -------------------------------
   -- 4.1  Explicit Dereference --
   -------------------------------

   --  Parsed by P_Name (4.1)

   -------------------------------
   -- 4.1  Implicit_Dereference --
   -------------------------------

   --  Parsed by P_Name (4.1)

   ----------------------------
   -- 4.1  Indexed Component --
   ----------------------------

   --  Parsed by P_Name (4.1)

   ----------------
   -- 4.1  Slice --
   ----------------

   --  Parsed by P_Name (4.1)

   -----------------------------
   -- 4.1  Selected_Component --
   -----------------------------

   --  Parsed by P_Name (4.1)

   ------------------------
   -- 4.1  Selector Name --
   ------------------------

   --  Parsed by P_Name (4.1)

   ------------------------------
   -- 4.1  Attribute Reference --
   ------------------------------

   --  Parsed by P_Name (4.1)

   -------------------------------
   -- 4.1  Attribute Designator --
   -------------------------------

   --  Parsed by P_Name (4.1)

   --------------------------------------
   -- 4.1.4  Range Attribute Reference --
   --------------------------------------

   --  RANGE_ATTRIBUTE_REFERENCE ::= PREFIX ' RANGE_ATTRIBUTE_DESIGNATOR

   --  RANGE_ATTRIBUTE_DESIGNATOR ::= range [(static_EXPRESSION)]

   --  In the grammar, a RANGE attribute is simply a name, but its use is
   --  highly restricted, so in the parser, we do not regard it as a name.
   --  Instead, P_Name returns without scanning the 'RANGE part of the
   --  attribute, and the caller uses the following function to construct
   --  a range attribute in places where it is appropriate.

   --  Note that RANGE here is treated essentially as an identifier,
   --  rather than a reserved word.

   --  The caller has parsed the prefix, i.e. a name, and Token points to
   --  the apostrophe. The token after the apostrophe is known to be RANGE
   --  at this point. The prefix node becomes the prefix of the attribute.

   --  Error_Recovery: Cannot raise Error_Resync

   function P_Range_Attribute_Reference
     (Prefix_Node : Node_Id)
      return        Node_Id
   is
      Attr_Node  : Node_Id;

   begin
      Attr_Node := New_Node (N_Attribute_Reference, Token_Ptr);
      Set_Prefix (Attr_Node, Prefix_Node);
      Scan; -- past apostrophe

      if Style_Check then
         Style.Check_Attribute_Name (True);
      end if;

      Set_Attribute_Name (Attr_Node, Name_Range);
      Scan; -- past RANGE

      if Token = Tok_Left_Paren then
         Scan; -- past left paren
         Set_Expressions (Attr_Node, New_List (P_Expression_If_OK));
         T_Right_Paren;
      end if;

      return Attr_Node;
   end P_Range_Attribute_Reference;

   -------------------------------------
   -- P_Reduction_Attribute_Reference --
   -------------------------------------

   function P_Reduction_Attribute_Reference (S : Node_Id)
      return Node_Id
   is
      Attr_Node  : Node_Id;
      Attr_Name  : Name_Id;

   begin
      Attr_Name := Token_Name;
      Scan;   --  past Reduce
      Attr_Node := New_Node (N_Attribute_Reference, Token_Ptr);
      Set_Attribute_Name (Attr_Node, Attr_Name);
      if Attr_Name /= Name_Reduce then
         Error_Msg ("Reduce attribute expected", Prev_Token_Ptr);
      end if;

      Set_Prefix (Attr_Node, S);
      Set_Expressions (Attr_Node, New_List);
      T_Left_Paren;
      Append (P_Name, Expressions (Attr_Node));
      T_Comma;
      Append (P_Expression, Expressions (Attr_Node));
      T_Right_Paren;

      return Attr_Node;
   end P_Reduction_Attribute_Reference;

   ---------------------------------------
   -- 4.1.4  Range Attribute Designator --
   ---------------------------------------

   --  Parsed by P_Range_Attribute_Reference (4.4)

   ---------------------------------------------
   -- 4.1.4 (2) Reduction_Attribute_Reference --
   ---------------------------------------------

   --  parsed by P_Reduction_Attribute_Reference

   --------------------
   -- 4.3  Aggregate --
   --------------------

   --  AGGREGATE ::= RECORD_AGGREGATE | EXTENSION_AGGREGATE | ARRAY_AGGREGATE

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3), except in the case where
   --  an aggregate is known to be required (code statement, extension
   --  aggregate), in which cases this routine performs the necessary check
   --  that we have an aggregate rather than a parenthesized expression

   --  Error recovery: can raise Error_Resync

   function P_Aggregate return Node_Id is
      Aggr_Sloc : constant Source_Ptr := Token_Ptr;
      Aggr_Node : constant Node_Id    := P_Aggregate_Or_Paren_Expr;

   begin
      if Nkind (Aggr_Node) /= N_Aggregate
           and then
         Nkind (Aggr_Node) /= N_Extension_Aggregate
         and then Ada_Version < Ada_2022
      then
         Error_Msg
           ("aggregate may not have single positional component", Aggr_Sloc);
         return Error;
      else
         return Aggr_Node;
      end if;
   end P_Aggregate;

   ------------------------------------------------
   -- 4.3  Aggregate or Parenthesized Expression --
   ------------------------------------------------

   --  This procedure parses out either an aggregate or a parenthesized
   --  expression (these two constructs are closely related, since a
   --  parenthesized expression looks like an aggregate with a single
   --  positional component).

   --  AGGREGATE ::=
   --    RECORD_AGGREGATE | EXTENSION_AGGREGATE | ARRAY_AGGREGATE

   --  RECORD_AGGREGATE ::= (RECORD_COMPONENT_ASSOCIATION_LIST)

   --  RECORD_COMPONENT_ASSOCIATION_LIST ::=
   --     RECORD_COMPONENT_ASSOCIATION {, RECORD_COMPONENT_ASSOCIATION}
   --   | null record

   --  RECORD_COMPONENT_ASSOCIATION ::=
   --    [COMPONENT_CHOICE_LIST =>] EXPRESSION

   --  COMPONENT_CHOICE_LIST ::=
   --    component_SELECTOR_NAME {| component_SELECTOR_NAME}
   --  | others

   --  EXTENSION_AGGREGATE ::=
   --    (ANCESTOR_PART with RECORD_COMPONENT_ASSOCIATION_LIST)

   --  ANCESTOR_PART ::= EXPRESSION | SUBTYPE_MARK

   --  ARRAY_AGGREGATE ::=
   --    POSITIONAL_ARRAY_AGGREGATE | NAMED_ARRAY_AGGREGATE

   --  POSITIONAL_ARRAY_AGGREGATE ::=
   --    (EXPRESSION, EXPRESSION {, EXPRESSION})
   --  | (EXPRESSION {, EXPRESSION}, others => EXPRESSION)
   --  | (EXPRESSION {, EXPRESSION}, others => <>)

   --  NAMED_ARRAY_AGGREGATE ::=
   --    (ARRAY_COMPONENT_ASSOCIATION {, ARRAY_COMPONENT_ASSOCIATION})

   --  PRIMARY ::= (EXPRESSION);

   --  Error recovery: can raise Error_Resync

   --  Note: POSITIONAL_ARRAY_AGGREGATE rule has been extended to give support
   --        to Ada 2005 limited aggregates (AI-287)

   function P_Aggregate_Or_Paren_Expr return Node_Id is
      Aggregate_Node : Node_Id;
      Expr_List      : List_Id;
      Assoc_List     : List_Id;
      Expr_Node      : Node_Id;
      Lparen_Sloc    : Source_Ptr;
      Scan_State     : Saved_Scan_State;

      procedure Box_Error;
      --  Called if <> is encountered as positional aggregate element. Issues
      --  error message and sets Expr_Node to Error.

      function Is_Quantified_Expression return Boolean;
      --  The presence of iterated component associations requires a one
      --  token lookahead to distinguish it from quantified expressions.

      ---------------
      -- Box_Error --
      ---------------

      procedure Box_Error is
      begin
         Error_Msg_Ada_2005_Extension ("'<'> in aggregate");

         --  Ada 2005 (AI-287): The box notation is allowed only with named
         --  notation because positional notation might be error prone. For
         --  example, in "(X, <>, Y, <>)", there is no type associated with
         --  the boxes, so you might not be leaving out the components you
         --  thought you were leaving out.

         Error_Msg_SC ("(Ada 2005) box only allowed with named notation");
         Scan; -- past box
         Expr_Node := Error;
      end Box_Error;

      ------------------------------
      -- Is_Quantified_Expression --
      ------------------------------

      function Is_Quantified_Expression return Boolean is
         Maybe      : Boolean;
         Scan_State : Saved_Scan_State;

      begin
         Save_Scan_State (Scan_State);
         Scan;   --  past FOR
         Maybe := Token = Tok_All or else Token = Tok_Some;
         Restore_Scan_State (Scan_State);  --  to FOR
         return Maybe;
      end Is_Quantified_Expression;

      Start_Token : constant Token_Type := Token;
      --  Used to prevent mismatches (...] and [...)

   --  Start of processing for P_Aggregate_Or_Paren_Expr

   begin
      Lparen_Sloc := Token_Ptr;
      if Token = Tok_Left_Bracket then
         Scan;

         --  Special case for null aggregate in Ada 2022

         if Token = Tok_Right_Bracket then
            Scan;   --  past ]
            Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
            Set_Expressions (Aggregate_Node, New_List);
            Set_Is_Homogeneous_Aggregate (Aggregate_Node);
            return Aggregate_Node;
         end if;
      else
         T_Left_Paren;
      end if;

      --  Note on parentheses count. For cases like an if expression, the
      --  parens here really count as real parentheses for the paren count,
      --  so we adjust the paren count accordingly after scanning the expr.

      --  If expression

      if Token = Tok_If then
         Expr_Node := P_If_Expression;
         T_Right_Paren;
         Set_Paren_Count (Expr_Node, Paren_Count (Expr_Node) + 1);
         return Expr_Node;

      --  Case expression

      elsif Token = Tok_Case then
         Expr_Node := P_Case_Expression;
         T_Right_Paren;
         Set_Paren_Count (Expr_Node, Paren_Count (Expr_Node) + 1);
         return Expr_Node;

      --  Quantified expression

      elsif Token = Tok_For and then Is_Quantified_Expression then
         Expr_Node := P_Quantified_Expression;
         T_Right_Paren;
         Set_Paren_Count (Expr_Node, Paren_Count (Expr_Node) + 1);
         return Expr_Node;

      --  Note: the mechanism used here of rescanning the initial expression
      --  is distinctly unpleasant, but it saves a lot of fiddling in scanning
      --  out the discrete choice list.

      --  Deal with expression and extension aggregates first

      elsif Token /= Tok_Others then
         Save_Scan_State (Scan_State); -- at start of expression

         --  Deal with (NULL RECORD)

         if Token = Tok_Null then
            Scan; -- past NULL

            if Token = Tok_Record then
               Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
               Set_Null_Record_Present (Aggregate_Node, True);
               Scan; -- past RECORD
               T_Right_Paren;
               return Aggregate_Node;
            else
               Restore_Scan_State (Scan_State); -- to NULL that must be expr
            end if;

         elsif Token = Tok_For then
            Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
            Expr_Node := P_Iterated_Component_Association;
            goto Aggregate;
         end if;

         --  Scan expression, handling box appearing as positional argument

         if Token = Tok_Box then
            Box_Error;
         else
            Expr_Node := P_Expression_Or_Range_Attribute_If_OK;
         end if;

         --  Extension or Delta aggregate

         if Token = Tok_With then
            if Nkind (Expr_Node) = N_Attribute_Reference
              and then Attribute_Name (Expr_Node) = Name_Range
            then
               Bad_Range_Attribute (Sloc (Expr_Node));
               return Error;
            end if;

            if Ada_Version = Ada_83 then
               Error_Msg_SC ("(Ada 83) extension aggregate not allowed");
            end if;

            Scan; -- past WITH
            if Token = Tok_Delta then
               Scan; -- past DELTA
               Aggregate_Node := New_Node (N_Delta_Aggregate, Lparen_Sloc);
               Set_Expression (Aggregate_Node, Expr_Node);
               Expr_Node := Empty;

               goto Aggregate;

            else
               Aggregate_Node := New_Node (N_Extension_Aggregate, Lparen_Sloc);
               Set_Ancestor_Part (Aggregate_Node, Expr_Node);
            end if;

            --  Deal with WITH NULL RECORD case

            if Token = Tok_Null then
               Save_Scan_State (Scan_State); -- at NULL
               Scan; -- past NULL

               if Token = Tok_Record then
                  Scan; -- past RECORD
                  Set_Null_Record_Present (Aggregate_Node, True);
                  T_Right_Paren;
                  return Aggregate_Node;

               else
                  Restore_Scan_State (Scan_State); -- to NULL that must be expr
               end if;
            end if;

            if Token /= Tok_Others then
               Save_Scan_State (Scan_State);
               Expr_Node := P_Expression;
            else
               Expr_Node := Empty;
            end if;

         --  Expression

         elsif Token = Tok_Right_Paren or else Token in Token_Class_Eterm then
            if Nkind (Expr_Node) = N_Attribute_Reference
              and then Attribute_Name (Expr_Node) = Name_Range
            then
               Error_Msg
                 ("|parentheses not allowed for range attribute", Lparen_Sloc);
               Scan; -- past right paren
               return Expr_Node;
            end if;

            --  Bump paren count of expression

            if Expr_Node /= Error then
               Set_Paren_Count (Expr_Node, Paren_Count (Expr_Node) + 1);
            end if;

            T_Right_Paren; -- past right paren (error message if none)
            return Expr_Node;

         --  Normal aggregate

         else
            Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
         end if;

      --  Others

      else
         Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
         Expr_Node := Empty;
      end if;

      --  Prepare to scan list of component associations
      <<Aggregate>>
      Expr_List  := No_List; -- don't set yet, maybe all named entries
      Assoc_List := No_List; -- don't set yet, maybe all positional entries

      --  This loop scans through component associations. On entry to the
      --  loop, an expression has been scanned at the start of the current
      --  association unless initial token was OTHERS, in which case
      --  Expr_Node is set to Empty.

      loop
         --  Deal with others association first. This is a named association

         if No (Expr_Node) then
            Append_New (P_Record_Or_Array_Component_Association, Assoc_List);

         --  Improper use of WITH

         elsif Token = Tok_With then
            Error_Msg_SC ("WITH must be preceded by single expression in " &
                          "extension aggregate");
            raise Error_Resync;

         --  Range attribute can only appear as part of a discrete choice list

         elsif Nkind (Expr_Node) = N_Attribute_Reference
           and then Attribute_Name (Expr_Node) = Name_Range
           and then Token /= Tok_Arrow
           and then Token /= Tok_Vertical_Bar
         then
            Bad_Range_Attribute (Sloc (Expr_Node));
            return Error;

         --  Assume positional case if comma, right paren, or literal or
         --  identifier or OTHERS follows (the latter cases are missing
         --  comma cases). Also assume positional if a semicolon follows,
         --  which can happen if there are missing parens.
         --  In Ada 2012 and 2022 an iterated association can appear.

         elsif Nkind (Expr_Node) in
           N_Iterated_Component_Association | N_Iterated_Element_Association
         then
            Append_New (Expr_Node, Assoc_List);

         elsif Token = Tok_Comma
           or else Token = Tok_Right_Paren
           or else Token = Tok_Others
           or else Token in Token_Class_Lit_Or_Name
           or else Token = Tok_Semicolon
         then
            if Present (Assoc_List) then
               Error_Msg_BC -- CODEFIX
                 ("""='>"" expected (positional association cannot follow "
                  & "named association)");
            end if;

            Append_New (Expr_Node, Expr_List);

         --  Check for aggregate followed by left parent, maybe missing comma

         elsif Nkind (Expr_Node) = N_Aggregate
           and then Token = Tok_Left_Paren
         then
            T_Comma;

            Append_New (Expr_Node, Expr_List);

         elsif Token = Tok_Right_Bracket then
            Append_New (Expr_Node, Expr_List);
            exit;

         --  Anything else is assumed to be a named association

         else
            Restore_Scan_State (Scan_State); -- to start of expression

            Append_New (P_Record_Or_Array_Component_Association, Assoc_List);
         end if;

         exit when not Comma_Present;

         --  If we are at an expression terminator, something is seriously
         --  wrong, so let's get out now, before we start eating up stuff
         --  that doesn't belong to us.

         if Token in Token_Class_Eterm and then Token /= Tok_For then
            Error_Msg_AP
              ("expecting expression or component association");
            exit;
         end if;

         --  Deal with misused box

         if Token = Tok_Box then
            Box_Error;

         --  Otherwise initiate for reentry to top of loop by scanning an
         --  initial expression, unless the first token is OTHERS or FOR,
         --  which indicates an iterated component association.

         elsif Token = Tok_Others then
            Expr_Node := Empty;

         elsif Token = Tok_For then
            Expr_Node := P_Iterated_Component_Association;

         else
            Save_Scan_State (Scan_State); -- at start of expression
            Expr_Node := P_Expression_Or_Range_Attribute_If_OK;

         end if;
      end loop;

      --  All component associations (positional and named) have been scanned.
      --  Scan ] or ) based on Start_Token.

      case Start_Token is
         when Tok_Left_Bracket =>
            Set_Component_Associations (Aggregate_Node, Assoc_List);
            Set_Is_Homogeneous_Aggregate (Aggregate_Node);
            T_Right_Bracket;

            if Token = Tok_Apostrophe then
               Scan;

               if Token = Tok_Identifier then
                  return P_Reduction_Attribute_Reference (Aggregate_Node);
               end if;
            end if;
         when Tok_Left_Paren =>
            T_Right_Paren;
         when others => raise Program_Error;
      end case;

      if Nkind (Aggregate_Node) /= N_Delta_Aggregate then
         Set_Expressions (Aggregate_Node, Expr_List);
      end if;

      Set_Component_Associations (Aggregate_Node, Assoc_List);
      return Aggregate_Node;
   end P_Aggregate_Or_Paren_Expr;

   ------------------------------------------------
   -- 4.3  Record or Array Component Association --
   ------------------------------------------------

   --  RECORD_COMPONENT_ASSOCIATION ::=
   --    [COMPONENT_CHOICE_LIST =>] EXPRESSION
   --  | COMPONENT_CHOICE_LIST => <>

   --  COMPONENT_CHOICE_LIST =>
   --    component_SELECTOR_NAME {| component_SELECTOR_NAME}
   --  | others

   --  ARRAY_COMPONENT_ASSOCIATION ::=
   --    DISCRETE_CHOICE_LIST => EXPRESSION
   --  | DISCRETE_CHOICE_LIST => <>
   --  | ITERATED_COMPONENT_ASSOCIATION

   --  Note: this routine only handles the named cases, including others.
   --  Cases where the component choice list is not present have already
   --  been handled directly.

   --  Error recovery: can raise Error_Resync

   --  Note: RECORD_COMPONENT_ASSOCIATION and ARRAY_COMPONENT_ASSOCIATION
   --        rules have been extended to give support to Ada 2005 limited
   --        aggregates (AI-287)

   function P_Record_Or_Array_Component_Association return Node_Id is
      Assoc_Node                  : Node_Id;
      Box_Present                 : Boolean := False;
      Box_With_Identifier_Present : Boolean := False;
   begin
      --  A loop indicates an iterated_component_association

      if Token = Tok_For then
         return P_Iterated_Component_Association;
      end if;

      Assoc_Node := New_Node (N_Component_Association, Token_Ptr);
      Set_Binding_Chars (Assoc_Node, No_Name);

      Set_Choices (Assoc_Node, P_Discrete_Choice_List);
      Set_Sloc (Assoc_Node, Token_Ptr);
      TF_Arrow;

      if Token = Tok_Box then

         --  Ada 2005(AI-287): The box notation is used to indicate the
         --  default initialization of aggregate components

         Error_Msg_Ada_2005_Extension ("component association with '<'>");

         Box_Present := True;
         Set_Box_Present (Assoc_Node);
         Scan; -- past box
      elsif Token = Tok_Less then
         declare
            Scan_State : Saved_Scan_State;
            Id         : Node_Id;
         begin
            Save_Scan_State (Scan_State);
            Scan; -- past "<"
            if Token = Tok_Identifier then
               Id := P_Defining_Identifier;
               if Token = Tok_Greater then
                  if Extensions_Allowed then
                     Set_Box_Present (Assoc_Node);
                     Set_Binding_Chars (Assoc_Node, Chars (Id));
                     Box_Present := True;
                     Box_With_Identifier_Present := True;
                     Scan; -- past ">"
                  else
                     Error_Msg
                       ("Identifier within box only supported under -gnatX",
                        Token_Ptr);
                     Box_Present := True;
                     --  Avoid cascading errors by ignoring the identifier
                  end if;
               end if;
            end if;
            if not Box_Present then
               --  it wasn't an "is <identifier>", so restore.
               Restore_Scan_State (Scan_State);
            end if;
         end;
      end if;

      if not Box_Present then
         Set_Expression (Assoc_Node, P_Expression);
      end if;

      --  Check for "is <identifier>" for aggregate that is part of
      --  a pattern for a general case statement.

      if Token = Tok_Is then
         declare
            Scan_State : Saved_Scan_State;
            Id         : Node_Id;
         begin
            Save_Scan_State (Scan_State);
            Scan; -- past "is"
            if Token = Tok_Identifier then
               Id := P_Defining_Identifier;

               if not Extensions_Allowed then
                  Error_Msg
                    ("IS following component association"
                       & " only supported under -gnatX",
                     Token_Ptr);
               elsif Box_With_Identifier_Present then
                  Error_Msg
                    ("Both identifier-in-box and trailing identifier"
                       & " specified for one component association",
                     Token_Ptr);
               else
                  Set_Binding_Chars (Assoc_Node, Chars (Id));
               end if;
            else
               --  It wasn't an "is <identifier>", so restore.
               Restore_Scan_State (Scan_State);
            end if;
         end;
      end if;

      return Assoc_Node;
   end P_Record_Or_Array_Component_Association;

   -----------------------------
   -- 4.3.1  Record Aggregate --
   -----------------------------

   --  Case of enumeration aggregate is parsed by P_Aggregate (4.3)
   --  All other cases are parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ----------------------------------------------
   -- 4.3.1  Record Component Association List --
   ----------------------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ----------------------------------
   -- 4.3.1  Component Choice List --
   ----------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   --------------------------------
   -- 4.3.1  Extension Aggregate --
   --------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   --------------------------
   -- 4.3.1  Ancestor Part --
   --------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ----------------------------
   -- 4.3.1  Array Aggregate --
   ----------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ---------------------------------------
   -- 4.3.1  Positional Array Aggregate --
   ---------------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ----------------------------------
   -- 4.3.1  Named Array Aggregate --
   ----------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ----------------------------------------
   -- 4.3.1  Array Component Association --
   ----------------------------------------

   --  Parsed by P_Aggregate_Or_Paren_Expr (4.3)

   ---------------------
   -- 4.4  Expression --
   ---------------------

   --  This procedure parses EXPRESSION or CHOICE_EXPRESSION

   --  EXPRESSION ::=
   --    RELATION {LOGICAL_OPERATOR RELATION}

   --  CHOICE_EXPRESSION ::=
   --    CHOICE_RELATION {LOGICAL_OPERATOR CHOICE_RELATION}

   --  LOGICAL_OPERATOR ::= and | and then | or | or else | xor

   --  On return, Expr_Form indicates the categorization of the expression
   --  EF_Range_Attr is not a possible value (if a range attribute is found,
   --  an error message is given, and Error is returned).

   --  Error recovery: cannot raise Error_Resync

   function P_Expression return Node_Id is
      Logical_Op      : Node_Kind;
      Prev_Logical_Op : Node_Kind;
      Op_Location     : Source_Ptr;
      Node1           : Node_Id;
      Node2           : Node_Id;

   begin
      Node1 := P_Relation;

      if Token in Token_Class_Logop then
         Prev_Logical_Op := N_Empty;

         loop
            Op_Location := Token_Ptr;
            Logical_Op := P_Logical_Operator;

            if Prev_Logical_Op /= N_Empty and then
               Logical_Op /= Prev_Logical_Op
            then
               Error_Msg
                 ("mixed logical operators in expression", Op_Location);
               Prev_Logical_Op := N_Empty;
            else
               Prev_Logical_Op := Logical_Op;
            end if;

            Node2 := Node1;
            Node1 := New_Op_Node (Logical_Op, Op_Location);
            Set_Left_Opnd (Node1, Node2);
            Set_Right_Opnd (Node1, P_Relation);

            --  Check for case of errant comma or semicolon

            if Token = Tok_Comma or else Token = Tok_Semicolon then
               declare
                  Com        : constant Boolean := Token = Tok_Comma;
                  Scan_State : Saved_Scan_State;
                  Logop      : Node_Kind;

               begin
                  Save_Scan_State (Scan_State); -- at comma/semicolon
                  Scan; -- past comma/semicolon

                  --  Check for AND THEN or OR ELSE after comma/semicolon. We
                  --  do not deal with AND/OR because those cases get mixed up
                  --  with the select alternatives case.

                  if Token = Tok_And or else Token = Tok_Or then
                     Logop := P_Logical_Operator;
                     Restore_Scan_State (Scan_State); -- to comma/semicolon

                     if Logop in N_And_Then | N_Or_Else then
                        Scan; -- past comma/semicolon

                        if Com then
                           Error_Msg_SP -- CODEFIX
                             ("|extra "","" ignored");
                        else
                           Error_Msg_SP -- CODEFIX
                             ("|extra "";"" ignored");
                        end if;

                     else
                        Restore_Scan_State (Scan_State); -- to comma/semicolon
                     end if;

                  else
                     Restore_Scan_State (Scan_State); -- to comma/semicolon
                  end if;
               end;
            end if;

            exit when Token not in Token_Class_Logop;
         end loop;

         Expr_Form := EF_Non_Simple;
      end if;

      if Token = Tok_Apostrophe then
         Bad_Range_Attribute (Token_Ptr);
         return Error;
      else
         return Node1;
      end if;
   end P_Expression;

   --  This function is identical to the normal P_Expression, except that it
   --  also permits the appearance of a case, conditional, or quantified
   --  expression if the call immediately follows a left paren, and followed
   --  by a right parenthesis. These forms are allowed if these conditions
   --  are not met, but an error message will be issued.

   function P_Expression_If_OK return Node_Id is
   begin
      --  Case of conditional, case or quantified expression

      if Token = Tok_Case
        or else Token = Tok_If
        or else Token = Tok_For
        or else Token = Tok_Declare
      then
         return P_Unparen_Cond_Expr_Etc;

      --  Normal case, not case/conditional/quantified expression

      else
         return P_Expression;
      end if;
   end P_Expression_If_OK;

   --  This function is identical to the normal P_Expression, except that it
   --  checks that the expression scan did not stop on a right paren. It is
   --  called in all contexts where a right parenthesis cannot legitimately
   --  follow an expression.

   --  Error recovery: cannot raise Error_Resync

   function P_Expression_No_Right_Paren return Node_Id is
      Expr : constant Node_Id := P_Expression;
   begin
      Ignore (Tok_Right_Paren);
      return Expr;
   end P_Expression_No_Right_Paren;

   ----------------------------------------
   -- 4.4  Expression_Or_Range_Attribute --
   ----------------------------------------

   --  EXPRESSION ::=
   --    RELATION {and RELATION} | RELATION {and then RELATION}
   --  | RELATION {or RELATION}  | RELATION {or else RELATION}
   --  | RELATION {xor RELATION}

   --  RANGE_ATTRIBUTE_REFERENCE ::= PREFIX ' RANGE_ATTRIBUTE_DESIGNATOR

   --  RANGE_ATTRIBUTE_DESIGNATOR ::= range [(static_EXPRESSION)]

   --  On return, Expr_Form indicates the categorization of the expression
   --  and EF_Range_Attr is one of the possibilities.

   --  Error recovery: cannot raise Error_Resync

   --  In the grammar, a RANGE attribute is simply a name, but its use is
   --  highly restricted, so in the parser, we do not regard it as a name.
   --  Instead, P_Name returns without scanning the 'RANGE part of the
   --  attribute, and P_Expression_Or_Range_Attribute handles the range
   --  attribute reference. In the normal case where a range attribute is
   --  not allowed, an error message is issued by P_Expression.

   function P_Expression_Or_Range_Attribute return Node_Id is
      Logical_Op      : Node_Kind;
      Prev_Logical_Op : Node_Kind;
      Op_Location     : Source_Ptr;
      Node1           : Node_Id;
      Node2           : Node_Id;
      Attr_Node       : Node_Id;

   begin
      Node1 := P_Relation;

      if Token = Tok_Apostrophe then
         Attr_Node := P_Range_Attribute_Reference (Node1);
         Expr_Form := EF_Range_Attr;
         return Attr_Node;

      elsif Token in Token_Class_Logop then
         Prev_Logical_Op := N_Empty;

         loop
            Op_Location := Token_Ptr;
            Logical_Op := P_Logical_Operator;

            if Prev_Logical_Op /= N_Empty and then
               Logical_Op /= Prev_Logical_Op
            then
               Error_Msg
                 ("mixed logical operators in expression", Op_Location);
               Prev_Logical_Op := N_Empty;
            else
               Prev_Logical_Op := Logical_Op;
            end if;

            Node2 := Node1;
            Node1 := New_Op_Node (Logical_Op, Op_Location);
            Set_Left_Opnd (Node1, Node2);
            Set_Right_Opnd (Node1, P_Relation);
            exit when Token not in Token_Class_Logop;
         end loop;

         Expr_Form := EF_Non_Simple;
      end if;

      if Token = Tok_Apostrophe then
         Bad_Range_Attribute (Token_Ptr);
         return Error;
      else
         return Node1;
      end if;
   end P_Expression_Or_Range_Attribute;

   --  Version that allows a non-parenthesized case, conditional, or quantified
   --  expression if the call immediately follows a left paren, and followed
   --  by a right parenthesis. These forms are allowed if these conditions
   --  are not met, but an error message will be issued.

   function P_Expression_Or_Range_Attribute_If_OK return Node_Id is
   begin
      --  Case of conditional, case or quantified expression

      if Token = Tok_Case
        or else Token = Tok_If
        or else Token = Tok_For
        or else Token = Tok_Declare
      then
         return P_Unparen_Cond_Expr_Etc;

      --  Normal case, not one of the above expression types

      else
         return P_Expression_Or_Range_Attribute;
      end if;
   end P_Expression_Or_Range_Attribute_If_OK;

   -------------------
   -- 4.4  Relation --
   -------------------

   --  This procedure scans both relations and choice relations

   --  CHOICE_RELATION ::=
   --    SIMPLE_EXPRESSION [RELATIONAL_OPERATOR SIMPLE_EXPRESSION]

   --  RELATION ::=
   --    SIMPLE_EXPRESSION [not] in MEMBERSHIP_CHOICE_LIST
   --  | RAISE_EXPRESSION

   --  MEMBERSHIP_CHOICE_LIST ::=
   --    MEMBERSHIP_CHOICE {'|' MEMBERSHIP CHOICE}

   --  MEMBERSHIP_CHOICE ::=
   --    CHOICE_EXPRESSION | RANGE | SUBTYPE_MARK

   --  RAISE_EXPRESSION ::= raise exception_NAME [with string_EXPRESSION]

   --  On return, Expr_Form indicates the categorization of the expression

   --  Note: if Token = Tok_Apostrophe on return, then Expr_Form is set to
   --  EF_Simple_Name and the following token is RANGE (range attribute case).

   --  Error recovery: cannot raise Error_Resync. If an error occurs within an
   --  expression, then tokens are scanned until either a non-expression token,
   --  a right paren (not matched by a left paren) or a comma, is encountered.

   function P_Relation return Node_Id is
      Node1, Node2 : Node_Id;
      Optok        : Source_Ptr;

   begin
      --  First check for raise expression

      if Token = Tok_Raise then
         Expr_Form := EF_Non_Simple;
         return P_Raise_Expression;
      end if;

      --  All other cases

      Node1 := P_Simple_Expression;

      if Token not in Token_Class_Relop then
         return Node1;

      else
         --  Here we have a relational operator following. If so then scan it
         --  out. Note that the assignment symbol := is treated as a relational
         --  operator to improve the error recovery when it is misused for =.
         --  P_Relational_Operator also parses the IN and NOT IN operations.

         Optok := Token_Ptr;
         Node2 := New_Op_Node (P_Relational_Operator, Optok);
         Set_Left_Opnd (Node2, Node1);

         --  Case of IN or NOT IN

         if Prev_Token = Tok_In then
            P_Membership_Test (Node2);

         --  Case of relational operator (= /= < <= > >=)

         else
            Set_Right_Opnd (Node2, P_Simple_Expression);
         end if;

         Expr_Form := EF_Non_Simple;

         if Token in Token_Class_Relop then
            Error_Msg_SC ("unexpected relational operator");
            raise Error_Resync;
         end if;

         return Node2;
      end if;

   --  If any error occurs, then scan to the next expression terminator symbol
   --  or comma or right paren at the outer (i.e. current) parentheses level.
   --  The flags are set to indicate a normal simple expression.

   exception
      when Error_Resync =>
         Resync_Expression;
         Expr_Form := EF_Simple;
         return Error;
   end P_Relation;

   ----------------------------
   -- 4.4  Simple Expression --
   ----------------------------

   --  SIMPLE_EXPRESSION ::=
   --    [UNARY_ADDING_OPERATOR] TERM {BINARY_ADDING_OPERATOR TERM}

   --  On return, Expr_Form indicates the categorization of the expression

   --  Note: if Token = Tok_Apostrophe on return, then Expr_Form is set to
   --  EF_Simple_Name and the following token is RANGE (range attribute case).

   --  Error recovery: cannot raise Error_Resync. If an error occurs within an
   --  expression, then tokens are scanned until either a non-expression token,
   --  a right paren (not matched by a left paren) or a comma, is encountered.

   --  Note: P_Simple_Expression is called only internally by higher level
   --  expression routines. In cases in the grammar where a simple expression
   --  is required, the approach is to scan an expression, and then post an
   --  appropriate error message if the expression obtained is not simple. This
   --  gives better error recovery and treatment.

   function P_Simple_Expression return Node_Id is
      Scan_State : Saved_Scan_State;
      Node1      : Node_Id;
      Node2      : Node_Id;
      Tokptr     : Source_Ptr;

      function At_Start_Of_Attribute return Boolean;
      --  Tests if we have quote followed by attribute name, if so, return True
      --  otherwise return False.

      ---------------------------
      -- At_Start_Of_Attribute --
      ---------------------------

      function At_Start_Of_Attribute return Boolean is
      begin
         if Token /= Tok_Apostrophe then
            return False;

         else
            declare
               Scan_State : Saved_Scan_State;

            begin
               Save_Scan_State (Scan_State);
               Scan; -- past quote

               if Token = Tok_Identifier
                 and then Is_Attribute_Name (Chars (Token_Node))
               then
                  Restore_Scan_State (Scan_State);
                  return True;
               else
                  Restore_Scan_State (Scan_State);
                  return False;
               end if;
            end;
         end if;
      end At_Start_Of_Attribute;

   --  Start of processing for P_Simple_Expression

   begin
      --  Check for cases starting with a name. There are two reasons for
      --  special casing. First speed things up by catching a common case
      --  without going through several routine layers. Second the caller must
      --  be informed via Expr_Form when the simple expression is a name.

      if Token in Token_Class_Name then
         Node1 := P_Name;

         --  Deal with apostrophe cases

         if Token = Tok_Apostrophe then
            Save_Scan_State (Scan_State); -- at apostrophe
            Scan; -- past apostrophe

            --  If qualified expression, scan it out and fall through

            if Token = Tok_Left_Paren then
               Node1 := P_Qualified_Expression (Node1);
               Expr_Form := EF_Simple;

            --  If range attribute, then we return with Token pointing to the
            --  apostrophe. Note: avoid the normal error check on exit. We
            --  know that the expression really is complete in this case.

            else -- Token = Tok_Range then
               Restore_Scan_State (Scan_State); -- to apostrophe
               Expr_Form := EF_Simple_Name;
               return Node1;
            end if;
         end if;

         --  If an expression terminator follows, the previous processing
         --  completely scanned out the expression (a common case), and
         --  left Expr_Form set appropriately for returning to our caller.

         if Token in Token_Class_Sterm then
            null;

         --  If we do not have an expression terminator, then complete the
         --  scan of a simple expression. This code duplicates the code
         --  found in P_Term and P_Factor.

         else
            if Token = Tok_Double_Asterisk then
               if Style_Check then
                  Style.Check_Exponentiation_Operator;
               end if;

               Node2 := New_Op_Node (N_Op_Expon, Token_Ptr);
               Scan; -- past **
               Set_Left_Opnd (Node2, Node1);
               Set_Right_Opnd (Node2, P_Primary);
               Check_Bad_Exp;
               Node1 := Node2;
            end if;

            loop
               exit when Token not in Token_Class_Mulop;
               Tokptr := Token_Ptr;
               Node2 := New_Op_Node (P_Multiplying_Operator, Tokptr);

               if Style_Check then
                  Style.Check_Binary_Operator;
               end if;

               Scan; -- past operator
               Set_Left_Opnd (Node2, Node1);
               Set_Right_Opnd (Node2, P_Factor);
               Node1 := Node2;
            end loop;

            loop
               exit when Token not in Token_Class_Binary_Addop;
               Tokptr := Token_Ptr;
               Node2 := New_Op_Node (P_Binary_Adding_Operator, Tokptr);

               if Style_Check then
                  Style.Check_Binary_Operator;
               end if;

               Scan; -- past operator
               Set_Left_Opnd (Node2, Node1);
               Set_Right_Opnd (Node2, P_Term);
               Node1 := Node2;
            end loop;

            Expr_Form := EF_Simple;
         end if;

      --  Cases where simple expression does not start with a name

      else
         --  Scan initial sign and initial Term

         if Token in Token_Class_Unary_Addop then
            Tokptr := Token_Ptr;
            Node1 := New_Op_Node (P_Unary_Adding_Operator, Tokptr);

            if Style_Check then
               Style.Check_Unary_Plus_Or_Minus (Inside_Depends);
            end if;

            Scan; -- past operator
            Set_Right_Opnd (Node1, P_Term);
         else
            Node1 := P_Term;
         end if;

         --  In the following, we special-case a sequence of concatenations of
         --  string literals, such as "aaa" & "bbb" & ... & "ccc", with nothing
         --  else mixed in. For such a sequence, we return a tree representing
         --  "" & "aaabbb...ccc" (a single concatenation). This is done only if
         --  the number of concatenations is large. If semantic analysis
         --  resolves the "&" to a predefined one, then this folding gives the
         --  right answer. Otherwise, semantic analysis will complain about a
         --  capacity-exceeded error. The purpose of this trick is to avoid
         --  creating a deeply nested tree, which would cause deep recursion
         --  during semantics, causing stack overflow. This way, we can handle
         --  enormous concatenations in the normal case of predefined "&". We
         --  first build up the normal tree, and then rewrite it if
         --  appropriate.

         declare
            Num_Concats_Threshold : constant Positive := 1000;
            --  Arbitrary threshold value to enable optimization

            First_Node : constant Node_Id := Node1;
            Is_Strlit_Concat : Boolean;
            --  True iff we've parsed a sequence of concatenations of string
            --  literals, with nothing else mixed in.

            Num_Concats : Natural;
            --  Number of "&" operators if Is_Strlit_Concat is True

         begin
            Is_Strlit_Concat :=
              Nkind (Node1) = N_String_Literal
                and then Token = Tok_Ampersand;
            Num_Concats := 0;

            --  Scan out sequence of terms separated by binary adding operators

            loop
               exit when Token not in Token_Class_Binary_Addop;
               Tokptr := Token_Ptr;
               Node2 := New_Op_Node (P_Binary_Adding_Operator, Tokptr);

               if Style_Check and then not Debug_Flag_Dot_QQ then
                  Style.Check_Binary_Operator;
               end if;

               Scan; -- past operator
               Set_Left_Opnd (Node2, Node1);
               Node1 := P_Term;
               Set_Right_Opnd (Node2, Node1);

               --  Check if we're still concatenating string literals

               Is_Strlit_Concat :=
                 Is_Strlit_Concat
                   and then Nkind (Node2) = N_Op_Concat
                 and then Nkind (Node1) = N_String_Literal;

               if Is_Strlit_Concat then
                  Num_Concats := Num_Concats + 1;
               end if;

               Node1 := Node2;
            end loop;

            --  If we have an enormous series of concatenations of string
            --  literals, rewrite as explained above. The Is_Folded_In_Parser
            --  flag tells semantic analysis that if the "&" is not predefined,
            --  the folded value is wrong.

            if Is_Strlit_Concat
              and then Num_Concats >= Num_Concats_Threshold
            then
               declare
                  Empty_String_Val : String_Id;
                  --  String_Id for ""

                  Strlit_Concat_Val : String_Id;
                  --  Contains the folded value (which will be correct if the
                  --  "&" operators are the predefined ones).

                  Cur_Node : Node_Id;
                  --  For walking up the tree

                  New_Node : Node_Id;
                  --  Folded node to replace Node1

                  Loc : constant Source_Ptr := Sloc (First_Node);

               begin
                  --  Walk up the tree starting at the leftmost string literal
                  --  (First_Node), building up the Strlit_Concat_Val as we
                  --  go. Note that we do not use recursion here -- the whole
                  --  point is to avoid recursively walking that enormous tree.

                  Start_String;
                  Store_String_Chars (Strval (First_Node));

                  Cur_Node := Parent (First_Node);
                  while Present (Cur_Node) loop
                     pragma Assert (Nkind (Cur_Node) = N_Op_Concat and then
                        Nkind (Right_Opnd (Cur_Node)) = N_String_Literal);

                     Store_String_Chars (Strval (Right_Opnd (Cur_Node)));
                     Cur_Node := Parent (Cur_Node);
                  end loop;

                  Strlit_Concat_Val := End_String;

                  --  Create new folded node, and rewrite result with a concat-
                  --  enation of an empty string literal and the folded node.

                  Start_String;
                  Empty_String_Val := End_String;
                  New_Node :=
                    Make_Op_Concat (Loc,
                      Make_String_Literal (Loc, Empty_String_Val),
                      Make_String_Literal (Loc, Strlit_Concat_Val,
                        Is_Folded_In_Parser => True));
                  Rewrite (Node1, New_Node);
               end;
            end if;
         end;

         --  All done, we clearly do not have name or numeric literal so this
         --  is a case of a simple expression which is some other possibility.

         Expr_Form := EF_Simple;
      end if;

      --  Come here at end of simple expression, where we do a couple of
      --  special checks to improve error recovery.

      --  Special test to improve error recovery. If the current token is a
      --  period, then someone is trying to do selection on something that is
      --  not a name, e.g. a qualified expression.

      if Token = Tok_Dot then
         Error_Msg_SC ("prefix for selection is not a name");

         --  If qualified expression, comment and continue, otherwise something
         --  is pretty nasty so do an Error_Resync call.

         if Ada_Version < Ada_2012
           and then Nkind (Node1) = N_Qualified_Expression
         then
            Error_Msg_SC ("\would be legal in Ada 2012 mode");
         else
            raise Error_Resync;
         end if;
      end if;

      --  Special test to improve error recovery: If the current token is
      --  not the first token on a line (as determined by checking the
      --  previous token position with the start of the current line),
      --  then we insist that we have an appropriate terminating token.
      --  Consider the following two examples:

      --   1)  if A nad B then ...

      --   2)  A := B
      --       C := D

      --  In the first example, we would like to issue a binary operator
      --  expected message and resynchronize to the then. In the second
      --  example, we do not want to issue a binary operator message, so
      --  that instead we will get the missing semicolon message. This
      --  distinction is of course a heuristic which does not always work,
      --  but in practice it is quite effective.

      --  Note: the one case in which we do not go through this circuit is
      --  when we have scanned a range attribute and want to return with
      --  Token pointing to the apostrophe. The apostrophe is not normally
      --  an expression terminator, and is not in Token_Class_Sterm, but
      --  in this special case we know that the expression is complete.

      if not Token_Is_At_Start_Of_Line
         and then Token not in Token_Class_Sterm
      then
         --  Normally the right error message is indeed that we expected a
         --  binary operator, but in the case of being between a right and left
         --  paren, e.g. in an aggregate, a more likely error is missing comma.

         if Prev_Token = Tok_Right_Paren and then Token = Tok_Left_Paren then
            T_Comma;

         --  And if we have a quote, we may have a bad attribute

         elsif At_Start_Of_Attribute then
            Error_Msg_SC ("prefix of attribute must be a name");

            if Ada_Version >= Ada_2012 then
               Error_Msg_SC ("\qualify expression to turn it into a name");
            end if;

         --  Normal case for binary operator expected message

         else
            Error_Msg_AP ("binary operator expected");
         end if;

         raise Error_Resync;

      else
         return Node1;
      end if;

   --  If any error occurs, then scan to next expression terminator symbol
   --  or comma, right paren or vertical bar at the outer (i.e. current) paren
   --  level. Expr_Form is set to indicate a normal simple expression.

   exception
      when Error_Resync =>
         Resync_Expression;
         Expr_Form := EF_Simple;
         return Error;
   end P_Simple_Expression;

   -----------------------------------------------
   -- 4.4  Simple Expression or Range Attribute --
   -----------------------------------------------

   --  SIMPLE_EXPRESSION ::=
   --    [UNARY_ADDING_OPERATOR] TERM {BINARY_ADDING_OPERATOR TERM}

   --  RANGE_ATTRIBUTE_REFERENCE ::= PREFIX ' RANGE_ATTRIBUTE_DESIGNATOR

   --  RANGE_ATTRIBUTE_DESIGNATOR ::= range [(static_EXPRESSION)]

   --  Error recovery: cannot raise Error_Resync

   function P_Simple_Expression_Or_Range_Attribute return Node_Id is
      Sexpr     : Node_Id;
      Attr_Node : Node_Id;

   begin
      --  We don't just want to roar ahead and call P_Simple_Expression
      --  here, since we want to handle the case of a parenthesized range
      --  attribute cleanly.

      if Token = Tok_Left_Paren then
         declare
            Lptr       : constant Source_Ptr := Token_Ptr;
            Scan_State : Saved_Scan_State;

         begin
            Save_Scan_State (Scan_State);
            Scan; -- past left paren
            Sexpr := P_Simple_Expression;

            if Token = Tok_Apostrophe then
               Attr_Node := P_Range_Attribute_Reference (Sexpr);
               Expr_Form := EF_Range_Attr;

               if Token = Tok_Right_Paren then
                  Scan; -- scan past right paren if present
               end if;

               Error_Msg ("parentheses not allowed for range attribute", Lptr);

               return Attr_Node;
            end if;

            Restore_Scan_State (Scan_State);
         end;
      end if;

      --  Here after dealing with parenthesized range attribute

      Sexpr := P_Simple_Expression;

      if Token = Tok_Apostrophe then
         Attr_Node := P_Range_Attribute_Reference (Sexpr);
         Expr_Form := EF_Range_Attr;
         return Attr_Node;

      else
         return Sexpr;
      end if;
   end P_Simple_Expression_Or_Range_Attribute;

   ---------------
   -- 4.4  Term --
   ---------------

   --  TERM ::= FACTOR {MULTIPLYING_OPERATOR FACTOR}

   --  Error recovery: can raise Error_Resync

   function P_Term return Node_Id is
      Node1, Node2 : Node_Id;
      Tokptr       : Source_Ptr;

   begin
      Node1 := P_Factor;

      loop
         exit when Token not in Token_Class_Mulop;
         Tokptr := Token_Ptr;
         Node2 := New_Op_Node (P_Multiplying_Operator, Tokptr);

         if Style_Check and then not Debug_Flag_Dot_QQ then
            Style.Check_Binary_Operator;
         end if;

         Scan; -- past operator
         Set_Left_Opnd (Node2, Node1);
         Set_Right_Opnd (Node2, P_Factor);
         Node1 := Node2;
      end loop;

      return Node1;
   end P_Term;

   -----------------
   -- 4.4  Factor --
   -----------------

   --  FACTOR ::= PRIMARY [** PRIMARY] | abs PRIMARY | not PRIMARY

   --  Error recovery: can raise Error_Resync

   function P_Factor return Node_Id is
      Node1 : Node_Id;
      Node2 : Node_Id;

   begin
      if Token = Tok_Abs then
         Node1 := New_Op_Node (N_Op_Abs, Token_Ptr);

         if Style_Check then
            Style.Check_Abs_Not;
         end if;

         Scan; -- past ABS
         Set_Right_Opnd (Node1, P_Primary);
         return Node1;

      elsif Token = Tok_Not then
         Node1 := New_Op_Node (N_Op_Not, Token_Ptr);

         if Style_Check then
            Style.Check_Abs_Not;
         end if;

         Scan; -- past NOT
         Set_Right_Opnd (Node1, P_Primary);
         return Node1;

      else
         Node1 := P_Primary;

         if Token = Tok_Double_Asterisk then
            Node2 := New_Op_Node (N_Op_Expon, Token_Ptr);
            Scan; -- past **
            Set_Left_Opnd (Node2, Node1);
            Set_Right_Opnd (Node2, P_Primary);
            Check_Bad_Exp;
            return Node2;
         else
            return Node1;
         end if;
      end if;
   end P_Factor;

   ------------------
   -- 4.4  Primary --
   ------------------

   --  PRIMARY ::=
   --    NUMERIC_LITERAL  | null
   --  | STRING_LITERAL   | AGGREGATE
   --  | NAME             | QUALIFIED_EXPRESSION
   --  | ALLOCATOR        | (EXPRESSION) | QUANTIFIED_EXPRESSION
   --  | REDUCTION_ATTRIBUTE_REFERENCE

   --  Error recovery: can raise Error_Resync

   function P_Primary return Node_Id is
      Scan_State : Saved_Scan_State;
      Node1      : Node_Id;

      Lparen : constant Boolean := Prev_Token = Tok_Left_Paren;
      --  Remember if previous token is a left parenthesis. This is used to
      --  deal with checking whether IF/CASE/FOR expressions appearing as
      --  primaries require extra parenthesization.

   begin
      --  The loop runs more than once only if misplaced pragmas are found
      --  or if a misplaced unary minus is skipped.

      loop
         case Token is

            --  Name token can start a name, call or qualified expression, all
            --  of which are acceptable possibilities for primary. Note also
            --  that string literal is included in name (as operator symbol)
            --  and type conversion is included in name (as indexed component).

            when Tok_Char_Literal
               | Tok_Identifier
               | Tok_Operator_Symbol
            =>
               Node1 := P_Name;

               --  All done unless apostrophe follows

               if Token /= Tok_Apostrophe then
                  return Node1;

               --  Apostrophe following means that we have either just parsed
               --  the subtype mark of a qualified expression, or the prefix
               --  or a range attribute.

               else -- Token = Tok_Apostrophe
                  Save_Scan_State (Scan_State); -- at apostrophe
                  Scan; -- past apostrophe

                  --  If range attribute, then this is always an error, since
                  --  the only legitimate case (where the scanned expression is
                  --  a qualified simple name) is handled at the level of the
                  --  Simple_Expression processing. This case corresponds to a
                  --  usage such as 3 + A'Range, which is always illegal.

                  if Token = Tok_Range then
                     Restore_Scan_State (Scan_State); -- to apostrophe
                     Bad_Range_Attribute (Token_Ptr);
                     return Error;

                  --  If left paren, then we have a qualified expression.
                  --  Note that P_Name guarantees that in this case, where
                  --  Token = Tok_Apostrophe on return, the only two possible
                  --  tokens following the apostrophe are left paren and
                  --  RANGE, so we know we have a left paren here.

                  else -- Token = Tok_Left_Paren
                     return P_Qualified_Expression (Node1);

                  end if;
               end if;

            --  Numeric or string literal

            when Tok_Integer_Literal
               | Tok_Real_Literal
               | Tok_String_Literal
            =>
               Node1 := Token_Node;
               Scan; -- past number
               return Node1;

            --  Left paren, starts aggregate or parenthesized expression

            when Tok_Left_Paren =>
               declare
                  Expr : constant Node_Id := P_Aggregate_Or_Paren_Expr;

               begin
                  if Nkind (Expr) = N_Attribute_Reference
                    and then Attribute_Name (Expr) = Name_Range
                  then
                     Bad_Range_Attribute (Sloc (Expr));
                  end if;

                  return Expr;
               end;

            when Tok_Left_Bracket =>
               return P_Aggregate;

            --  Allocator

            when Tok_New =>
               return P_Allocator;

            --  Null

            when Tok_Null =>
               Scan; -- past NULL
               return New_Node (N_Null, Prev_Token_Ptr);

            --  Pragma, not allowed here, so just skip past it

            when Tok_Pragma =>
               P_Pragmas_Misplaced;

            --  Deal with IF (possible unparenthesized if expression)

            when Tok_If =>

               --  If this looks like a real if, defined as an IF appearing at
               --  the start of a new line, then we consider we have a missing
               --  operand. If in Ada 2012 and the IF is not properly indented
               --  for a statement, we prefer to issue a message about an ill-
               --  parenthesized if expression.

               if Token_Is_At_Start_Of_Line
                 and then not
                   (Ada_Version >= Ada_2012
                     and then Style_Check_Indentation /= 0
                     and then Start_Column rem Style_Check_Indentation /= 0)
               then
                  Error_Msg_AP ("missing operand");
                  return Error;

               --  If this looks like an if expression, then treat it that way
               --  with an error message if not explicitly surrounded by
               --  parentheses.

               elsif Ada_Version >= Ada_2012 then
                  Node1 := P_If_Expression;

                  if not (Lparen and then Token = Tok_Right_Paren) then
                     Error_Msg
                       ("if expression must be parenthesized", Sloc (Node1));
                  end if;

                  return Node1;

               --  Otherwise treat as misused identifier

               else
                  return P_Identifier;
               end if;

            --  Deal with CASE (possible unparenthesized case expression)

            when Tok_Case =>

               --  If this looks like a real case, defined as a CASE appearing
               --  the start of a new line, then we consider we have a missing
               --  operand. If in Ada 2012 and the CASE is not properly
               --  indented for a statement, we prefer to issue a message about
               --  an ill-parenthesized case expression.

               if Token_Is_At_Start_Of_Line
                 and then not
                   (Ada_Version >= Ada_2012
                     and then Style_Check_Indentation /= 0
                     and then Start_Column rem Style_Check_Indentation /= 0)
               then
                  Error_Msg_AP ("missing operand");
                  return Error;

               --  If this looks like a case expression, then treat it that way
               --  with an error message if not within parentheses.

               elsif Ada_Version >= Ada_2012 then
                  Node1 := P_Case_Expression;

                  if not (Lparen and then Token = Tok_Right_Paren) then
                     Error_Msg
                       ("case expression must be parenthesized", Sloc (Node1));
                  end if;

                  return Node1;

               --  Otherwise treat as misused identifier

               else
                  return P_Identifier;
               end if;

            --  For [all | some]  indicates a quantified expression

            when Tok_For =>
               if Token_Is_At_Start_Of_Line then
                  Error_Msg_AP ("misplaced loop");
                  return Error;

               elsif Ada_Version >= Ada_2012 then
                  Save_Scan_State (Scan_State);
                  Scan;   --  past FOR

                  if Token = Tok_All or else Token = Tok_Some  then
                     Restore_Scan_State (Scan_State);  -- To FOR
                     Node1 := P_Quantified_Expression;

                     if not (Lparen and then Token = Tok_Right_Paren) then
                        Error_Msg
                          ("quantified expression must be parenthesized",
                           Sloc (Node1));
                     end if;
                  else
                     Restore_Scan_State (Scan_State);  -- To FOR
                     Node1 := P_Iterated_Component_Association;
                  end if;

                  return Node1;

               --  Otherwise treat as misused identifier

               else
                  return P_Identifier;
               end if;

            --  Minus may well be an improper attempt at a unary minus. Give
            --  a message, skip the minus and keep going.

            when Tok_Minus =>
               Error_Msg_SC ("parentheses required for unary minus");
               Scan; -- past minus

            when Tok_At_Sign =>  --  AI12-0125 : target_name
               Error_Msg_Ada_2022_Feature ("target name", Token_Ptr);

               Node1 := P_Name;
               return Node1;

            --  Anything else is illegal as the first token of a primary, but
            --  we test for some common errors, to improve error messages.

            when others =>
               if Is_Reserved_Identifier then
                  return P_Identifier;

               elsif Prev_Token = Tok_Comma then
                  Error_Msg_SP -- CODEFIX
                    ("|extra "","" ignored");
                  raise Error_Resync;

               else
                  Error_Msg_AP ("missing operand");
                  raise Error_Resync;
               end if;
         end case;
      end loop;
   end P_Primary;

   -------------------------------
   -- 4.4 Quantified_Expression --
   -------------------------------

   --  QUANTIFIED_EXPRESSION ::=
   --    for QUANTIFIER LOOP_PARAMETER_SPECIFICATION => PREDICATE |
   --    for QUANTIFIER ITERATOR_SPECIFICATION => PREDICATE

   function P_Quantified_Expression return Node_Id is
      I_Spec : Node_Id;
      Node1  : Node_Id;

   begin
      Error_Msg_Ada_2012_Feature ("quantified expression", Token_Ptr);
      Scan;  --  past FOR
      Node1 := New_Node (N_Quantified_Expression, Prev_Token_Ptr);

      if Token = Tok_All then
         Set_All_Present (Node1);
      elsif Token /= Tok_Some then
         Error_Msg_AP ("missing quantifier");
         raise Error_Resync;
      end if;

      Scan; -- past ALL or SOME
      I_Spec := P_Loop_Parameter_Specification;

      if Nkind (I_Spec) = N_Loop_Parameter_Specification then
         Set_Loop_Parameter_Specification (Node1, I_Spec);
      else
         Set_Iterator_Specification (Node1, I_Spec);
      end if;

      if Token = Tok_Arrow then
         Scan;
         Set_Condition (Node1, P_Expression);
         return Node1;
      else
         Error_Msg_AP ("missing arrow");
         raise Error_Resync;
      end if;
   end P_Quantified_Expression;

   ---------------------------
   -- 4.5  Logical Operator --
   ---------------------------

   --  LOGICAL_OPERATOR  ::=  and | or | xor

   --  Note: AND THEN and OR ELSE are also treated as logical operators
   --  by the parser (even though they are not operators semantically)

   --  The value returned is the appropriate Node_Kind code for the operator
   --  On return, Token points to the token following the scanned operator.

   --  The caller has checked that the first token is a legitimate logical
   --  operator token (i.e. is either XOR, AND, OR).

   --  Error recovery: cannot raise Error_Resync

   function P_Logical_Operator return Node_Kind is
   begin
      if Token = Tok_And then
         if Style_Check then
            Style.Check_Binary_Operator;
         end if;

         Scan; -- past AND

         if Token = Tok_Then then
            Scan; -- past THEN
            return N_And_Then;
         else
            return N_Op_And;
         end if;

      elsif Token = Tok_Or then
         if Style_Check then
            Style.Check_Binary_Operator;
         end if;

         Scan; -- past OR

         if Token = Tok_Else then
            Scan; -- past ELSE
            return N_Or_Else;
         else
            return N_Op_Or;
         end if;

      else -- Token = Tok_Xor
         if Style_Check then
            Style.Check_Binary_Operator;
         end if;

         Scan; -- past XOR
         return N_Op_Xor;
      end if;
   end P_Logical_Operator;

   ------------------------------
   -- 4.5  Relational Operator --
   ------------------------------

   --  RELATIONAL_OPERATOR ::= = | /= | < | <= | > | >=

   --  The value returned is the appropriate Node_Kind code for the operator.
   --  On return, Token points to the operator token, NOT past it.

   --  The caller has checked that the first token is a legitimate relational
   --  operator token (i.e. is one of the operator tokens listed above).

   --  Error recovery: cannot raise Error_Resync

   function P_Relational_Operator return Node_Kind is
      Op_Kind : Node_Kind;
      Relop_Node : constant array (Token_Class_Relop) of Node_Kind :=
                     (Tok_Less          => N_Op_Lt,
                      Tok_Equal         => N_Op_Eq,
                      Tok_Greater       => N_Op_Gt,
                      Tok_Not_Equal     => N_Op_Ne,
                      Tok_Greater_Equal => N_Op_Ge,
                      Tok_Less_Equal    => N_Op_Le,
                      Tok_In            => N_In,
                      Tok_Not           => N_Not_In,
                      Tok_Box           => N_Op_Ne);

   begin
      if Token = Tok_Box then
         Error_Msg_SC -- CODEFIX
           ("|""'<'>"" should be ""/=""");
      end if;

      Op_Kind := Relop_Node (Token);

      if Style_Check then
         Style.Check_Binary_Operator;
      end if;

      Scan; -- past operator token

      --  Deal with NOT IN, if previous token was NOT, we must have IN now

      if Prev_Token = Tok_Not then

         --  Style check, for NOT IN, we require one space between NOT and IN

         if Style_Check and then Token = Tok_In then
            Style.Check_Not_In;
         end if;

         T_In;
      end if;

      return Op_Kind;
   end P_Relational_Operator;

   ---------------------------------
   -- 4.5  Binary Adding Operator --
   ---------------------------------

   --  BINARY_ADDING_OPERATOR ::= + | - | &

   --  The value returned is the appropriate Node_Kind code for the operator.
   --  On return, Token points to the operator token (NOT past it).

   --  The caller has checked that the first token is a legitimate adding
   --  operator token (i.e. is one of the operator tokens listed above).

   --  Error recovery: cannot raise Error_Resync

   function P_Binary_Adding_Operator return Node_Kind is
      Addop_Node : constant array (Token_Class_Binary_Addop) of Node_Kind :=
                     (Tok_Ampersand => N_Op_Concat,
                      Tok_Minus     => N_Op_Subtract,
                      Tok_Plus      => N_Op_Add);
   begin
      return Addop_Node (Token);
   end P_Binary_Adding_Operator;

   --------------------------------
   -- 4.5  Unary Adding Operator --
   --------------------------------

   --  UNARY_ADDING_OPERATOR ::= + | -

   --  The value returned is the appropriate Node_Kind code for the operator.
   --  On return, Token points to the operator token (NOT past it).

   --  The caller has checked that the first token is a legitimate adding
   --  operator token (i.e. is one of the operator tokens listed above).

   --  Error recovery: cannot raise Error_Resync

   function P_Unary_Adding_Operator return Node_Kind is
      Addop_Node : constant array (Token_Class_Unary_Addop) of Node_Kind :=
                     (Tok_Minus => N_Op_Minus,
                      Tok_Plus  => N_Op_Plus);
   begin
      return Addop_Node (Token);
   end P_Unary_Adding_Operator;

   -------------------------------
   -- 4.5  Multiplying Operator --
   -------------------------------

   --  MULTIPLYING_OPERATOR ::= * | / | mod | rem

   --  The value returned is the appropriate Node_Kind code for the operator.
   --  On return, Token points to the operator token (NOT past it).

   --  The caller has checked that the first token is a legitimate multiplying
   --  operator token (i.e. is one of the operator tokens listed above).

   --  Error recovery: cannot raise Error_Resync

   function P_Multiplying_Operator return Node_Kind is
      Mulop_Node : constant array (Token_Class_Mulop) of Node_Kind :=
        (Tok_Asterisk       => N_Op_Multiply,
         Tok_Mod            => N_Op_Mod,
         Tok_Rem            => N_Op_Rem,
         Tok_Slash          => N_Op_Divide);
   begin
      return Mulop_Node (Token);
   end P_Multiplying_Operator;

   --------------------------------------
   -- 4.5  Highest Precedence Operator --
   --------------------------------------

   --  Parsed by P_Factor (4.4)

   --  Note: this rule is not in fact used by the grammar at any point

   --------------------------
   -- 4.6  Type Conversion --
   --------------------------

   --  Parsed by P_Primary as a Name (4.1)

   -------------------------------
   -- 4.7  Qualified Expression --
   -------------------------------

   --  QUALIFIED_EXPRESSION ::=
   --    SUBTYPE_MARK ' (EXPRESSION) | SUBTYPE_MARK ' AGGREGATE

   --  The caller has scanned the name which is the Subtype_Mark parameter
   --  and scanned past the single quote following the subtype mark. The
   --  caller has not checked that this name is in fact appropriate for
   --  a subtype mark name (i.e. it is a selected component or identifier).

   --  Error_Recovery: cannot raise Error_Resync

   function P_Qualified_Expression (Subtype_Mark : Node_Id) return Node_Id is
      Qual_Node : Node_Id;
   begin
      Qual_Node := New_Node (N_Qualified_Expression, Prev_Token_Ptr);
      Set_Subtype_Mark (Qual_Node, Check_Subtype_Mark (Subtype_Mark));
      Set_Expression (Qual_Node, P_Aggregate_Or_Paren_Expr);
      return Qual_Node;
   end P_Qualified_Expression;

   --------------------
   -- 4.8  Allocator --
   --------------------

   --  ALLOCATOR ::=
   --      new [SUBPOOL_SPECIFICATION] SUBTYPE_INDICATION
   --    | new [SUBPOOL_SPECIFICATION] QUALIFIED_EXPRESSION
   --
   --  SUBPOOL_SPECIFICATION ::= (subpool_handle_NAME)

   --  The caller has checked that the initial token is NEW

   --  Error recovery: can raise Error_Resync

   function P_Allocator return Node_Id is
      Alloc_Node             : Node_Id;
      Type_Node              : Node_Id;
      Null_Exclusion_Present : Boolean;

   begin
      Alloc_Node := New_Node (N_Allocator, Token_Ptr);
      T_New;

      --  Scan subpool_specification if present (Ada 2012 (AI05-0111-3))

      --  Scan Null_Exclusion if present (Ada 2005 (AI-231))

      if Token = Tok_Left_Paren then
         Scan; -- past (
         Set_Subpool_Handle_Name (Alloc_Node, P_Name);
         T_Right_Paren;

         Error_Msg_Ada_2012_Feature
           ("|subpool specification",
            Sloc (Subpool_Handle_Name (Alloc_Node)));
      end if;

      Null_Exclusion_Present := P_Null_Exclusion;
      Set_Null_Exclusion_Present (Alloc_Node, Null_Exclusion_Present);
      Type_Node := P_Subtype_Mark_Resync;

      if Token = Tok_Apostrophe then
         Scan; -- past apostrophe
         Set_Expression (Alloc_Node, P_Qualified_Expression (Type_Node));
      else
         Set_Expression
           (Alloc_Node,
            P_Subtype_Indication (Type_Node, Null_Exclusion_Present));

         --  AI05-0104: An explicit null exclusion is not allowed for an
         --  allocator without initialization. In previous versions of the
         --  language it just raises constraint error.

         if Ada_Version >= Ada_2012 and then Null_Exclusion_Present then
            Error_Msg_N
              ("an allocator with a subtype indication "
               & "cannot have a null exclusion", Alloc_Node);
         end if;
      end if;

      return Alloc_Node;
   end P_Allocator;

   -----------------------
   -- P_Case_Expression --
   -----------------------

   function P_Case_Expression return Node_Id is
      Loc        : constant Source_Ptr := Token_Ptr;
      Case_Node  : Node_Id;
      Save_State : Saved_Scan_State;

   begin
      Error_Msg_Ada_2012_Feature ("|case expression", Token_Ptr);
      Scan; -- past CASE
      Case_Node :=
        Make_Case_Expression (Loc,
          Expression   => P_Expression_No_Right_Paren,
          Alternatives => New_List);
      T_Is;

      --  We now have scanned out CASE expression IS, scan alternatives

      loop
         T_When;
         Append_To (Alternatives (Case_Node), P_Case_Expression_Alternative);

         --  Missing comma if WHEN (more alternatives present)

         if Token = Tok_When then
            T_Comma;

         --  A semicolon followed by "when" is probably meant to be a comma

         elsif Token = Tok_Semicolon then
            Save_Scan_State (Save_State);
            Scan; -- past the semicolon

            if Token /= Tok_When then
               Restore_Scan_State (Save_State);
               exit;
            end if;

            Error_Msg_SP -- CODEFIX
              ("|"";"" should be "",""");

         --  If comma/WHEN, skip comma and we have another alternative

         elsif Token = Tok_Comma then
            Save_Scan_State (Save_State);
            Scan; -- past comma

            if Token /= Tok_When then
               Restore_Scan_State (Save_State);
               exit;
            end if;

         --  If no comma or WHEN, definitely done

         else
            exit;
         end if;
      end loop;

      --  If we have an END CASE, diagnose as not needed

      if Token = Tok_End then
         Error_Msg_SC ("`END CASE` not allowed at end of case expression");
         Scan; -- past END

         if Token = Tok_Case then
            Scan; -- past CASE;
         end if;
      end if;

      --  Return the Case_Expression node

      return Case_Node;
   end P_Case_Expression;

   -----------------------------------
   -- P_Case_Expression_Alternative --
   -----------------------------------

   --  CASE_STATEMENT_ALTERNATIVE ::=
   --    when DISCRETE_CHOICE_LIST =>
   --      EXPRESSION

   --  The caller has checked that and scanned past the initial WHEN token
   --  Error recovery: can raise Error_Resync

   function P_Case_Expression_Alternative return Node_Id is
      Case_Alt_Node : Node_Id;
   begin
      Case_Alt_Node := New_Node (N_Case_Expression_Alternative, Token_Ptr);
      Set_Discrete_Choices (Case_Alt_Node, P_Discrete_Choice_List);
      TF_Arrow;
      Set_Expression (Case_Alt_Node, P_Expression);
      return Case_Alt_Node;
   end P_Case_Expression_Alternative;

   --------------------------------------
   -- P_Iterated_Component_Association --
   --------------------------------------

   --  ITERATED_COMPONENT_ASSOCIATION ::=
   --    for DEFINING_IDENTIFIER in DISCRETE_CHOICE_LIST => EXPRESSION
   --    for ITERATOR_SPECIFICATION => EXPRESSION

   function P_Iterated_Component_Association return Node_Id is
      Assoc_Node : Node_Id;
      Choice     : Node_Id;
      Filter     : Node_Id := Empty;
      Id         : Node_Id;
      Iter_Spec  : Node_Id;
      Loop_Spec  : Node_Id;
      State      : Saved_Scan_State;

      procedure Build_Iterated_Element_Association;
      --  If the iterator includes a key expression or a filter, it is
      --  an Ada 2022 Iterator_Element_Association within a container
      --  aggregate.

      ----------------------------------------
      -- Build_Iterated_Element_Association --
      ----------------------------------------

      procedure Build_Iterated_Element_Association is
      begin
         --  Build loop_parameter_specification

         Loop_Spec :=
           New_Node (N_Loop_Parameter_Specification, Prev_Token_Ptr);
         Set_Defining_Identifier (Loop_Spec, Id);

         Choice :=  First (Discrete_Choices (Assoc_Node));
         Assoc_Node :=
           New_Node (N_Iterated_Element_Association, Prev_Token_Ptr);
         Set_Loop_Parameter_Specification (Assoc_Node, Loop_Spec);

         if Present (Next (Choice)) then
            Error_Msg_N ("expect loop parameter specification", Choice);
         end if;

         Remove (Choice);
         Set_Discrete_Subtype_Definition (Loop_Spec, Choice);
         Set_Iterator_Filter (Loop_Spec, Filter);
      end Build_Iterated_Element_Association;

   --  Start of processing for P_Iterated_Component_Association

   begin
      Scan;  --  past FOR
      Save_Scan_State (State);

      --  A lookahead is necessary to differentiate between the
      --  Ada 2012 form with a choice list, and the Ada 2022 element
      --  iterator form, recognized by the presence of "OF". Other
      --  disambiguation requires context and is done during semantic
      --  analysis. Note that "for X in E" is syntactically ambiguous:
      --  if E is a subtype indication this is a loop parameter spec,
      --  while if E a name it is an iterator_specification, and the
      --  disambiguation takes place during semantic analysis.
      --  In addition, if "use" is present after the specification,
      --  this is an Iterated_Element_Association that carries a
      --  key_expression, and we generate the appropriate node.
      --  Finally, the Iterated_Element form is reserved for container
      --  aggregates, and is illegal in array aggregates.

      Id := P_Defining_Identifier;
      Assoc_Node :=
        New_Node (N_Iterated_Component_Association, Prev_Token_Ptr);

      if Token = Tok_In then
         Set_Defining_Identifier (Assoc_Node, Id);
         T_In;
         Set_Discrete_Choices (Assoc_Node, P_Discrete_Choice_List);

         --  The iterator may include a filter

         if Token = Tok_When then
            Scan;    -- past WHEN
            Filter := P_Condition;
         end if;

         if Token = Tok_Use then

            --  Ada 2022 Key-expression is present, rewrite node as an
            --  Iterated_Element_Association.

            Scan;  --  past USE
            Build_Iterated_Element_Association;
            Set_Key_Expression (Assoc_Node, P_Expression);

         elsif Present (Filter) then
            --  A loop_parameter_specification also indicates an Ada 2022
            --  construct, in contrast with a subtype indication used in
            --  array aggregates.

            Build_Iterated_Element_Association;
         end if;

         TF_Arrow;
         Set_Expression (Assoc_Node, P_Expression);

      elsif Ada_Version >= Ada_2022
        and then Token = Tok_Of
      then
         Restore_Scan_State (State);
         Scan;  -- past OF
         Set_Defining_Identifier (Assoc_Node, Id);
         Iter_Spec := P_Iterator_Specification (Id);
         Set_Iterator_Specification (Assoc_Node, Iter_Spec);

         if Token = Tok_Use then
            Scan;  -- past USE
            --  This is an iterated_element_association

            Assoc_Node :=
              New_Node (N_Iterated_Element_Association, Prev_Token_Ptr);
            Set_Iterator_Specification (Assoc_Node, Iter_Spec);
            Set_Key_Expression (Assoc_Node, P_Expression);
         end if;

         TF_Arrow;
         Set_Expression (Assoc_Node, P_Expression);
      end if;

      Error_Msg_Ada_2022_Feature ("iterated component", Token_Ptr);

      return Assoc_Node;
   end P_Iterated_Component_Association;

   ---------------------
   -- P_If_Expression --
   ---------------------

   --  IF_EXPRESSION ::=
   --    if CONDITION then DEPENDENT_EXPRESSION
   --                {elsif CONDITION then DEPENDENT_EXPRESSION}
   --                [else DEPENDENT_EXPRESSION]

   --  DEPENDENT_EXPRESSION ::= EXPRESSION

   function P_If_Expression return Node_Id is
      function P_If_Expression_Internal
        (Loc  : Source_Ptr;
         Cond : Node_Id) return Node_Id;
      --  This is the internal recursive routine that does all the work, it is
      --  recursive since it is used to process ELSIF parts, which internally
      --  are N_If_Expression nodes with the Is_Elsif flag set. The calling
      --  sequence is like the outer function except that the caller passes
      --  the conditional expression (scanned using P_Expression), and the
      --  scan pointer points just past this expression. Loc points to the
      --  IF or ELSIF token.

      ------------------------------
      -- P_If_Expression_Internal --
      ------------------------------

      function P_If_Expression_Internal
        (Loc  : Source_Ptr;
         Cond : Node_Id) return Node_Id
      is
         Exprs : constant List_Id := New_List;
         Expr  : Node_Id;
         State : Saved_Scan_State;
         Eptr  : Source_Ptr;

      begin
         --  All cases except where we are at right paren

         if Token /= Tok_Right_Paren then
            TF_Then;
            Append_To (Exprs, P_Condition (Cond));
            Append_To (Exprs, P_Expression);

         --  Case of right paren (missing THEN phrase). Note that we know this
         --  is the IF case, since the caller dealt with this possibility in
         --  the ELSIF case.

         else
            Error_Msg_BC ("missing THEN phrase");
            Append_To (Exprs, P_Condition (Cond));
         end if;

         --  We now have scanned out IF expr THEN expr

         --  Check for common error of semicolon before the ELSE

         if Token = Tok_Semicolon then
            Save_Scan_State (State);
            Scan; -- past semicolon

            if Token = Tok_Else or else Token = Tok_Elsif then
               Error_Msg_SP -- CODEFIX
                 ("|extra "";"" ignored");

            else
               Restore_Scan_State (State);
            end if;
         end if;

         --  Scan out ELSIF sequence if present

         if Token = Tok_Elsif then
            Eptr := Token_Ptr;
            Scan; -- past ELSIF
            Expr := P_Expression;

            --  If we are at a right paren, we assume the ELSIF should be ELSE

            if Token = Tok_Right_Paren then
               Error_Msg ("ELSIF should be ELSE", Eptr);
               Append_To (Exprs, Expr);

            --  Otherwise we have an OK ELSIF

            else
               Expr := P_If_Expression_Internal (Eptr, Expr);
               Set_Is_Elsif (Expr);
               Append_To (Exprs, Expr);
            end if;

         --  Scan out ELSE phrase if present

         elsif Token = Tok_Else then

            --  Scan out ELSE expression

            Scan; -- Past ELSE
            Append_To (Exprs, P_Expression);

            --  Skip redundant ELSE parts

            while Token = Tok_Else loop
               Error_Msg_SC ("only one ELSE part is allowed");
               Scan; -- past ELSE
               Discard_Junk_Node (P_Expression);
            end loop;

         --  Two expression case (implied True, filled in during semantics)

         else
            null;
         end if;

         --  If we have an END IF, diagnose as not needed

         if Token = Tok_End then
            Error_Msg_SC ("`END IF` not allowed at end of if expression");
            Scan; -- past END

            if Token = Tok_If then
               Scan; -- past IF;
            end if;
         end if;

         --  Return the If_Expression node

         return Make_If_Expression (Loc, Expressions => Exprs);
      end P_If_Expression_Internal;

   --  Local variables

      Loc     : constant Source_Ptr := Token_Ptr;
      If_Expr : Node_Id;

   --  Start of processing for P_If_Expression

   begin
      Error_Msg_Ada_2012_Feature ("|if expression", Token_Ptr);
      Scan; -- past IF
      Inside_If_Expression := Inside_If_Expression + 1;
      If_Expr := P_If_Expression_Internal (Loc, P_Expression);
      Inside_If_Expression := Inside_If_Expression - 1;
      return If_Expr;
   end P_If_Expression;

   --------------------------
   -- P_Declare_Expression --
   --------------------------

   --  DECLARE_EXPRESSION ::=
   --      DECLARE {DECLARE_ITEM}
   --      begin BODY_EXPRESSION

   --  DECLARE_ITEM ::= OBJECT_DECLARATION
   --  | OBJECT_RENAMING_DECLARATION

   function P_Declare_Expression return Node_Id is
      Loc : constant Source_Ptr := Token_Ptr;
   begin
      Scan; -- past DECLARE

      declare
         Actions : constant List_Id := P_Basic_Declarative_Items
           (Declare_Expression => True);
         --  Most declarative items allowed by P_Basic_Declarative_Items are
         --  illegal; semantic analysis will deal with that.
      begin
         if Token = Tok_Begin then
            Scan;
         else
            Error_Msg_SC -- CODEFIX
              ("BEGIN expected!");
         end if;

         declare
            Expression : constant Node_Id := P_Expression;
            Result : constant Node_Id :=
              Make_Expression_With_Actions (Loc, Actions, Expression);
         begin
            Error_Msg_Ada_2022_Feature ("declare expression", Loc);

            return Result;
         end;
      end;
   end P_Declare_Expression;

   -----------------------
   -- P_Membership_Test --
   -----------------------

   --  MEMBERSHIP_CHOICE_LIST ::= MEMBERSHIP_CHOICE {'|' MEMBERSHIP_CHOICE}
   --  MEMBERSHIP_CHOICE      ::= CHOICE_EXPRESSION | range | subtype_mark

   procedure P_Membership_Test (N : Node_Id) is
      Alt : constant Node_Id :=
              P_Range_Or_Subtype_Mark
                (Allow_Simple_Expression => (Ada_Version >= Ada_2012));

   begin
      --  Set case

      if Token = Tok_Vertical_Bar then
         Error_Msg_Ada_2012_Feature ("set notation", Token_Ptr);
         Set_Alternatives (N, New_List (Alt));
         Set_Right_Opnd   (N, Empty);

         --  Loop to accumulate alternatives

         while Token = Tok_Vertical_Bar loop
            Scan; -- past vertical bar
            Append_To
              (Alternatives (N),
               P_Range_Or_Subtype_Mark (Allow_Simple_Expression => True));
         end loop;

      --  Not set case

      else
         Set_Right_Opnd   (N, Alt);
         Set_Alternatives (N, No_List);
      end if;
   end P_Membership_Test;

   -----------------------------
   -- P_Unparen_Cond_Expr_Etc --
   -----------------------------

   function P_Unparen_Cond_Expr_Etc return Node_Id is
      Lparen : constant Boolean := Prev_Token = Tok_Left_Paren;

      Result     : Node_Id;
      Scan_State : Saved_Scan_State;

   begin
      --  Case expression

      if Token = Tok_Case then
         Result := P_Case_Expression;

         if not (Lparen and then Token = Tok_Right_Paren) then
            Error_Msg_N ("case expression must be parenthesized!", Result);
         end if;

      --  If expression

      elsif Token = Tok_If then
         Result := P_If_Expression;

         if not (Lparen and then Token = Tok_Right_Paren) then
            Error_Msg_N ("if expression must be parenthesized!", Result);
         end if;

      --  Quantified expression or iterated component association

      elsif Token = Tok_For then

         Save_Scan_State (Scan_State);
         Scan;  --  past FOR

         if Token = Tok_All or else Token = Tok_Some then
            Restore_Scan_State (Scan_State);
            Result := P_Quantified_Expression;

            if not (Lparen and then Token = Tok_Right_Paren) then
               Error_Msg_N
                 ("quantified expression must be parenthesized!", Result);
            end if;

         else
            --  If no quantifier keyword, this is an iterated component in
            --  an aggregate.

            Restore_Scan_State (Scan_State);
            Result := P_Iterated_Component_Association;
         end if;

      --  Declare expression

      elsif Token = Tok_Declare then
         Result := P_Declare_Expression;

         if not (Lparen and then Token = Tok_Right_Paren) then
            Error_Msg_N ("declare expression must be parenthesized!", Result);
         end if;

      --  No other possibility should exist (caller was supposed to check)

      else
         raise Program_Error;
      end if;

      --  Return expression (possibly after having given message)

      return Result;
   end P_Unparen_Cond_Expr_Etc;

end Ch4;
