OSDN Git Service

* 1aexcept.adb, 1aexcept.ads, 1ic.ads, 1ssecsta.adb,
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch5.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 5                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2001, Free Software Foundation, Inc.         --
10 --                                                                          --
11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
12 -- terms of the  GNU General Public License as published  by the Free Soft- --
13 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
17 -- for  more details.  You should have  received  a copy of the GNU General --
18 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 pragma Style_Checks (All_Checks);
28 --  Turn off subprogram body ordering check. Subprograms are in order
29 --  by RM section rather than alphabetical
30
31 separate (Par)
32 package body Ch5 is
33
34    --  Local functions, used only in this chapter
35
36    function P_Case_Statement                     return Node_Id;
37    function P_Case_Statement_Alternative         return Node_Id;
38    function P_Condition                          return Node_Id;
39    function P_Exit_Statement                     return Node_Id;
40    function P_Goto_Statement                     return Node_Id;
41    function P_If_Statement                       return Node_Id;
42    function P_Label                              return Node_Id;
43    function P_Loop_Parameter_Specification       return Node_Id;
44    function P_Null_Statement                     return Node_Id;
45
46    function P_Assignment_Statement (LHS : Node_Id)  return Node_Id;
47    --  Parse assignment statement. On entry, the caller has scanned the left
48    --  hand side (passed in as Lhs), and the colon-equal (or some symbol
49    --  taken to be an error equivalent such as equal).
50
51    function P_Begin_Statement (Block_Name : Node_Id := Empty) return Node_Id;
52    --  Parse begin-end statement. If Block_Name is non-Empty on entry, it is
53    --  the N_Identifier node for the label on the block. If Block_Name is
54    --  Empty on entry (the default), then the block statement is unlabeled.
55
56    function P_Declare_Statement (Block_Name : Node_Id := Empty) return Node_Id;
57    --  Parse declare block. If Block_Name is non-Empty on entry, it is
58    --  the N_Identifier node for the label on the block. If Block_Name is
59    --  Empty on entry (the default), then the block statement is unlabeled.
60
61    function P_For_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
62    --  Parse for statement. If Loop_Name is non-Empty on entry, it is
63    --  the N_Identifier node for the label on the loop. If Loop_Name is
64    --  Empty on entry (the default), then the for statement is unlabeled.
65
66    function P_Loop_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
67    --  Parse loop statement. If Loop_Name is non-Empty on entry, it is
68    --  the N_Identifier node for the label on the loop. If Loop_Name is
69    --  Empty on entry (the default), then the loop statement is unlabeled.
70
71    function P_While_Statement (Loop_Name : Node_Id := Empty) return Node_Id;
72    --  Parse while statement. If Loop_Name is non-Empty on entry, it is
73    --  the N_Identifier node for the label on the loop. If Loop_Name is
74    --  Empty on entry (the default), then the while statement is unlabeled.
75
76    function Set_Loop_Block_Name (L : Character) return Name_Id;
77    --  Given a letter 'L' for a loop or 'B' for a block, returns a name
78    --  of the form L_nn or B_nn where nn is a serial number obtained by
79    --  incrementing the variable Loop_Block_Count.
80
81    procedure Then_Scan;
82    --  Scan past THEN token, testing for illegal junk after it
83
84    ---------------------------------
85    -- 5.1  Sequence of Statements --
86    ---------------------------------
87
88    --  SEQUENCE_OF_STATEMENTS ::= STATEMENT {STATEMENT}
89
90    --  STATEMENT ::=
91    --    {LABEL} SIMPLE_STATEMENT | {LABEL} COMPOUND_STATEMENT
92
93    --  SIMPLE_STATEMENT ::=      NULL_STATEMENT
94    --  | ASSIGNMENT_STATEMENT  | EXIT_STATEMENT
95    --  | GOTO_STATEMENT        | PROCEDURE_CALL_STATEMENT
96    --  | RETURN_STATEMENT      | ENTRY_CALL_STATEMENT
97    --  | REQUEUE_STATEMENT     | DELAY_STATEMENT
98    --  | ABORT_STATEMENT       | RAISE_STATEMENT
99    --  | CODE_STATEMENT
100
101    --  COMPOUND_STATEMENT ::=
102    --    IF_STATEMENT         | CASE_STATEMENT
103    --  | LOOP_STATEMENT       | BLOCK_STATEMENT
104    --  | ACCEPT_STATEMENT     | SELECT_STATEMENT
105
106    --  This procedure scans a sequence of statements. The caller sets SS_Flags
107    --  to indicate acceptable termination conditions for the sequence:
108
109    --    SS_Flags.Eftm Terminate on ELSIF
110    --    SS_Flags.Eltm Terminate on ELSE
111    --    SS_Flags.Extm Terminate on EXCEPTION
112    --    SS_Flags.Ortm Terminate on OR
113    --    SS_Flags.Tatm Terminate on THEN ABORT (Token = ABORT on return)
114    --    SS_Flags.Whtm Terminate on WHEN
115    --    SS_Flags.Unco Unconditional terminate after scanning one statement
116
117    --  In addition, the scan is always terminated by encountering END or the
118    --  end of file (EOF) condition. If one of the six above terminators is
119    --  encountered with the corresponding SS_Flags flag not set, then the
120    --  action taken is as follows:
121
122    --    If the keyword occurs to the left of the expected column of the end
123    --    for the current sequence (as recorded in the current end context),
124    --    then it is assumed to belong to an outer context, and is considered
125    --    to terminate the sequence of statements.
126
127    --    If the keyword occurs to the right of, or in the expected column of
128    --    the end for the current sequence, then an error message is output,
129    --    the keyword together with its associated context is skipped, and
130    --    the statement scan continues until another terminator is found.
131
132    --  Note that the first action means that control can return to the caller
133    --  with Token set to a terminator other than one of those specified by the
134    --  SS parameter. The caller should treat such a case as equivalent to END.
135
136    --  In addition, the flag SS_Flags.Sreq is set to True to indicate that at
137    --  least one real statement (other than a pragma) is required in the
138    --  statement sequence. During the processing of the sequence, this
139    --  flag is manipulated to indicate the current status of the requirement
140    --  for a statement. For example, it is turned off by the occurrence of a
141    --  statement, and back on by a label (which requires a following statement)
142
143    --  Error recovery: cannot raise Error_Resync. If an error occurs during
144    --  parsing a statement, then the scan pointer is advanced past the next
145    --  semicolon and the parse continues.
146
147    function P_Sequence_Of_Statements (SS_Flags : SS_Rec) return List_Id is
148
149       Statement_Required : Boolean;
150       --  This flag indicates if a subsequent statement (other than a pragma)
151       --  is required. It is initialized from the Sreq flag, and modified as
152       --  statements are scanned (a statement turns it off, and a label turns
153       --  it back on again since a statement must follow a label).
154
155       Declaration_Found : Boolean := False;
156       --  This flag is set True if a declaration is encountered, so that the
157       --  error message about declarations in the statement part is only
158       --  given once for a given sequence of statements.
159
160       Scan_State_Label : Saved_Scan_State;
161       Scan_State       : Saved_Scan_State;
162
163       Statement_List : List_Id;
164       Block_Label    : Name_Id;
165       Id_Node        : Node_Id;
166       Name_Node      : Node_Id;
167
168       procedure Junk_Declaration;
169       --  Procedure called to handle error of declaration encountered in
170       --  statement sequence.
171
172       procedure Test_Statement_Required;
173       --  Flag error if Statement_Required flag set
174
175       procedure Junk_Declaration is
176       begin
177          if (not Declaration_Found) or All_Errors_Mode then
178             Error_Msg_SC ("declarations must come before BEGIN");
179             Declaration_Found := True;
180          end if;
181
182          Skip_Declaration (Statement_List);
183       end Junk_Declaration;
184
185       procedure Test_Statement_Required is
186       begin
187          if Statement_Required then
188             Error_Msg_BC ("statement expected");
189          end if;
190       end Test_Statement_Required;
191
192    --  Start of processing for P_Sequence_Of_Statements
193
194    begin
195       Statement_List := New_List;
196       Statement_Required := SS_Flags.Sreq;
197
198       loop
199          while Token = Tok_Semicolon loop
200             Error_Msg_SC ("unexpected semicolon ignored");
201             Scan; -- past junk semicolon
202          end loop;
203
204          begin
205             if Style_Check then Style.Check_Indentation; end if;
206
207             --  Deal with reserved identifier (in assignment or call)
208
209             if Is_Reserved_Identifier then
210                Save_Scan_State (Scan_State); -- at possible bad identifier
211                Scan; -- and scan past it
212
213                --  We have an reserved word which is spelled in identifier
214                --  style, so the question is whether it really is intended
215                --  to be an identifier.
216
217                if
218                   --  If followed by a semicolon, then it is an identifier,
219                   --  with the exception of the cases tested for below.
220
221                   (Token = Tok_Semicolon
222                     and then Prev_Token /= Tok_Return
223                     and then Prev_Token /= Tok_Null
224                     and then Prev_Token /= Tok_Raise
225                     and then Prev_Token /= Tok_End
226                     and then Prev_Token /= Tok_Exit)
227
228                   --  If followed by colon, colon-equal, or dot, then we
229                   --  definitely  have an identifier (could not be reserved)
230
231                   or else Token = Tok_Colon
232                   or else Token = Tok_Colon_Equal
233                   or else Token = Tok_Dot
234
235                   --  Left paren means we have an identifier except for those
236                   --  reserved words that can legitimately be followed by a
237                   --  left paren.
238
239                   or else
240                     (Token = Tok_Left_Paren
241                       and then Prev_Token /= Tok_Case
242                       and then Prev_Token /= Tok_Delay
243                       and then Prev_Token /= Tok_If
244                       and then Prev_Token /= Tok_Elsif
245                       and then Prev_Token /= Tok_Return
246                       and then Prev_Token /= Tok_When
247                       and then Prev_Token /= Tok_While
248                       and then Prev_Token /= Tok_Separate)
249                then
250                   --  Here we have an apparent reserved identifier and the
251                   --  token past it is appropriate to this usage (and would
252                   --  be a definite error if this is not an identifier). What
253                   --  we do is to use P_Identifier to fix up the identifier,
254                   --  and then fall into the normal processing.
255
256                   Restore_Scan_State (Scan_State); -- back to the ID
257                   Scan_Reserved_Identifier (Force_Msg => False);
258
259                   --  Not a reserved identifier after all (or at least we can't
260                   --  be sure that it is), so reset the scan and continue.
261
262                else
263                   Restore_Scan_State (Scan_State); -- back to the reserved word
264                end if;
265             end if;
266
267             --  Now look to see what kind of statement we have
268
269             case Token is
270
271                --  Case of end or EOF
272
273                when Tok_End | Tok_EOF =>
274
275                   --  These tokens always terminate the statement sequence
276
277                   Test_Statement_Required;
278                   exit;
279
280                --  Case of ELSIF
281
282                when Tok_Elsif =>
283
284                   --  Terminate if Eftm set or if the ELSIF is to the left
285                   --  of the expected column of the end for this sequence
286
287                   if SS_Flags.Eftm
288                      or else Start_Column < Scope.Table (Scope.Last).Ecol
289                   then
290                      Test_Statement_Required;
291                      exit;
292
293                   --  Otherwise complain and skip past ELSIF Condition then
294
295                   else
296                      Error_Msg_SC ("ELSIF not allowed here");
297                      Scan; -- past ELSIF
298                      Discard_Junk_Node (P_Expression_No_Right_Paren);
299                      Then_Scan;
300                      Statement_Required := False;
301                   end if;
302
303                --  Case of ELSE
304
305                when Tok_Else =>
306
307                   --  Terminate if Eltm set or if the else is to the left
308                   --  of the expected column of the end for this sequence
309
310                   if SS_Flags.Eltm
311                      or else Start_Column < Scope.Table (Scope.Last).Ecol
312                   then
313                      Test_Statement_Required;
314                      exit;
315
316                   --  Otherwise complain and skip past else
317
318                   else
319                      Error_Msg_SC ("ELSE not allowed here");
320                      Scan; -- past ELSE
321                      Statement_Required := False;
322                   end if;
323
324                --  Case of exception
325
326                when Tok_Exception =>
327                   Test_Statement_Required;
328
329                   --  If Extm not set and the exception is not to the left
330                   --  of the expected column of the end for this sequence, then
331                   --  we assume it belongs to the current sequence, even though
332                   --  it is not permitted.
333
334                   if not SS_Flags.Extm and then
335                      Start_Column >= Scope.Table (Scope.Last).Ecol
336
337                   then
338                      Error_Msg_SC ("exception handler not permitted here");
339                      Scan; -- past EXCEPTION
340                      Discard_Junk_List (Parse_Exception_Handlers);
341                   end if;
342
343                   --  Always return, in the case where we scanned out handlers
344                   --  that we did not expect, Parse_Exception_Handlers returned
345                   --  with Token being either end or EOF, so we are OK
346
347                   exit;
348
349                --  Case of OR
350
351                when Tok_Or =>
352
353                   --  Terminate if Ortm set or if the or is to the left
354                   --  of the expected column of the end for this sequence
355
356                   if SS_Flags.Ortm
357                      or else Start_Column < Scope.Table (Scope.Last).Ecol
358                   then
359                      Test_Statement_Required;
360                      exit;
361
362                   --  Otherwise complain and skip past or
363
364                   else
365                      Error_Msg_SC ("OR not allowed here");
366                      Scan; -- past or
367                      Statement_Required := False;
368                   end if;
369
370                --  Case of THEN (deal also with THEN ABORT)
371
372                when Tok_Then =>
373                   Save_Scan_State (Scan_State); -- at THEN
374                   Scan; -- past THEN
375
376                   --  Terminate if THEN ABORT allowed (ATC case)
377
378                   exit when SS_Flags.Tatm and then Token = Tok_Abort;
379
380                   --  Otherwise we treat THEN as some kind of mess where we
381                   --  did not see the associated IF, but we pick up assuming
382                   --  it had been there!
383
384                   Restore_Scan_State (Scan_State); -- to THEN
385                   Append_To (Statement_List, P_If_Statement);
386                   Statement_Required := False;
387
388                --  Case of WHEN (error because we are not in a case)
389
390                when Tok_When | Tok_Others =>
391
392                   --  Terminate if Whtm set or if the WHEN is to the left
393                   --  of the expected column of the end for this sequence
394
395                   if SS_Flags.Whtm
396                      or else Start_Column < Scope.Table (Scope.Last).Ecol
397                   then
398                      Test_Statement_Required;
399                      exit;
400
401                   --  Otherwise complain and skip when Choice {| Choice} =>
402
403                   else
404                      Error_Msg_SC ("WHEN not allowed here");
405                      Scan; -- past when
406                      Discard_Junk_List (P_Discrete_Choice_List);
407                      TF_Arrow;
408                      Statement_Required := False;
409                   end if;
410
411                --  Cases of statements starting with an identifier
412
413                when Tok_Identifier =>
414                   Check_Bad_Layout;
415
416                   --  Save scan pointers and line number in case block label
417
418                   Id_Node := Token_Node;
419                   Block_Label := Token_Name;
420                   Save_Scan_State (Scan_State_Label); -- at possible label
421                   Scan; -- past Id
422
423                   --  Check for common case of assignment, since it occurs
424                   --  frequently, and we want to process it efficiently.
425
426                   if Token = Tok_Colon_Equal then
427                      Scan; -- past the colon-equal
428                      Append_To (Statement_List,
429                        P_Assignment_Statement (Id_Node));
430                      Statement_Required := False;
431
432                   --  Check common case of procedure call, another case that
433                   --  we want to speed up as much as possible.
434
435                   elsif Token = Tok_Semicolon then
436                      Append_To (Statement_List,
437                        P_Statement_Name (Id_Node));
438                      Scan; -- past semicolon
439                      Statement_Required := False;
440
441                   --  Check for case of "go to" in place of "goto"
442
443                   elsif Token = Tok_Identifier
444                     and then Block_Label = Name_Go
445                     and then Token_Name = Name_To
446                   then
447                      Error_Msg_SP ("goto is one word");
448                      Append_To (Statement_List, P_Goto_Statement);
449                      Statement_Required := False;
450
451                   --  Check common case of = used instead of :=, just so we
452                   --  give a better error message for this special misuse.
453
454                   elsif Token = Tok_Equal then
455                      T_Colon_Equal; -- give := expected message
456                      Append_To (Statement_List,
457                        P_Assignment_Statement (Id_Node));
458                      Statement_Required := False;
459
460                   --  Check case of loop label or block label
461
462                   elsif Token = Tok_Colon
463                     or else (Token in Token_Class_Labeled_Stmt
464                               and then not Token_Is_At_Start_Of_Line)
465                   then
466                      T_Colon; -- past colon (if there, or msg for missing one)
467
468                      --  Test for more than one label
469
470                      loop
471                         exit when Token /= Tok_Identifier;
472                         Save_Scan_State (Scan_State); -- at second Id
473                         Scan; -- past Id
474
475                         if Token = Tok_Colon then
476                            Error_Msg_SP
477                               ("only one label allowed on block or loop");
478                            Scan; -- past colon on extra label
479
480                            --  Use the second label as the "real" label
481
482                            Scan_State_Label := Scan_State;
483
484                            --  We will set Error_name as the Block_Label since
485                            --  we really don't know which of the labels might
486                            --  be used at the end of the loop or block!
487
488                            Block_Label := Error_Name;
489
490                         --  If Id with no colon, then backup to point to the
491                         --  Id and we will issue the message below when we try
492                         --  to scan out the statement as some other form.
493
494                         else
495                            Restore_Scan_State (Scan_State); -- to second Id
496                            exit;
497                         end if;
498                      end loop;
499
500                      --  Loop_Statement (labeled Loop_Statement)
501
502                      if Token = Tok_Loop then
503                         Append_To (Statement_List,
504                           P_Loop_Statement (Id_Node));
505
506                      --  While statement (labeled loop statement with WHILE)
507
508                      elsif Token = Tok_While then
509                         Append_To (Statement_List,
510                           P_While_Statement (Id_Node));
511
512                      --  Declare statement (labeled block statement with
513                      --  DECLARE part)
514
515                      elsif Token = Tok_Declare then
516                         Append_To (Statement_List,
517                           P_Declare_Statement (Id_Node));
518
519                      --  Begin statement (labeled block statement with no
520                      --  DECLARE part)
521
522                      elsif Token = Tok_Begin then
523                         Append_To (Statement_List,
524                           P_Begin_Statement (Id_Node));
525
526                      --  For statement (labeled loop statement with FOR)
527
528                      elsif Token = Tok_For then
529                         Append_To (Statement_List,
530                           P_For_Statement (Id_Node));
531
532                      --  Improper statement follows label. If we have an
533                      --  expression token, then assume the colon was part
534                      --  of a misplaced declaration.
535
536                      elsif Token not in Token_Class_Eterm then
537                         Restore_Scan_State (Scan_State_Label);
538                         Junk_Declaration;
539
540                      --  Otherwise complain we have inappropriate statement
541
542                      else
543                         Error_Msg_AP
544                           ("loop or block statement must follow label");
545                      end if;
546
547                      Statement_Required := False;
548
549                   --  Here we have an identifier followed by something
550                   --  other than a colon, semicolon or assignment symbol.
551                   --  The only valid possibility is a name extension symbol
552
553                   elsif Token in Token_Class_Namext then
554                      Restore_Scan_State (Scan_State_Label); -- to Id
555                      Name_Node := P_Name;
556
557                      --  Skip junk right parens in this context
558
559                      while Token = Tok_Right_Paren loop
560                         Error_Msg_SC ("extra right paren");
561                         Scan; -- past )
562                      end loop;
563
564                      --  Check context following call
565
566                      if Token = Tok_Colon_Equal then
567                         Scan; -- past colon equal
568                         Append_To (Statement_List,
569                           P_Assignment_Statement (Name_Node));
570                         Statement_Required := False;
571
572                      --  Check common case of = used instead of :=
573
574                      elsif Token = Tok_Equal then
575                         T_Colon_Equal; -- give := expected message
576                         Append_To (Statement_List,
577                           P_Assignment_Statement (Name_Node));
578                         Statement_Required := False;
579
580                      --  Check apostrophe cases
581
582                      elsif Token = Tok_Apostrophe then
583                         Append_To (Statement_List,
584                           P_Code_Statement (Name_Node));
585                         Statement_Required := False;
586
587                      --  The only other valid item after a name is ; which
588                      --  means that the item we just scanned was a call.
589
590                      elsif Token = Tok_Semicolon then
591                         Append_To (Statement_List,
592                           P_Statement_Name (Name_Node));
593                         Scan; -- past semicolon
594                         Statement_Required := False;
595
596                      --  A slash following an identifier or a selected
597                      --  component in this situation is most likely a
598                      --  period (have a look at the keyboard :-)
599
600                      elsif Token = Tok_Slash
601                        and then (Nkind (Name_Node) = N_Identifier
602                                    or else
603                                  Nkind (Name_Node) = N_Selected_Component)
604                      then
605                         Error_Msg_SC ("""/"" should be "".""");
606                         Statement_Required := False;
607                         raise Error_Resync;
608
609                      --  Else we have a missing semicolon
610
611                      else
612                         TF_Semicolon;
613                         Statement_Required := False;
614                      end if;
615
616                   --  If junk after identifier, check if identifier is an
617                   --  instance of an incorrectly spelled keyword. If so, we
618                   --  do nothing. The Bad_Spelling_Of will have reset Token
619                   --  to the appropriate keyword, so the next time round the
620                   --  loop we will process the modified token. Note that we
621                   --  check for ELSIF before ELSE here. That's not accidental.
622                   --  We don't want to identify a misspelling of ELSE as
623                   --  ELSIF, and in particular we do not want to treat ELSEIF
624                   --  as ELSE IF.
625
626                   else
627                      Restore_Scan_State (Scan_State_Label); -- to identifier
628
629                      if Bad_Spelling_Of (Tok_Abort)
630                        or else Bad_Spelling_Of (Tok_Accept)
631                        or else Bad_Spelling_Of (Tok_Case)
632                        or else Bad_Spelling_Of (Tok_Declare)
633                        or else Bad_Spelling_Of (Tok_Delay)
634                        or else Bad_Spelling_Of (Tok_Elsif)
635                        or else Bad_Spelling_Of (Tok_Else)
636                        or else Bad_Spelling_Of (Tok_End)
637                        or else Bad_Spelling_Of (Tok_Exception)
638                        or else Bad_Spelling_Of (Tok_Exit)
639                        or else Bad_Spelling_Of (Tok_For)
640                        or else Bad_Spelling_Of (Tok_Goto)
641                        or else Bad_Spelling_Of (Tok_If)
642                        or else Bad_Spelling_Of (Tok_Loop)
643                        or else Bad_Spelling_Of (Tok_Or)
644                        or else Bad_Spelling_Of (Tok_Pragma)
645                        or else Bad_Spelling_Of (Tok_Raise)
646                        or else Bad_Spelling_Of (Tok_Requeue)
647                        or else Bad_Spelling_Of (Tok_Return)
648                        or else Bad_Spelling_Of (Tok_Select)
649                        or else Bad_Spelling_Of (Tok_When)
650                        or else Bad_Spelling_Of (Tok_While)
651                      then
652                         null;
653
654                      --  If not a bad spelling, then we really have junk
655
656                      else
657                         Scan; -- past identifier again
658
659                         --  If next token is first token on line, then we
660                         --  consider that we were missing a semicolon after
661                         --  the identifier, and process it as a procedure
662                         --  call with no parameters.
663
664                         if Token_Is_At_Start_Of_Line then
665                            Append_To (Statement_List,
666                              P_Statement_Name (Id_Node));
667                            T_Semicolon; -- to give error message
668                            Statement_Required := False;
669
670                         --  Otherwise we give a missing := message and
671                         --  simply abandon the junk that is there now.
672
673                         else
674                            T_Colon_Equal; -- give := expected message
675                            raise Error_Resync;
676                         end if;
677
678                      end if;
679                   end if;
680
681                --  Statement starting with operator symbol. This could be
682                --  a call, a name starting an assignment, or a qualified
683                --  expression.
684
685                when Tok_Operator_Symbol =>
686                   Check_Bad_Layout;
687                   Name_Node := P_Name;
688
689                   --  An attempt at a range attribute or a qualified expression
690                   --  must be illegal here (a code statement cannot possibly
691                   --  allow qualification by a function name).
692
693                   if Token = Tok_Apostrophe then
694                      Error_Msg_SC ("apostrophe illegal here");
695                      raise Error_Resync;
696                   end if;
697
698                   --  Scan possible assignment if we have a name
699
700                   if Expr_Form = EF_Name
701                     and then Token = Tok_Colon_Equal
702                   then
703                      Scan; -- past colon equal
704                      Append_To (Statement_List,
705                        P_Assignment_Statement (Name_Node));
706                   else
707                      Append_To (Statement_List,
708                        P_Statement_Name (Name_Node));
709                   end if;
710
711                   TF_Semicolon;
712                   Statement_Required := False;
713
714                --  Label starting with << which must precede real statement
715
716                when Tok_Less_Less =>
717                   Append_To (Statement_List, P_Label);
718                   Statement_Required := True;
719
720                --  Pragma appearing as a statement in a statement sequence
721
722                when Tok_Pragma =>
723                   Check_Bad_Layout;
724                   Append_To (Statement_List, P_Pragma);
725
726                --  Abort_Statement
727
728                when Tok_Abort =>
729                   Check_Bad_Layout;
730                   Append_To (Statement_List, P_Abort_Statement);
731                   Statement_Required := False;
732
733                --  Accept_Statement
734
735                when Tok_Accept =>
736                   Check_Bad_Layout;
737                   Append_To (Statement_List, P_Accept_Statement);
738                   Statement_Required := False;
739
740                --  Begin_Statement (Block_Statement with no declare, no label)
741
742                when Tok_Begin =>
743                   Check_Bad_Layout;
744                   Append_To (Statement_List, P_Begin_Statement);
745                   Statement_Required := False;
746
747                --  Case_Statement
748
749                when Tok_Case =>
750                   Check_Bad_Layout;
751                   Append_To (Statement_List, P_Case_Statement);
752                   Statement_Required := False;
753
754                --  Block_Statement with DECLARE and no label
755
756                when Tok_Declare =>
757                   Check_Bad_Layout;
758                   Append_To (Statement_List, P_Declare_Statement);
759                   Statement_Required := False;
760
761                --  Delay_Statement
762
763                when Tok_Delay =>
764                   Check_Bad_Layout;
765                   Append_To (Statement_List, P_Delay_Statement);
766                   Statement_Required := False;
767
768                --  Exit_Statement
769
770                when Tok_Exit =>
771                   Check_Bad_Layout;
772                   Append_To (Statement_List, P_Exit_Statement);
773                   Statement_Required := False;
774
775                --  Loop_Statement with FOR and no label
776
777                when Tok_For =>
778                   Check_Bad_Layout;
779                   Append_To (Statement_List, P_For_Statement);
780                   Statement_Required := False;
781
782                --  Goto_Statement
783
784                when Tok_Goto =>
785                   Check_Bad_Layout;
786                   Append_To (Statement_List, P_Goto_Statement);
787                   Statement_Required := False;
788
789                --  If_Statement
790
791                when Tok_If =>
792                   Check_Bad_Layout;
793                   Append_To (Statement_List, P_If_Statement);
794                   Statement_Required := False;
795
796                --  Loop_Statement
797
798                when Tok_Loop =>
799                   Check_Bad_Layout;
800                   Append_To (Statement_List, P_Loop_Statement);
801                   Statement_Required := False;
802
803                --  Null_Statement
804
805                when Tok_Null =>
806                   Check_Bad_Layout;
807                   Append_To (Statement_List, P_Null_Statement);
808                   Statement_Required := False;
809
810                --  Raise_Statement
811
812                when Tok_Raise =>
813                   Check_Bad_Layout;
814                   Append_To (Statement_List, P_Raise_Statement);
815                   Statement_Required := False;
816
817                --  Requeue_Statement
818
819                when Tok_Requeue =>
820                   Check_Bad_Layout;
821                   Append_To (Statement_List, P_Requeue_Statement);
822                   Statement_Required := False;
823
824                --  Return_Statement
825
826                when Tok_Return =>
827                   Check_Bad_Layout;
828                   Append_To (Statement_List, P_Return_Statement);
829                   Statement_Required := False;
830
831                --  Select_Statement
832
833                when Tok_Select =>
834                   Check_Bad_Layout;
835                   Append_To (Statement_List, P_Select_Statement);
836                   Statement_Required := False;
837
838                --  While_Statement (Block_Statement with while and no loop)
839
840                when Tok_While =>
841                   Check_Bad_Layout;
842                   Append_To (Statement_List, P_While_Statement);
843                   Statement_Required := False;
844
845                --  Anything else is some kind of junk, signal an error message
846                --  and then raise Error_Resync, to merge with the normal
847                --  handling of a bad statement.
848
849                when others =>
850
851                   if Token in Token_Class_Declk then
852                      Junk_Declaration;
853
854                   else
855                      Error_Msg_BC ("statement expected");
856                      raise Error_Resync;
857                   end if;
858             end case;
859
860          --  On error resynchronization, skip past next semicolon, and, since
861          --  we are still in the statement loop, look for next statement. We
862          --  set Statement_Required False to avoid an unnecessary error message
863          --  complaining that no statement was found (i.e. we consider the
864          --  junk to satisfy the requirement for a statement being present).
865
866          exception
867             when Error_Resync =>
868                Resync_Past_Semicolon_Or_To_Loop_Or_Then;
869                Statement_Required := False;
870          end;
871
872          exit when SS_Flags.Unco;
873
874       end loop;
875
876       return Statement_List;
877
878    end P_Sequence_Of_Statements;
879
880    --------------------
881    -- 5.1  Statement --
882    --------------------
883
884    --  Parsed by P_Sequence_Of_Statements (5.1), except for the case
885    --  of a statement of the form of a name, which is handled here. The
886    --  argument passed in is the tree for the name which has been scanned
887    --  The returned value is the corresponding statement form.
888
889    --  This routine is also used by Par.Prag for processing the procedure
890    --  call that appears as the second argument of a pragma Assert.
891
892    --  Error recovery: cannot raise Error_Resync
893
894    function P_Statement_Name (Name_Node : Node_Id) return Node_Id is
895       Stmt_Node : Node_Id;
896
897    begin
898       --  Case of Indexed component, which is a procedure call with arguments
899
900       if Nkind (Name_Node) = N_Indexed_Component then
901          declare
902             Prefix_Node : Node_Id := Prefix (Name_Node);
903             Exprs_Node  : List_Id := Expressions (Name_Node);
904          begin
905             Change_Node (Name_Node, N_Procedure_Call_Statement);
906             Set_Name (Name_Node, Prefix_Node);
907             Set_Parameter_Associations (Name_Node, Exprs_Node);
908             return Name_Node;
909          end;
910
911       --  Case of function call node, which is a really a procedure call
912
913       elsif Nkind (Name_Node) = N_Function_Call then
914          declare
915             Fname_Node  : Node_Id := Name (Name_Node);
916             Params_List : List_Id := Parameter_Associations (Name_Node);
917
918          begin
919             Change_Node (Name_Node, N_Procedure_Call_Statement);
920             Set_Name (Name_Node, Fname_Node);
921             Set_Parameter_Associations (Name_Node, Params_List);
922             return Name_Node;
923          end;
924
925       --  Case of call to attribute that denotes a procedure. Here we
926       --  just leave the attribute reference unchanged.
927
928       elsif Nkind (Name_Node) = N_Attribute_Reference
929         and then Is_Procedure_Attribute_Name (Attribute_Name (Name_Node))
930       then
931          return Name_Node;
932
933       --  All other cases of names are parameterless procedure calls
934
935       else
936          Stmt_Node :=
937            New_Node (N_Procedure_Call_Statement, Sloc (Name_Node));
938          Set_Name (Stmt_Node, Name_Node);
939          return Stmt_Node;
940       end if;
941
942    end P_Statement_Name;
943
944    ---------------------------
945    -- 5.1  Simple Statement --
946    ---------------------------
947
948    --  Parsed by P_Sequence_Of_Statements (5.1)
949
950    -----------------------------
951    -- 5.1  Compound Statement --
952    -----------------------------
953
954    --  Parsed by P_Sequence_Of_Statements (5.1)
955
956    -------------------------
957    -- 5.1  Null Statement --
958    -------------------------
959
960    --  NULL_STATEMENT ::= null;
961
962    --  The caller has already checked that the current token is null
963
964    --  Error recovery: cannot raise Error_Resync
965
966    function P_Null_Statement return Node_Id is
967       Null_Stmt_Node : Node_Id;
968
969    begin
970       Null_Stmt_Node := New_Node (N_Null_Statement, Token_Ptr);
971       Scan; -- past NULL
972       TF_Semicolon;
973       return Null_Stmt_Node;
974    end P_Null_Statement;
975
976    ----------------
977    -- 5.1  Label --
978    ----------------
979
980    --  LABEL ::= <<label_STATEMENT_IDENTIFIER>>
981
982    --  STATEMENT_IDENTIFIER ::= DIRECT_NAME
983
984    --  The IDENTIFIER of a STATEMENT_IDENTIFIER shall be an identifier
985    --  (not an OPERATOR_SYMBOL)
986
987    --  The caller has already checked that the current token is <<
988
989    --  Error recovery: can raise Error_Resync
990
991    function P_Label return Node_Id is
992       Label_Node : Node_Id;
993
994    begin
995       Label_Node := New_Node (N_Label, Token_Ptr);
996       Scan; -- past <<
997       Set_Identifier (Label_Node, P_Identifier);
998       T_Greater_Greater;
999       Append_Elmt (Label_Node, Label_List);
1000       return Label_Node;
1001    end P_Label;
1002
1003    -------------------------------
1004    -- 5.1  Statement Identifier --
1005    -------------------------------
1006
1007    --  Statement label is parsed by P_Label (5.1)
1008
1009    --  Loop label is parsed by P_Loop_Statement (5.5), P_For_Statement (5.5)
1010    --   or P_While_Statement (5.5)
1011
1012    --  Block label is parsed by P_Begin_Statement (5.6) or
1013    --   P_Declare_Statement (5.6)
1014
1015    -------------------------------
1016    -- 5.2  Assignment Statement --
1017    -------------------------------
1018
1019    --  ASSIGNMENT_STATEMENT ::=
1020    --    variable_NAME := EXPRESSION;
1021
1022    --  Error recovery: can raise Error_Resync
1023
1024    function P_Assignment_Statement (LHS : Node_Id) return Node_Id is
1025       Assign_Node : Node_Id;
1026
1027    begin
1028       Assign_Node := New_Node (N_Assignment_Statement, Prev_Token_Ptr);
1029       Set_Name (Assign_Node, LHS);
1030       Set_Expression (Assign_Node, P_Expression_No_Right_Paren);
1031       TF_Semicolon;
1032       return Assign_Node;
1033    end P_Assignment_Statement;
1034
1035    -----------------------
1036    -- 5.3  If Statement --
1037    -----------------------
1038
1039    --  IF_STATEMENT ::=
1040    --    if CONDITION then
1041    --      SEQUENCE_OF_STATEMENTS
1042    --    {elsif CONDITION then
1043    --      SEQUENCE_OF_STATEMENTS}
1044    --    [else
1045    --      SEQUENCE_OF_STATEMENTS]
1046    --    end if;
1047
1048    --  The caller has checked that the initial token is IF (or in the error
1049    --  case of a mysterious THEN, the initial token may simply be THEN, in
1050    --  which case, no condition (or IF) was scanned).
1051
1052    --  Error recovery: can raise Error_Resync
1053
1054    function P_If_Statement return Node_Id is
1055       If_Node    : Node_Id;
1056       Elsif_Node : Node_Id;
1057       Loc        : Source_Ptr;
1058
1059       procedure Add_Elsif_Part;
1060       --  An internal procedure used to scan out a single ELSIF part. On entry
1061       --  the ELSIF (or an ELSE which has been determined should be ELSIF) is
1062       --  scanned out and is in Prev_Token.
1063
1064       procedure Check_If_Column;
1065       --  An internal procedure used to check that THEN, ELSE ELSE, or ELSIF
1066       --  appear in the right place if column checking is enabled (i.e. if
1067       --  they are the first token on the line, then they must appear in
1068       --  the same column as the opening IF).
1069
1070       procedure Check_Then_Column;
1071       --  This procedure carries out the style checks for a THEN token
1072       --  Note that the caller has set Loc to the Source_Ptr value for
1073       --  the previous IF or ELSIF token. These checks apply only to a
1074       --  THEN at the start of a line.
1075
1076       function Else_Should_Be_Elsif return Boolean;
1077       --  An internal routine used to do a special error recovery check when
1078       --  an ELSE is encountered. It determines if the ELSE should be treated
1079       --  as an ELSIF. A positive decision (TRUE returned, is made if the ELSE
1080       --  is followed by a sequence of tokens, starting on the same line as
1081       --  the ELSE, which are not expression terminators, followed by a THEN.
1082       --  On entry, the ELSE has been scanned out.
1083
1084       procedure Add_Elsif_Part is
1085       begin
1086          if No (Elsif_Parts (If_Node)) then
1087             Set_Elsif_Parts (If_Node, New_List);
1088          end if;
1089
1090          Elsif_Node := New_Node (N_Elsif_Part, Prev_Token_Ptr);
1091          Loc := Prev_Token_Ptr;
1092          Set_Condition (Elsif_Node, P_Condition);
1093          Check_Then_Column;
1094          Then_Scan;
1095          Set_Then_Statements
1096            (Elsif_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1097          Append (Elsif_Node, Elsif_Parts (If_Node));
1098       end Add_Elsif_Part;
1099
1100       procedure Check_If_Column is
1101       begin
1102          if Style.RM_Column_Check and then Token_Is_At_Start_Of_Line
1103            and then Start_Column /= Scope.Table (Scope.Last).Ecol
1104          then
1105             Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
1106             Error_Msg_SC ("(style) this token should be@");
1107          end if;
1108       end Check_If_Column;
1109
1110       procedure Check_Then_Column is
1111       begin
1112          if Token_Is_At_Start_Of_Line and then Token = Tok_Then then
1113             Check_If_Column;
1114             if Style_Check then Style.Check_Then (Loc); end if;
1115          end if;
1116       end Check_Then_Column;
1117
1118       function Else_Should_Be_Elsif return Boolean is
1119          Scan_State : Saved_Scan_State;
1120
1121       begin
1122          if Token_Is_At_Start_Of_Line then
1123             return False;
1124
1125          else
1126             Save_Scan_State (Scan_State);
1127
1128             loop
1129                if Token in Token_Class_Eterm then
1130                   Restore_Scan_State (Scan_State);
1131                   return False;
1132                else
1133                   Scan; -- past non-expression terminating token
1134
1135                   if Token = Tok_Then then
1136                      Restore_Scan_State (Scan_State);
1137                      return True;
1138                   end if;
1139                end if;
1140             end loop;
1141          end if;
1142       end Else_Should_Be_Elsif;
1143
1144    --  Start of processing for P_If_Statement
1145
1146    begin
1147       If_Node := New_Node (N_If_Statement, Token_Ptr);
1148
1149       Push_Scope_Stack;
1150       Scope.Table (Scope.Last).Etyp := E_If;
1151       Scope.Table (Scope.Last).Ecol := Start_Column;
1152       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1153       Scope.Table (Scope.Last).Labl := Error;
1154       Scope.Table (Scope.Last).Node := If_Node;
1155
1156       if Token = Tok_If then
1157          Loc := Token_Ptr;
1158          Scan; -- past IF
1159          Set_Condition (If_Node, P_Condition);
1160
1161          --  Deal with misuse of IF expression => used instead
1162          --  of WHEN expression =>
1163
1164          if Token = Tok_Arrow then
1165             Error_Msg_SC ("THEN expected");
1166             Scan; -- past the arrow
1167             Pop_Scope_Stack; -- remove unneeded entry
1168             raise Error_Resync;
1169          end if;
1170
1171          Check_Then_Column;
1172
1173       else
1174          Error_Msg_SC ("no IF for this THEN");
1175          Set_Condition (If_Node, Error);
1176       end if;
1177
1178       Then_Scan;
1179
1180       Set_Then_Statements
1181         (If_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1182
1183       --  This loop scans out else and elsif parts
1184
1185       loop
1186          if Token = Tok_Elsif then
1187             Check_If_Column;
1188
1189             if Present (Else_Statements (If_Node)) then
1190                Error_Msg_SP ("ELSIF cannot appear after ELSE");
1191             end if;
1192
1193             Scan; -- past ELSIF
1194             Add_Elsif_Part;
1195
1196          elsif Token = Tok_Else then
1197             Check_If_Column;
1198             Scan; -- past ELSE
1199
1200             if Else_Should_Be_Elsif then
1201                Error_Msg_SP ("ELSE should be ELSIF");
1202                Add_Elsif_Part;
1203
1204             else
1205                --  Here we have an else that really is an else
1206
1207                if Present (Else_Statements (If_Node)) then
1208                   Error_Msg_SP ("Only one ELSE part allowed");
1209                   Append_List
1210                     (P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq),
1211                      Else_Statements (If_Node));
1212                else
1213                   Set_Else_Statements
1214                     (If_Node, P_Sequence_Of_Statements (SS_Eftm_Eltm_Sreq));
1215                end if;
1216             end if;
1217
1218          --  If anything other than ELSE or ELSIF, exit the loop. The token
1219          --  had better be END (and in fact it had better be END IF), but
1220          --  we will let End_Statements take care of checking that.
1221
1222          else
1223             exit;
1224          end if;
1225       end loop;
1226
1227       End_Statements;
1228       return If_Node;
1229
1230    end P_If_Statement;
1231
1232    --------------------
1233    -- 5.3  Condition --
1234    --------------------
1235
1236    --  CONDITION ::= boolean_EXPRESSION
1237
1238    function P_Condition return Node_Id is
1239       Cond : Node_Id;
1240
1241    begin
1242       Cond := P_Expression_No_Right_Paren;
1243
1244       --  It is never possible for := to follow a condition, so if we get
1245       --  a := we assume it is a mistyped equality. Note that we do not try
1246       --  to reconstruct the tree correctly in this case, but we do at least
1247       --  give an accurate error message.
1248
1249       while Token = Tok_Colon_Equal loop
1250          Error_Msg_SC (""":="" should be ""=""");
1251          Scan; -- past junk :=
1252          Discard_Junk_Node (P_Expression_No_Right_Paren);
1253       end loop;
1254
1255       return Cond;
1256    end P_Condition;
1257
1258    -------------------------
1259    -- 5.4  Case Statement --
1260    -------------------------
1261
1262    --  CASE_STATEMENT ::=
1263    --    case EXPRESSION is
1264    --      CASE_STATEMENT_ALTERNATIVE
1265    --      {CASE_STATEMENT_ALTERNATIVE}
1266    --    end case;
1267
1268    --  The caller has checked that the first token is CASE
1269
1270    --  Can raise Error_Resync
1271
1272    function P_Case_Statement return Node_Id is
1273       Case_Node         : Node_Id;
1274       Alternatives_List : List_Id;
1275       First_When_Loc    : Source_Ptr;
1276
1277    begin
1278       Case_Node := New_Node (N_Case_Statement, Token_Ptr);
1279
1280       Push_Scope_Stack;
1281       Scope.Table (Scope.Last).Etyp := E_Case;
1282       Scope.Table (Scope.Last).Ecol := Start_Column;
1283       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1284       Scope.Table (Scope.Last).Labl := Error;
1285       Scope.Table (Scope.Last).Node := Case_Node;
1286
1287       Scan; -- past CASE
1288       Set_Expression (Case_Node, P_Expression_No_Right_Paren);
1289       TF_Is;
1290
1291       --  Prepare to parse case statement alternatives
1292
1293       Alternatives_List := New_List;
1294       P_Pragmas_Opt (Alternatives_List);
1295       First_When_Loc := Token_Ptr;
1296
1297       --  Loop through case statement alternatives
1298
1299       loop
1300          --  If we have a WHEN or OTHERS, then that's fine keep going. Note
1301          --  that it is a semantic check to ensure the proper use of OTHERS
1302
1303          if Token = Tok_When or else Token = Tok_Others then
1304             Append (P_Case_Statement_Alternative, Alternatives_List);
1305
1306          --  If we have an END, then probably we are at the end of the case
1307          --  but we only exit if Check_End thinks the END was reasonable.
1308
1309          elsif Token = Tok_End then
1310             exit when Check_End;
1311
1312          --  Here if token is other than WHEN, OTHERS or END. We definitely
1313          --  have an error, but the question is whether or not to get out of
1314          --  the case statement. We don't want to get out early, or we will
1315          --  get a slew of junk error messages for subsequent when tokens.
1316
1317          --  If the token is not at the start of the line, or if it is indented
1318          --  with respect to the current case statement, then the best guess is
1319          --  that we are still supposed to be inside the case statement. We
1320          --  complain about the missing WHEN, and discard the junk statements.
1321
1322          elsif not Token_Is_At_Start_Of_Line
1323            or else Start_Column > Scope.Table (Scope.Last).Ecol
1324          then
1325             Error_Msg_BC ("WHEN (case statement alternative) expected");
1326
1327             --  Here is a possibility for infinite looping if we don't make
1328             --  progress. So try to process statements, otherwise exit
1329
1330             declare
1331                Error_Ptr : constant Source_Ptr := Scan_Ptr;
1332             begin
1333                Discard_Junk_List (P_Sequence_Of_Statements (SS_Whtm));
1334                exit when Scan_Ptr = Error_Ptr and then Check_End;
1335             end;
1336
1337          --  Here we have a junk token at the start of the line and it is
1338          --  not indented. If Check_End thinks there is a missing END, then
1339          --  we will get out of the case, otherwise we keep going.
1340
1341          else
1342             exit when Check_End;
1343          end if;
1344       end loop;
1345
1346       --  Make sure we have at least one alternative
1347
1348       if No (First_Non_Pragma (Alternatives_List)) then
1349          Error_Msg
1350             ("WHEN expected, must have at least one alternative in case",
1351              First_When_Loc);
1352          return Error;
1353
1354       else
1355          Set_Alternatives (Case_Node, Alternatives_List);
1356          return Case_Node;
1357       end if;
1358    end P_Case_Statement;
1359
1360    -------------------------------------
1361    -- 5.4  Case Statement Alternative --
1362    -------------------------------------
1363
1364    --  CASE_STATEMENT_ALTERNATIVE ::=
1365    --    when DISCRETE_CHOICE_LIST =>
1366    --      SEQUENCE_OF_STATEMENTS
1367
1368    --  The caller has checked that the initial token is WHEN or OTHERS
1369    --  Error recovery: can raise Error_Resync
1370
1371    function P_Case_Statement_Alternative return Node_Id is
1372       Case_Alt_Node : Node_Id;
1373
1374    begin
1375       if Style_Check then Style.Check_Indentation; end if;
1376       Case_Alt_Node := New_Node (N_Case_Statement_Alternative, Token_Ptr);
1377       T_When; -- past WHEN (or give error in OTHERS case)
1378       Set_Discrete_Choices (Case_Alt_Node, P_Discrete_Choice_List);
1379       TF_Arrow;
1380       Set_Statements (Case_Alt_Node, P_Sequence_Of_Statements (SS_Sreq_Whtm));
1381       return Case_Alt_Node;
1382    end P_Case_Statement_Alternative;
1383
1384    -------------------------
1385    -- 5.5  Loop Statement --
1386    -------------------------
1387
1388    --  LOOP_STATEMENT ::=
1389    --    [LOOP_STATEMENT_IDENTIFIER:]
1390    --      [ITERATION_SCHEME] loop
1391    --        SEQUENCE_OF_STATEMENTS
1392    --      end loop [loop_IDENTIFIER];
1393
1394    --  ITERATION_SCHEME ::=
1395    --    while CONDITION
1396    --  | for LOOP_PARAMETER_SPECIFICATION
1397
1398    --  The parsing of loop statements is handled by one of three functions
1399    --  P_Loop_Statement, P_For_Statement or P_While_Statement depending
1400    --  on the initial keyword in the construct (excluding the identifier)
1401
1402    --  P_Loop_Statement
1403
1404    --  This function parses the case where no iteration scheme is present
1405
1406    --  The caller has checked that the initial token is LOOP. The parameter
1407    --  is the node identifiers for the loop label if any (or is set to Empty
1408    --  if there is no loop label).
1409
1410    --  Error recovery : cannot raise Error_Resync
1411
1412    function P_Loop_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1413       Loop_Node : Node_Id;
1414
1415    begin
1416       Push_Scope_Stack;
1417       Scope.Table (Scope.Last).Labl := Loop_Name;
1418       Scope.Table (Scope.Last).Ecol := Start_Column;
1419       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1420       Scope.Table (Scope.Last).Etyp := E_Loop;
1421
1422       Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1423       TF_Loop;
1424
1425       if No (Loop_Name) then
1426          Set_Has_Created_Identifier (Loop_Node, True);
1427          Set_Identifier (Loop_Node,
1428            Make_Identifier (Sloc (Loop_Node), Set_Loop_Block_Name ('L')));
1429       else
1430          Set_Identifier (Loop_Node, Loop_Name);
1431       end if;
1432
1433       Append_Elmt (Loop_Node, Label_List);
1434
1435       Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1436       End_Statements (Loop_Node);
1437       return Loop_Node;
1438    end P_Loop_Statement;
1439
1440    --  P_For_Statement
1441
1442    --  This function parses a loop statement with a FOR iteration scheme
1443
1444    --  The caller has checked that the initial token is FOR. The parameter
1445    --  is the node identifier for the block label if any (or is set to Empty
1446    --  if there is no block label).
1447
1448    --  Note: the caller fills in the Identifier field if a label was present
1449
1450    --  Error recovery: can raise Error_Resync
1451
1452    function P_For_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1453       Loop_Node        : Node_Id;
1454       Iter_Scheme_Node : Node_Id;
1455       Loop_For_Flag    : Boolean;
1456
1457    begin
1458       Push_Scope_Stack;
1459       Scope.Table (Scope.Last).Labl := Loop_Name;
1460       Scope.Table (Scope.Last).Ecol := Start_Column;
1461       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1462       Scope.Table (Scope.Last).Etyp := E_Loop;
1463
1464       Loop_For_Flag := (Prev_Token = Tok_Loop);
1465       Scan; -- past FOR
1466       Iter_Scheme_Node := New_Node (N_Iteration_Scheme, Token_Ptr);
1467       Set_Loop_Parameter_Specification
1468          (Iter_Scheme_Node, P_Loop_Parameter_Specification);
1469
1470       --  The following is a special test so that a miswritten for loop such
1471       --  as "loop for I in 1..10;" is handled nicely, without making an extra
1472       --  entry in the scope stack. We don't bother to actually fix up the
1473       --  tree in this case since it's not worth the effort. Instead we just
1474       --  eat up the loop junk, leaving the entry for what now looks like an
1475       --  unmodified loop intact.
1476
1477       if Loop_For_Flag and then Token = Tok_Semicolon then
1478          Error_Msg_SC ("LOOP belongs here, not before FOR");
1479          Pop_Scope_Stack;
1480          return Error;
1481
1482       --  Normal case
1483
1484       else
1485          Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1486          TF_Loop;
1487          Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1488          End_Statements (Loop_Node);
1489          Set_Iteration_Scheme (Loop_Node, Iter_Scheme_Node);
1490
1491          if No (Loop_Name) then
1492             Set_Has_Created_Identifier (Loop_Node, True);
1493             Set_Identifier (Loop_Node,
1494               Make_Identifier (Sloc (Loop_Node), Set_Loop_Block_Name ('L')));
1495          else
1496             Set_Identifier (Loop_Node, Loop_Name);
1497          end if;
1498
1499          Append_Elmt (Loop_Node, Label_List);
1500
1501          return Loop_Node;
1502       end if;
1503
1504    end P_For_Statement;
1505
1506    --  P_While_Statement
1507
1508    --  This procedure scans a loop statement with a WHILE iteration scheme
1509
1510    --  The caller has checked that the initial token is WHILE. The parameter
1511    --  is the node identifier for the block label if any (or is set to Empty
1512    --  if there is no block label).
1513
1514    --  Error recovery: cannot raise Error_Resync
1515
1516    function P_While_Statement (Loop_Name : Node_Id := Empty) return Node_Id is
1517       Loop_Node        : Node_Id;
1518       Iter_Scheme_Node : Node_Id;
1519       Loop_While_Flag  : Boolean;
1520
1521    begin
1522       Push_Scope_Stack;
1523       Scope.Table (Scope.Last).Labl := Loop_Name;
1524       Scope.Table (Scope.Last).Ecol := Start_Column;
1525       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1526       Scope.Table (Scope.Last).Etyp := E_Loop;
1527
1528       Loop_While_Flag := (Prev_Token = Tok_Loop);
1529       Iter_Scheme_Node := New_Node (N_Iteration_Scheme, Token_Ptr);
1530       Scan; -- past WHILE
1531       Set_Condition (Iter_Scheme_Node, P_Condition);
1532
1533       --  The following is a special test so that a miswritten for loop such
1534       --  as "loop while I > 10;" is handled nicely, without making an extra
1535       --  entry in the scope stack. We don't bother to actually fix up the
1536       --  tree in this case since it's not worth the effort. Instead we just
1537       --  eat up the loop junk, leaving the entry for what now looks like an
1538       --  unmodified loop intact.
1539
1540       if Loop_While_Flag and then Token = Tok_Semicolon then
1541          Error_Msg_SC ("LOOP belongs here, not before WHILE");
1542          Pop_Scope_Stack;
1543          return Error;
1544
1545       --  Normal case
1546
1547       else
1548          Loop_Node := New_Node (N_Loop_Statement, Token_Ptr);
1549          TF_Loop;
1550          Set_Statements (Loop_Node, P_Sequence_Of_Statements (SS_Sreq));
1551          End_Statements (Loop_Node);
1552          Set_Iteration_Scheme (Loop_Node, Iter_Scheme_Node);
1553
1554          if No (Loop_Name) then
1555             Set_Has_Created_Identifier (Loop_Node, True);
1556             Set_Identifier (Loop_Node,
1557               Make_Identifier (Sloc (Loop_Node), Set_Loop_Block_Name ('L')));
1558          else
1559             Set_Identifier (Loop_Node, Loop_Name);
1560          end if;
1561
1562          Append_Elmt (Loop_Node, Label_List);
1563
1564          return Loop_Node;
1565       end if;
1566
1567    end P_While_Statement;
1568
1569    ---------------------------------------
1570    -- 5.5  Loop Parameter Specification --
1571    ---------------------------------------
1572
1573    --  LOOP_PARAMETER_SPECIFICATION ::=
1574    --    DEFINING_IDENTIFIER in [reverse] DISCRETE_SUBTYPE_DEFINITION
1575
1576    --  Error recovery: cannot raise Error_Resync
1577
1578    function P_Loop_Parameter_Specification return Node_Id is
1579       Loop_Param_Specification_Node : Node_Id;
1580
1581       ID_Node    : Node_Id;
1582       Scan_State : Saved_Scan_State;
1583
1584    begin
1585       Loop_Param_Specification_Node :=
1586         New_Node (N_Loop_Parameter_Specification, Token_Ptr);
1587
1588       Save_Scan_State (Scan_State);
1589       ID_Node := P_Defining_Identifier;
1590       Set_Defining_Identifier (Loop_Param_Specification_Node, ID_Node);
1591
1592       if Token = Tok_Left_Paren then
1593          Error_Msg_SC ("subscripted loop parameter not allowed");
1594          Restore_Scan_State (Scan_State);
1595          Discard_Junk_Node (P_Name);
1596
1597       elsif Token = Tok_Dot then
1598          Error_Msg_SC ("selected loop parameter not allowed");
1599          Restore_Scan_State (Scan_State);
1600          Discard_Junk_Node (P_Name);
1601       end if;
1602
1603       T_In;
1604
1605       if Token = Tok_Reverse then
1606          Scan; -- past REVERSE
1607          Set_Reverse_Present (Loop_Param_Specification_Node, True);
1608       end if;
1609
1610       Set_Discrete_Subtype_Definition
1611         (Loop_Param_Specification_Node, P_Discrete_Subtype_Definition);
1612       return Loop_Param_Specification_Node;
1613
1614    exception
1615       when Error_Resync =>
1616          return Error;
1617    end P_Loop_Parameter_Specification;
1618
1619    --------------------------
1620    -- 5.6  Block Statement --
1621    --------------------------
1622
1623    --  BLOCK_STATEMENT ::=
1624    --    [block_STATEMENT_IDENTIFIER:]
1625    --      [declare
1626    --        DECLARATIVE_PART]
1627    --      begin
1628    --        HANDLED_SEQUENCE_OF_STATEMENTS
1629    --      end [block_IDENTIFIER];
1630
1631    --  The parsing of block statements is handled by one of the two functions
1632    --  P_Declare_Statement or P_Begin_Statement depending on whether or not
1633    --  a declare section is present
1634
1635    --  P_Declare_Statement
1636
1637    --  This function parses a block statement with DECLARE present
1638
1639    --  The caller has checked that the initial token is DECLARE.
1640
1641    --  Error recovery: cannot raise Error_Resync
1642
1643    function P_Declare_Statement
1644      (Block_Name : Node_Id := Empty)
1645       return       Node_Id
1646    is
1647       Block_Node : Node_Id;
1648
1649    begin
1650       Block_Node := New_Node (N_Block_Statement, Token_Ptr);
1651
1652       Push_Scope_Stack;
1653       Scope.Table (Scope.Last).Etyp := E_Name;
1654       Scope.Table (Scope.Last).Lreq := Present (Block_Name);
1655       Scope.Table (Scope.Last).Ecol := Start_Column;
1656       Scope.Table (Scope.Last).Labl := Block_Name;
1657       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1658
1659       Scan; -- past DECLARE
1660
1661       if No (Block_Name) then
1662          Set_Has_Created_Identifier (Block_Node, True);
1663          Set_Identifier (Block_Node,
1664            Make_Identifier (Sloc (Block_Node), Set_Loop_Block_Name ('B')));
1665       else
1666          Set_Identifier (Block_Node, Block_Name);
1667       end if;
1668
1669       Append_Elmt (Block_Node, Label_List);
1670       Parse_Decls_Begin_End (Block_Node);
1671       return Block_Node;
1672    end P_Declare_Statement;
1673
1674    --  P_Begin_Statement
1675
1676    --  This function parses a block statement with no DECLARE present
1677
1678    --  The caller has checked that the initial token is BEGIN
1679
1680    --  Error recovery: cannot raise Error_Resync
1681
1682    function P_Begin_Statement
1683      (Block_Name : Node_Id := Empty)
1684       return       Node_Id
1685    is
1686       Block_Node : Node_Id;
1687
1688    begin
1689       Block_Node := New_Node (N_Block_Statement, Token_Ptr);
1690
1691       Push_Scope_Stack;
1692       Scope.Table (Scope.Last).Etyp := E_Name;
1693       Scope.Table (Scope.Last).Lreq := Present (Block_Name);
1694       Scope.Table (Scope.Last).Ecol := Start_Column;
1695       Scope.Table (Scope.Last).Labl := Block_Name;
1696       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1697
1698       if No (Block_Name) then
1699          Set_Has_Created_Identifier (Block_Node, True);
1700          Set_Identifier (Block_Node,
1701            Make_Identifier (Sloc (Block_Node), Set_Loop_Block_Name ('B')));
1702       else
1703          Set_Identifier (Block_Node, Block_Name);
1704       end if;
1705
1706       Append_Elmt (Block_Node, Label_List);
1707
1708       Scope.Table (Scope.Last).Ecol := Start_Column;
1709       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1710       Scan; -- past BEGIN
1711       Set_Handled_Statement_Sequence
1712         (Block_Node, P_Handled_Sequence_Of_Statements);
1713       End_Statements (Handled_Statement_Sequence (Block_Node));
1714       return Block_Node;
1715    end P_Begin_Statement;
1716
1717    -------------------------
1718    -- 5.7  Exit Statement --
1719    -------------------------
1720
1721    --  EXIT_STATEMENT ::=
1722    --    exit [loop_NAME] [when CONDITION];
1723
1724    --  The caller has checked that the initial token is EXIT
1725
1726    --  Error recovery: can raise Error_Resync
1727
1728    function P_Exit_Statement return Node_Id is
1729       Exit_Node : Node_Id;
1730
1731       function Missing_Semicolon_On_Exit return Boolean;
1732       --  This function deals with the following specialized situation
1733       --
1734       --    when 'x' =>
1735       --       exit [identifier]
1736       --    when 'y' =>
1737       --
1738       --  This looks like a messed up EXIT WHEN, when in fact the problem
1739       --  is a missing semicolon. It is called with Token pointing to the
1740       --  WHEN token, and returns True if a semicolon is missing before
1741       --  the WHEN as in the above example.
1742
1743       function Missing_Semicolon_On_Exit return Boolean is
1744          State : Saved_Scan_State;
1745
1746       begin
1747          if not Token_Is_At_Start_Of_Line then
1748             return False;
1749
1750          elsif Scope.Table (Scope.Last).Etyp /= E_Case then
1751             return False;
1752
1753          else
1754             Save_Scan_State (State);
1755             Scan; -- past WHEN
1756             Scan; -- past token after WHEN
1757
1758             if Token = Tok_Arrow then
1759                Restore_Scan_State (State);
1760                return True;
1761             else
1762                Restore_Scan_State (State);
1763                return False;
1764             end if;
1765          end if;
1766       end Missing_Semicolon_On_Exit;
1767
1768    --  Start of processing for P_Exit_Statement
1769
1770    begin
1771       Exit_Node := New_Node (N_Exit_Statement, Token_Ptr);
1772       Scan; -- past EXIT
1773
1774       if Token = Tok_Identifier then
1775          Set_Name (Exit_Node, P_Qualified_Simple_Name);
1776
1777       elsif Style_Check then
1778          --  This EXIT has no name, so check that
1779          --  the innermost loop is unnamed too.
1780
1781          Check_No_Exit_Name :
1782          for J in reverse 1 .. Scope.Last loop
1783             if Scope.Table (J).Etyp = E_Loop then
1784                if Present (Scope.Table (J).Labl) then
1785
1786                   --  Innermost loop in fact had a name, style check fails
1787
1788                   Style.No_Exit_Name (Scope.Table (J).Labl);
1789                end if;
1790
1791                exit Check_No_Exit_Name;
1792             end if;
1793          end loop Check_No_Exit_Name;
1794       end if;
1795
1796       if Token = Tok_When and then not Missing_Semicolon_On_Exit then
1797          Scan; -- past WHEN
1798          Set_Condition (Exit_Node, P_Condition);
1799
1800       --  Allow IF instead of WHEN, giving error message
1801
1802       elsif Token = Tok_If then
1803          T_When;
1804          Scan; -- past IF used in place of WHEN
1805          Set_Condition (Exit_Node, P_Expression_No_Right_Paren);
1806       end if;
1807
1808       TF_Semicolon;
1809       return Exit_Node;
1810    end P_Exit_Statement;
1811
1812    -------------------------
1813    -- 5.8  Goto Statement --
1814    -------------------------
1815
1816    --  GOTO_STATEMENT ::= goto label_NAME;
1817
1818    --  The caller has checked that the initial token is GOTO  (or TO in the
1819    --  error case where GO and TO were incorrectly separated).
1820
1821    --  Error recovery: can raise Error_Resync
1822
1823    function P_Goto_Statement return Node_Id is
1824       Goto_Node : Node_Id;
1825
1826    begin
1827       Goto_Node := New_Node (N_Goto_Statement, Token_Ptr);
1828       Scan; -- past GOTO (or TO)
1829       Set_Name (Goto_Node, P_Qualified_Simple_Name_Resync);
1830       No_Constraint;
1831       TF_Semicolon;
1832       return Goto_Node;
1833    end P_Goto_Statement;
1834
1835    ---------------------------
1836    -- Parse_Decls_Begin_End --
1837    ---------------------------
1838
1839    --  This function parses the construct:
1840
1841    --      DECLARATIVE_PART
1842    --    begin
1843    --      HANDLED_SEQUENCE_OF_STATEMENTS
1844    --    end [NAME];
1845
1846    --  The caller has built the scope stack entry, and created the node to
1847    --  whose Declarations and Handled_Statement_Sequence fields are to be
1848    --  set. On return these fields are filled in (except in the case of a
1849    --  task body, where the handled statement sequence is optional, and may
1850    --  thus be Empty), and the scan is positioned past the End sequence.
1851
1852    --  If the BEGIN is missing, then the parent node is used to help construct
1853    --  an appropriate missing BEGIN message. Possibilities for the parent are:
1854
1855    --    N_Block_Statement     declare block
1856    --    N_Entry_Body          entry body
1857    --    N_Package_Body        package body (begin part optional)
1858    --    N_Subprogram_Body     procedure or function body
1859    --    N_Task_Body           task body
1860
1861    --  Note: in the case of a block statement, there is definitely a DECLARE
1862    --  present (because a Begin statement without a DECLARE is handled by the
1863    --  P_Begin_Statement procedure, which does not call Parse_Decls_Begin_End.
1864
1865    --  Error recovery: cannot raise Error_Resync
1866
1867    procedure Parse_Decls_Begin_End (Parent : Node_Id) is
1868       Body_Decl    : Node_Id;
1869       Body_Sloc    : Source_Ptr;
1870       Decls        : List_Id;
1871       Decl         : Node_Id;
1872       Parent_Nkind : Node_Kind;
1873       Spec_Node    : Node_Id;
1874       HSS          : Node_Id;
1875
1876       procedure Missing_Begin (Msg : String);
1877       --  Called to post a missing begin message. In the normal case this is
1878       --  posted at the start of the current token. A special case arises when
1879       --  P_Declarative_Items has previously found a missing begin, in which
1880       --  case we replace the original error message.
1881
1882       procedure Set_Null_HSS (Parent : Node_Id);
1883       --  Construct an empty handled statement sequence and install in Parent
1884       --  Leaves HSS set to reference the newly constructed statement sequence.
1885
1886       -------------------
1887       -- Missing_Begin --
1888       -------------------
1889
1890       procedure Missing_Begin (Msg : String) is
1891       begin
1892          if Missing_Begin_Msg = No_Error_Msg then
1893             Error_Msg_BC (Msg);
1894          else
1895             Change_Error_Text (Missing_Begin_Msg, Msg);
1896
1897             --  Purge any messages issued after than, since a missing begin
1898             --  can cause a lot of havoc, and it is better not to dump these
1899             --  cascaded messages on the user.
1900
1901             Purge_Messages (Get_Location (Missing_Begin_Msg), Prev_Token_Ptr);
1902          end if;
1903       end Missing_Begin;
1904
1905       ------------------
1906       -- Set_Null_HSS --
1907       ------------------
1908
1909       procedure Set_Null_HSS (Parent : Node_Id) is
1910          Null_Stm : Node_Id;
1911
1912       begin
1913          Null_Stm :=
1914            Make_Null_Statement (Token_Ptr);
1915          Set_Comes_From_Source (Null_Stm, False);
1916
1917          HSS :=
1918            Make_Handled_Sequence_Of_Statements (Token_Ptr,
1919              Statements => New_List (Null_Stm));
1920          Set_Comes_From_Source (HSS, False);
1921
1922          Set_Handled_Statement_Sequence (Parent, HSS);
1923       end Set_Null_HSS;
1924
1925    --  Start of processing for Parse_Decls_Begin_End
1926
1927    begin
1928       Decls := P_Declarative_Part;
1929
1930       --  Check for misplacement of later vs basic declarations in Ada 83
1931
1932       if Ada_83 then
1933          Decl := First (Decls);
1934
1935          --  Loop through sequence of basic declarative items
1936
1937          Outer : while Present (Decl) loop
1938             if Nkind (Decl) /= N_Subprogram_Body
1939               and then Nkind (Decl) /= N_Package_Body
1940               and then Nkind (Decl) /= N_Task_Body
1941               and then Nkind (Decl) not in  N_Body_Stub
1942             then
1943                Next (Decl);
1944
1945             --  Once a body is encountered, we only allow later declarative
1946             --  items. The inner loop checks the rest of the list.
1947
1948             else
1949                Body_Sloc := Sloc (Decl);
1950
1951                Inner : while Present (Decl) loop
1952                   if Nkind (Decl) not in N_Later_Decl_Item
1953                     and then Nkind (Decl) /= N_Pragma
1954                   then
1955                      if Ada_83 then
1956                         Error_Msg_Sloc := Body_Sloc;
1957                         Error_Msg_N
1958                           ("(Ada 83) decl cannot appear after body#", Decl);
1959                      end if;
1960                   end if;
1961
1962                   Next (Decl);
1963                end loop Inner;
1964             end if;
1965          end loop Outer;
1966       end if;
1967
1968       --  Here is where we deal with the case of IS used instead of semicolon.
1969       --  Specifically, if the last declaration in the declarative part is a
1970       --  subprogram body still marked as having a bad IS, then this is where
1971       --  we decide that the IS should really have been a semicolon and that
1972       --  the body should have been a declaration. Note that if the bad IS
1973       --  had turned out to be OK (i.e. a decent begin/end was found for it),
1974       --  then the Bad_Is_Detected flag would have been reset by now.
1975
1976       Body_Decl := Last (Decls);
1977
1978       if Present (Body_Decl)
1979         and then Nkind (Body_Decl) = N_Subprogram_Body
1980         and then Bad_Is_Detected (Body_Decl)
1981       then
1982          --  OK, we have the case of a bad IS, so we need to fix up the tree.
1983          --  What we have now is a subprogram body with attached declarations
1984          --  and a possible statement sequence.
1985
1986          --  First step is to take the declarations that were part of the bogus
1987          --  subprogram body and append them to the outer declaration chain.
1988          --  In other words we append them past the body (which we will later
1989          --  convert into a declaration).
1990
1991          Append_List (Declarations (Body_Decl), Decls);
1992
1993          --  Now take the handled statement sequence of the bogus body and
1994          --  set it as the statement sequence for the outer construct. Note
1995          --  that it may be empty (we specially allowed a missing BEGIN for
1996          --  a subprogram body marked as having a bad IS -- see below).
1997
1998          Set_Handled_Statement_Sequence (Parent,
1999            Handled_Statement_Sequence (Body_Decl));
2000
2001          --  Next step is to convert the old body node to a declaration node
2002
2003          Spec_Node := Specification (Body_Decl);
2004          Change_Node (Body_Decl, N_Subprogram_Declaration);
2005          Set_Specification (Body_Decl, Spec_Node);
2006
2007          --  Final step is to put the declarations for the parent where
2008          --  they belong, and then fall through the IF to scan out the
2009          --  END statements.
2010
2011          Set_Declarations (Parent, Decls);
2012
2013       --  This is the normal case (i.e. any case except the bad IS case)
2014       --  If we have a BEGIN, then scan out the sequence of statements, and
2015       --  also reset the expected column for the END to match the BEGIN.
2016
2017       else
2018          Set_Declarations (Parent, Decls);
2019
2020          if Token = Tok_Begin then
2021             if Style_Check then Style.Check_Indentation; end if;
2022
2023             Error_Msg_Col := Scope.Table (Scope.Last).Ecol;
2024
2025             if Style.RM_Column_Check
2026               and then Token_Is_At_Start_Of_Line
2027               and then Start_Column /= Error_Msg_Col
2028             then
2029                Error_Msg_SC ("(style) BEGIN in wrong column, should be@");
2030
2031             else
2032                Scope.Table (Scope.Last).Ecol := Start_Column;
2033             end if;
2034
2035             Scope.Table (Scope.Last).Sloc := Token_Ptr;
2036             Scan; -- past BEGIN
2037             Set_Handled_Statement_Sequence (Parent,
2038               P_Handled_Sequence_Of_Statements);
2039
2040          --  No BEGIN present
2041
2042          else
2043             Parent_Nkind := Nkind (Parent);
2044
2045             --  A special check for the missing IS case. If we have a
2046             --  subprogram body that was marked as having a suspicious
2047             --  IS, and the current token is END, then we simply confirm
2048             --  the suspicion, and do not require a BEGIN to be present
2049
2050             if Parent_Nkind = N_Subprogram_Body
2051               and then Token  = Tok_End
2052               and then Scope.Table (Scope.Last).Etyp = E_Suspicious_Is
2053             then
2054                Scope.Table (Scope.Last).Etyp := E_Bad_Is;
2055
2056             --  Otherwise BEGIN is not required for a package body, so we
2057             --  don't mind if it is missing, but we do construct a dummy
2058             --  one (so that we have somewhere to set End_Label).
2059
2060             --  However if we have something other than a BEGIN which
2061             --  looks like it might be statements, then we signal a missing
2062             --  BEGIN for these cases as well. We define "something which
2063             --  looks like it might be statements" as a token other than
2064             --  END, EOF, or a token which starts declarations.
2065
2066             elsif Parent_Nkind = N_Package_Body
2067               and then (Token = Tok_End
2068                           or else Token = Tok_EOF
2069                           or else Token in Token_Class_Declk)
2070             then
2071                Set_Null_HSS (Parent);
2072
2073             --  These are cases in which a BEGIN is required and not present
2074
2075             else
2076                Set_Null_HSS (Parent);
2077
2078                --  Prepare to issue error message
2079
2080                Error_Msg_Sloc := Scope.Table (Scope.Last).Sloc;
2081                Error_Msg_Node_1 := Scope.Table (Scope.Last).Labl;
2082
2083                --  Now issue appropriate message
2084
2085                if Parent_Nkind = N_Block_Statement then
2086                   Missing_Begin ("missing BEGIN for DECLARE#!");
2087
2088                elsif Parent_Nkind = N_Entry_Body then
2089                   Missing_Begin ("missing BEGIN for ENTRY#!");
2090
2091                elsif Parent_Nkind = N_Subprogram_Body then
2092                   if Nkind (Specification (Parent))
2093                                = N_Function_Specification
2094                   then
2095                      Missing_Begin ("missing BEGIN for function&#!");
2096                   else
2097                      Missing_Begin ("missing BEGIN for procedure&#!");
2098                   end if;
2099
2100                --  The case for package body arises only when
2101                --  we have possible statement junk present.
2102
2103                elsif Parent_Nkind = N_Package_Body then
2104                   Missing_Begin ("missing BEGIN for package body&#!");
2105
2106                else
2107                   pragma Assert (Parent_Nkind = N_Task_Body);
2108                   Missing_Begin ("missing BEGIN for task body&#!");
2109                end if;
2110
2111                --  Here we pick up the statements after the BEGIN that
2112                --  should have been present but was not. We don't insist
2113                --  on statements being present if P_Declarative_Part had
2114                --  already found a missing BEGIN, since it might have
2115                --  swallowed a lone statement into the declarative part.
2116
2117                if Missing_Begin_Msg /= No_Error_Msg
2118                  and then Token = Tok_End
2119                then
2120                   null;
2121                else
2122                   Set_Handled_Statement_Sequence (Parent,
2123                     P_Handled_Sequence_Of_Statements);
2124                end if;
2125             end if;
2126          end if;
2127       end if;
2128
2129       --  Here with declarations and handled statement sequence scanned
2130
2131       if Present (Handled_Statement_Sequence (Parent)) then
2132          End_Statements (Handled_Statement_Sequence (Parent));
2133       else
2134          End_Statements;
2135       end if;
2136
2137       --  We know that End_Statements removed an entry from the scope stack
2138       --  (because it is required to do so under all circumstances). We can
2139       --  therefore reference the entry it removed one past the stack top.
2140       --  What we are interested in is whether it was a case of a bad IS.
2141
2142       if Scope.Table (Scope.Last + 1).Etyp = E_Bad_Is then
2143          Error_Msg ("IS should be "";""", Scope.Table (Scope.Last + 1).S_Is);
2144          Set_Bad_Is_Detected (Parent, True);
2145       end if;
2146
2147    end Parse_Decls_Begin_End;
2148
2149    -------------------------
2150    -- Set_Loop_Block_Name --
2151    -------------------------
2152
2153    function Set_Loop_Block_Name (L : Character) return Name_Id is
2154    begin
2155       Name_Buffer (1) := L;
2156       Name_Buffer (2) := '_';
2157       Name_Len := 2;
2158       Loop_Block_Count := Loop_Block_Count + 1;
2159       Add_Nat_To_Name_Buffer (Loop_Block_Count);
2160       return Name_Find;
2161    end Set_Loop_Block_Name;
2162
2163    ---------------
2164    -- Then_Scan --
2165    ---------------
2166
2167    procedure Then_Scan is
2168    begin
2169       TF_Then;
2170
2171       while Token = Tok_Then loop
2172          Error_Msg_SC ("redundant THEN");
2173          TF_Then;
2174       end loop;
2175
2176       if Token = Tok_And or else Token = Tok_Or then
2177          Error_Msg_SC ("unexpected logical operator");
2178          Scan;
2179
2180          if (Prev_Token = Tok_And and then Token = Tok_Then)
2181               or else
2182             (Prev_Token = Tok_Or  and then Token = Tok_Else)
2183          then
2184             Scan;
2185          end if;
2186
2187          Discard_Junk_Node (P_Expression);
2188       end if;
2189
2190       if Token = Tok_Then then
2191          Scan;
2192       end if;
2193    end Then_Scan;
2194
2195 end Ch5;