OSDN Git Service

2003-10-21 Arnaud Charlet <charlet@act-europe.fr>
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch9.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 9                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2002 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 Ch9 is
33
34    --  Local subprograms, used only in this chapter
35
36    function P_Accept_Alternative                   return Node_Id;
37    function P_Delay_Alternative                    return Node_Id;
38    function P_Delay_Relative_Statement             return Node_Id;
39    function P_Delay_Until_Statement                return Node_Id;
40    function P_Entry_Barrier                        return Node_Id;
41    function P_Entry_Body_Formal_Part               return Node_Id;
42    function P_Entry_Declaration                    return Node_Id;
43    function P_Entry_Index_Specification            return Node_Id;
44    function P_Protected_Definition                 return Node_Id;
45    function P_Protected_Operation_Declaration_Opt  return Node_Id;
46    function P_Protected_Operation_Items            return List_Id;
47    function P_Task_Definition                      return Node_Id;
48    function P_Task_Items                           return List_Id;
49
50    -----------------------------
51    -- 9.1  Task (also 10.1.3) --
52    -----------------------------
53
54    --  TASK_TYPE_DECLARATION ::=
55    --    task type DEFINING_IDENTIFIER [KNOWN_DISCRIMINANT_PART]
56    --      [is TASK_DEFINITION];
57
58    --  SINGLE_TASK_DECLARATION ::=
59    --    task DEFINING_IDENTIFIER [is TASK_DEFINITION];
60
61    --  TASK_BODY ::=
62    --    task body DEFINING_IDENTIFIER is
63    --      DECLARATIVE_PART
64    --    begin
65    --      HANDLED_SEQUENCE_OF_STATEMENTS
66    --    end [task_IDENTIFIER]
67
68    --  TASK_BODY_STUB ::=
69    --    task body DEFINING_IDENTIFIER is separate;
70
71    --  This routine scans out a task declaration, task body, or task stub
72
73    --  The caller has checked that the initial token is TASK and scanned
74    --  past it, so that Token is set to the token after TASK
75
76    --  Error recovery: cannot raise Error_Resync
77
78    function P_Task return Node_Id is
79       Name_Node  : Node_Id;
80       Task_Node  : Node_Id;
81       Task_Sloc  : Source_Ptr;
82
83    begin
84       Push_Scope_Stack;
85       Scope.Table (Scope.Last).Etyp := E_Name;
86       Scope.Table (Scope.Last).Ecol := Start_Column;
87       Scope.Table (Scope.Last).Sloc := Token_Ptr;
88       Scope.Table (Scope.Last).Lreq := False;
89       Task_Sloc := Prev_Token_Ptr;
90
91       if Token = Tok_Body then
92          Scan; -- past BODY
93          Name_Node := P_Defining_Identifier;
94          Scope.Table (Scope.Last).Labl := Name_Node;
95
96          if Token = Tok_Left_Paren then
97             Error_Msg_SC ("discriminant part not allowed in task body");
98             Discard_Junk_List (P_Known_Discriminant_Part_Opt);
99          end if;
100
101          TF_Is;
102
103          --  Task stub
104
105          if Token = Tok_Separate then
106             Scan; -- past SEPARATE
107             Task_Node := New_Node (N_Task_Body_Stub, Task_Sloc);
108             Set_Defining_Identifier (Task_Node, Name_Node);
109             TF_Semicolon;
110             Pop_Scope_Stack; -- remove unused entry
111
112          --  Task body
113
114          else
115             Task_Node := New_Node (N_Task_Body, Task_Sloc);
116             Set_Defining_Identifier (Task_Node, Name_Node);
117             Parse_Decls_Begin_End (Task_Node);
118          end if;
119
120          return Task_Node;
121
122       --  Otherwise we must have a task declaration
123
124       else
125          if Token = Tok_Type then
126             Scan; -- past TYPE
127             Task_Node := New_Node (N_Task_Type_Declaration, Task_Sloc);
128             Name_Node := P_Defining_Identifier;
129             Set_Defining_Identifier (Task_Node, Name_Node);
130             Scope.Table (Scope.Last).Labl := Name_Node;
131             Set_Discriminant_Specifications
132               (Task_Node, P_Known_Discriminant_Part_Opt);
133
134          else
135             Task_Node := New_Node (N_Single_Task_Declaration, Task_Sloc);
136             Name_Node := P_Defining_Identifier;
137             Set_Defining_Identifier (Task_Node, Name_Node);
138             Scope.Table (Scope.Last).Labl := Name_Node;
139
140             if Token = Tok_Left_Paren then
141                Error_Msg_SC ("discriminant part not allowed for single task");
142                Discard_Junk_List (P_Known_Discriminant_Part_Opt);
143             end if;
144
145          end if;
146
147          --  Parse optional task definition. Note that P_Task_Definition scans
148          --  out the semicolon as well as the task definition itself.
149
150          if Token = Tok_Semicolon then
151
152             --  A little check, if the next token after semicolon is
153             --  Entry, then surely the semicolon should really be IS
154
155             Scan; -- past semicolon
156
157             if Token = Tok_Entry then
158                Error_Msg_SP (""";"" should be IS");
159                Set_Task_Definition (Task_Node, P_Task_Definition);
160             else
161                Pop_Scope_Stack; -- Remove unused entry
162             end if;
163          else
164             TF_Is; -- must have IS if no semicolon
165             Set_Task_Definition (Task_Node, P_Task_Definition);
166          end if;
167
168          return Task_Node;
169       end if;
170    end P_Task;
171
172    --------------------------------
173    -- 9.1  Task Type Declaration --
174    --------------------------------
175
176    --  Parsed by P_Task (9.1)
177
178    ----------------------------------
179    -- 9.1  Single Task Declaration --
180    ----------------------------------
181
182    --  Parsed by P_Task (9.1)
183
184    --------------------------
185    -- 9.1  Task Definition --
186    --------------------------
187
188    --  TASK_DEFINITION ::=
189    --      {TASK_ITEM}
190    --    [private
191    --      {TASK_ITEM}]
192    --    end [task_IDENTIFIER];
193
194    --  The caller has already made the scope stack entry
195
196    --  Note: there is a small deviation from official syntax here in that we
197    --  regard the semicolon after end as part of the Task_Definition, and in
198    --  the official syntax, it's part of the enclosing declaration. The reason
199    --  for this deviation is that otherwise the end processing would have to
200    --  be special cased, which would be a nuisance!
201
202    --  Error recovery:  cannot raise Error_Resync
203
204    function P_Task_Definition return Node_Id is
205       Def_Node  : Node_Id;
206
207    begin
208       Def_Node := New_Node (N_Task_Definition, Token_Ptr);
209       Set_Visible_Declarations (Def_Node, P_Task_Items);
210
211       if Token = Tok_Private then
212          Scan; -- past PRIVATE
213          Set_Private_Declarations (Def_Node, P_Task_Items);
214
215          --  Deal gracefully with multiple PRIVATE parts
216
217          while Token = Tok_Private loop
218             Error_Msg_SC ("Only one private part allowed per task");
219             Scan; -- past PRIVATE
220             Append_List (P_Task_Items, Private_Declarations (Def_Node));
221          end loop;
222       end if;
223
224       End_Statements (Def_Node);
225       return Def_Node;
226    end P_Task_Definition;
227
228    --------------------
229    -- 9.1  Task Item --
230    --------------------
231
232    --  TASK_ITEM ::= ENTRY_DECLARATION | REPRESENTATION_CLAUSE
233
234    --  This subprogram scans a (possibly empty) list of task items and pragmas
235
236    --  Error recovery:  cannot raise Error_Resync
237
238    --  Note: a pragma can also be returned in this position
239
240    function P_Task_Items return List_Id is
241       Items      : List_Id;
242       Item_Node  : Node_Id;
243       Decl_Sloc  : Source_Ptr;
244
245    begin
246       --  Get rid of active SIS entry from outer scope. This means we will
247       --  miss some nested cases, but it doesn't seem worth the effort. See
248       --  discussion in Par for further details
249
250       SIS_Entry_Active := False;
251
252       --  Loop to scan out task items
253
254       Items := New_List;
255
256       Decl_Loop : loop
257          Decl_Sloc := Token_Ptr;
258
259          if Token = Tok_Pragma then
260             Append (P_Pragma, Items);
261
262          elsif Token = Tok_Entry then
263             Append (P_Entry_Declaration, Items);
264
265          elsif Token = Tok_For then
266             --  Representation clause in task declaration. The only rep
267             --  clause which is legal in a protected is an address clause,
268             --  so that is what we try to scan out.
269
270             Item_Node := P_Representation_Clause;
271
272             if Nkind (Item_Node) = N_At_Clause then
273                Append (Item_Node, Items);
274
275             elsif Nkind (Item_Node) = N_Attribute_Definition_Clause
276               and then Chars (Item_Node) = Name_Address
277             then
278                Append (Item_Node, Items);
279
280             else
281                Error_Msg
282                  ("the only representation clause " &
283                   "allowed here is an address clause!", Decl_Sloc);
284             end if;
285
286          elsif Token = Tok_Identifier
287            or else Token in Token_Class_Declk
288          then
289             Error_Msg_SC ("Illegal declaration in task definition");
290             Resync_Past_Semicolon;
291
292          else
293             exit Decl_Loop;
294          end if;
295       end loop Decl_Loop;
296
297       return Items;
298    end P_Task_Items;
299
300    --------------------
301    -- 9.1  Task Body --
302    --------------------
303
304    --  Parsed by P_Task (9.1)
305
306    ----------------------------------
307    -- 9.4  Protected (also 10.1.3) --
308    ----------------------------------
309
310    --  PROTECTED_TYPE_DECLARATION ::=
311    --    protected type DEFINING_IDENTIFIER [KNOWN_DISCRIMINANT_PART]
312    --      is PROTECTED_DEFINITION;
313
314    --  SINGLE_PROTECTED_DECLARATION ::=
315    --    protected DEFINING_IDENTIFIER is PROTECTED_DEFINITION;
316
317    --  PROTECTED_BODY ::=
318    --    protected body DEFINING_IDENTIFIER is
319    --      {PROTECTED_OPERATION_ITEM}
320    --    end [protected_IDENTIFIER];
321
322    --  PROTECTED_BODY_STUB ::=
323    --    protected body DEFINING_IDENTIFIER is separate;
324
325    --  This routine scans out a protected declaration, protected body
326    --  or a protected stub.
327
328    --  The caller has checked that the initial token is PROTECTED and
329    --  scanned past it, so Token is set to the following token.
330
331    --  Error recovery: cannot raise Error_Resync
332
333    function P_Protected return Node_Id is
334       Name_Node      : Node_Id;
335       Protected_Node : Node_Id;
336       Protected_Sloc : Source_Ptr;
337
338    begin
339       Push_Scope_Stack;
340       Scope.Table (Scope.Last).Etyp := E_Name;
341       Scope.Table (Scope.Last).Ecol := Start_Column;
342       Scope.Table (Scope.Last).Lreq := False;
343       Protected_Sloc := Prev_Token_Ptr;
344
345       if Token = Tok_Body then
346          Scan; -- past BODY
347          Name_Node := P_Defining_Identifier;
348          Scope.Table (Scope.Last).Labl := Name_Node;
349
350          if Token = Tok_Left_Paren then
351             Error_Msg_SC ("discriminant part not allowed in protected body");
352             Discard_Junk_List (P_Known_Discriminant_Part_Opt);
353          end if;
354
355          TF_Is;
356
357          --  Protected stub
358
359          if Token = Tok_Separate then
360             Scan; -- past SEPARATE
361             Protected_Node := New_Node (N_Protected_Body_Stub, Protected_Sloc);
362             Set_Defining_Identifier (Protected_Node, Name_Node);
363             TF_Semicolon;
364             Pop_Scope_Stack; -- remove unused entry
365
366          --  Protected body
367
368          else
369             Protected_Node := New_Node (N_Protected_Body, Protected_Sloc);
370             Set_Defining_Identifier (Protected_Node, Name_Node);
371             Set_Declarations (Protected_Node, P_Protected_Operation_Items);
372             End_Statements (Protected_Node);
373          end if;
374
375          return Protected_Node;
376
377       --  Otherwise we must have a protected declaration
378
379       else
380          if Token = Tok_Type then
381             Scan; -- past TYPE
382             Protected_Node :=
383               New_Node (N_Protected_Type_Declaration, Protected_Sloc);
384             Name_Node := P_Defining_Identifier;
385             Set_Defining_Identifier (Protected_Node, Name_Node);
386             Scope.Table (Scope.Last).Labl := Name_Node;
387             Set_Discriminant_Specifications
388               (Protected_Node, P_Known_Discriminant_Part_Opt);
389
390          else
391             Protected_Node :=
392               New_Node (N_Single_Protected_Declaration, Protected_Sloc);
393             Name_Node := P_Defining_Identifier;
394             Set_Defining_Identifier (Protected_Node, Name_Node);
395
396             if Token = Tok_Left_Paren then
397                Error_Msg_SC
398                  ("discriminant part not allowed for single protected");
399                Discard_Junk_List (P_Known_Discriminant_Part_Opt);
400             end if;
401
402             Scope.Table (Scope.Last).Labl := Name_Node;
403          end if;
404
405          T_Is;
406          Set_Protected_Definition (Protected_Node, P_Protected_Definition);
407          return Protected_Node;
408       end if;
409    end P_Protected;
410
411    -------------------------------------
412    -- 9.4  Protected Type Declaration --
413    -------------------------------------
414
415    --  Parsed by P_Protected (9.4)
416
417    ---------------------------------------
418    -- 9.4  Single Protected Declaration --
419    ---------------------------------------
420
421    --  Parsed by P_Protected (9.4)
422
423    -------------------------------
424    -- 9.4  Protected Definition --
425    -------------------------------
426
427    --  PROTECTED_DEFINITION ::=
428    --      {PROTECTED_OPERATION_DECLARATION}
429    --    [private
430    --      {PROTECTED_ELEMENT_DECLARATION}]
431    --    end [protected_IDENTIFIER]
432
433    --  PROTECTED_ELEMENT_DECLARATION ::=
434    --    PROTECTED_OPERATION_DECLARATION
435    --  | COMPONENT_DECLARATION
436
437    --  The caller has already established the scope stack entry
438
439    --  Error recovery: cannot raise Error_Resync
440
441    function P_Protected_Definition return Node_Id is
442       Def_Node  : Node_Id;
443       Item_Node : Node_Id;
444
445    begin
446       Def_Node := New_Node (N_Protected_Definition, Token_Ptr);
447
448       --  Get rid of active SIS entry from outer scope. This means we will
449       --  miss some nested cases, but it doesn't seem worth the effort. See
450       --  discussion in Par for further details
451
452       SIS_Entry_Active := False;
453
454       --  Loop to scan visible declarations (protected operation declarations)
455
456       Set_Visible_Declarations (Def_Node, New_List);
457
458       loop
459          Item_Node := P_Protected_Operation_Declaration_Opt;
460          exit when No (Item_Node);
461          Append (Item_Node, Visible_Declarations (Def_Node));
462       end loop;
463
464       --  Deal with PRIVATE part (including graceful handling
465       --  of multiple PRIVATE parts).
466
467       Private_Loop : while Token = Tok_Private loop
468          if No (Private_Declarations (Def_Node)) then
469             Set_Private_Declarations (Def_Node, New_List);
470          else
471             Error_Msg_SC ("duplicate private part");
472          end if;
473
474          Scan; -- past PRIVATE
475
476          Declaration_Loop : loop
477             if Token = Tok_Identifier then
478                P_Component_Items (Private_Declarations (Def_Node));
479             else
480                Item_Node := P_Protected_Operation_Declaration_Opt;
481                exit Declaration_Loop when No (Item_Node);
482                Append (Item_Node, Private_Declarations (Def_Node));
483             end if;
484          end loop Declaration_Loop;
485       end loop Private_Loop;
486
487       End_Statements (Def_Node);
488       return Def_Node;
489    end P_Protected_Definition;
490
491    ------------------------------------------
492    -- 9.4  Protected Operation Declaration --
493    ------------------------------------------
494
495    --  PROTECTED_OPERATION_DECLARATION ::=
496    --    SUBPROGRAM_DECLARATION
497    --  | ENTRY_DECLARATION
498    --  | REPRESENTATION_CLAUSE
499
500    --  Error recovery: cannot raise Error_Resync
501
502    --  Note: a pragma can also be returned in this position
503
504    --  We are not currently permitting representation clauses to appear as
505    --  protected operation declarations, do we have to rethink this???
506
507    function P_Protected_Operation_Declaration_Opt return Node_Id is
508       L : List_Id;
509       P : Source_Ptr;
510
511    begin
512       --  This loop runs more than once only when a junk declaration
513       --  is skipped.
514
515       loop
516          if Token = Tok_Pragma then
517             return P_Pragma;
518
519          elsif Token = Tok_Entry then
520             return P_Entry_Declaration;
521
522          elsif Token = Tok_Function or else Token = Tok_Procedure then
523             return P_Subprogram (Pf_Decl);
524
525          elsif Token = Tok_Identifier then
526             L := New_List;
527             P := Token_Ptr;
528             Skip_Declaration (L);
529
530             if Nkind (First (L)) = N_Object_Declaration then
531                Error_Msg
532                  ("component must be declared in private part of " &
533                   "protected type", P);
534             else
535                Error_Msg
536                  ("illegal declaration in protected definition", P);
537             end if;
538
539          elsif Token in Token_Class_Declk then
540             Error_Msg_SC ("illegal declaration in protected definition");
541             Resync_Past_Semicolon;
542
543             --  Return now to avoid cascaded messages if next declaration
544             --  is a valid component declaration.
545
546             return Error;
547
548          elsif Token = Tok_For then
549             Error_Msg_SC
550               ("representation clause not allowed in protected definition");
551             Resync_Past_Semicolon;
552
553          else
554             return Empty;
555          end if;
556       end loop;
557    end P_Protected_Operation_Declaration_Opt;
558
559    -----------------------------------
560    -- 9.4  Protected Operation Item --
561    -----------------------------------
562
563    --  PROTECTED_OPERATION_ITEM ::=
564    --    SUBPROGRAM_DECLARATION
565    --  | SUBPROGRAM_BODY
566    --  | ENTRY_BODY
567    --  | REPRESENTATION_CLAUSE
568
569    --  This procedure parses and returns a list of protected operation items
570
571    --  We are not currently permitting representation clauses to appear
572    --  as protected operation items, do we have to rethink this???
573
574    function P_Protected_Operation_Items return List_Id is
575       Item_List : List_Id;
576
577    begin
578       Item_List := New_List;
579
580       loop
581          if Token = Tok_Entry or else Bad_Spelling_Of (Tok_Entry) then
582             Append (P_Entry_Body, Item_List);
583
584          elsif Token = Tok_Function or else Bad_Spelling_Of (Tok_Function)
585                  or else
586                Token = Tok_Procedure or else Bad_Spelling_Of (Tok_Procedure)
587          then
588             Append (P_Subprogram (Pf_Decl_Pbod), Item_List);
589
590          elsif Token = Tok_Pragma or else Bad_Spelling_Of (Tok_Pragma) then
591             P_Pragmas_Opt (Item_List);
592
593          elsif Token = Tok_Private or else Bad_Spelling_Of (Tok_Private) then
594             Error_Msg_SC ("PRIVATE not allowed in protected body");
595             Scan; -- past PRIVATE
596
597          elsif Token = Tok_Identifier then
598             Error_Msg_SC
599               ("all components must be declared in spec!");
600             Resync_Past_Semicolon;
601
602          elsif Token in Token_Class_Declk then
603             Error_Msg_SC ("this declaration not allowed in protected body");
604             Resync_Past_Semicolon;
605
606          else
607             exit;
608          end if;
609       end loop;
610
611       return Item_List;
612    end P_Protected_Operation_Items;
613
614    ------------------------------
615    -- 9.5.2  Entry Declaration --
616    ------------------------------
617
618    --  ENTRY_DECLARATION ::=
619    --    entry DEFINING_IDENTIFIER [(DISCRETE_SUBTYPE_DEFINITION)]
620    --      PARAMETER_PROFILE;
621
622    --  The caller has checked that the initial token is ENTRY
623
624    --  Error recovery: cannot raise Error_Resync
625
626    function P_Entry_Declaration return Node_Id is
627       Decl_Node  : Node_Id;
628       Scan_State : Saved_Scan_State;
629
630    begin
631       Decl_Node := New_Node (N_Entry_Declaration, Token_Ptr);
632       Scan; -- past ENTRY
633
634       Set_Defining_Identifier (Decl_Node, P_Defining_Identifier);
635
636       --  If left paren, could be (Discrete_Subtype_Definition) or Formal_Part
637
638       if Token = Tok_Left_Paren then
639          Scan; -- past (
640
641          --  If identifier after left paren, could still be either
642
643          if Token = Tok_Identifier then
644             Save_Scan_State (Scan_State); -- at Id
645             Scan; -- past Id
646
647             --  If comma or colon after Id, must be Formal_Part
648
649             if Token = Tok_Comma or else Token = Tok_Colon then
650                Restore_Scan_State (Scan_State); -- to Id
651                Set_Parameter_Specifications (Decl_Node, P_Formal_Part);
652
653             --  Else if Id wi no comma or colon, must be discrete subtype defn
654
655             else
656                Restore_Scan_State (Scan_State); -- to Id
657                Set_Discrete_Subtype_Definition
658                  (Decl_Node, P_Discrete_Subtype_Definition);
659                T_Right_Paren;
660                Set_Parameter_Specifications (Decl_Node, P_Parameter_Profile);
661             end if;
662
663          --  If no Id, must be discrete subtype definition
664
665          else
666             Set_Discrete_Subtype_Definition
667               (Decl_Node, P_Discrete_Subtype_Definition);
668             T_Right_Paren;
669             Set_Parameter_Specifications (Decl_Node, P_Parameter_Profile);
670          end if;
671       end if;
672
673       --  Error recovery check for illegal return
674
675       if Token = Tok_Return then
676          Error_Msg_SC ("entry cannot have return value!");
677          Scan;
678          Discard_Junk_Node (P_Subtype_Indication);
679       end if;
680
681       --  Error recovery check for improper use of entry barrier in spec
682
683       if Token = Tok_When then
684          Error_Msg_SC ("barrier not allowed here (belongs in body)");
685          Scan; -- past WHEN;
686          Discard_Junk_Node (P_Expression_No_Right_Paren);
687       end if;
688
689       TF_Semicolon;
690       return Decl_Node;
691    end P_Entry_Declaration;
692
693    -----------------------------
694    -- 9.5.2  Accept Statement --
695    -----------------------------
696
697    --  ACCEPT_STATEMENT ::=
698    --    accept entry_DIRECT_NAME
699    --      [(ENTRY_INDEX)] PARAMETER_PROFILE [do
700    --        HANDLED_SEQUENCE_OF_STATEMENTS
701    --    end [entry_IDENTIFIER]];
702
703    --  The caller has checked that the initial token is ACCEPT
704
705    --  Error recovery: cannot raise Error_Resync. If an error occurs, the
706    --  scan is resynchronized past the next semicolon and control returns.
707
708    function P_Accept_Statement return Node_Id is
709       Scan_State  : Saved_Scan_State;
710       Accept_Node : Node_Id;
711       Hand_Seq    : Node_Id;
712
713    begin
714       Push_Scope_Stack;
715       Scope.Table (Scope.Last).Sloc := Token_Ptr;
716       Scope.Table (Scope.Last).Ecol := Start_Column;
717
718       Accept_Node := New_Node (N_Accept_Statement, Token_Ptr);
719       Scan; -- past ACCEPT
720       Scope.Table (Scope.Last).Labl := Token_Node;
721
722       Set_Entry_Direct_Name (Accept_Node, P_Identifier);
723
724       --  Left paren could be (Entry_Index) or Formal_Part, determine which
725
726       if Token = Tok_Left_Paren then
727          Save_Scan_State (Scan_State); -- at left paren
728          Scan; -- past left paren
729
730          --  If first token after left paren not identifier, then Entry_Index
731
732          if Token /= Tok_Identifier then
733             Set_Entry_Index (Accept_Node, P_Expression);
734             T_Right_Paren;
735             Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile);
736
737          --  First token after left paren is identifier, could be either case
738
739          else -- Token = Tok_Identifier
740             Scan; -- past identifier
741
742             --  If identifier followed by comma or colon, must be Formal_Part
743
744             if Token = Tok_Comma or else Token = Tok_Colon then
745                Restore_Scan_State (Scan_State); -- to left paren
746                Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile);
747
748             --  If identifier not followed by comma/colon, must be entry index
749
750             else
751                Restore_Scan_State (Scan_State); -- to left paren
752                Scan; -- past left paren (again!)
753                Set_Entry_Index (Accept_Node, P_Expression);
754                T_Right_Paren;
755                Set_Parameter_Specifications (Accept_Node, P_Parameter_Profile);
756             end if;
757          end if;
758       end if;
759
760       --  Scan out DO if present
761
762       if Token = Tok_Do then
763          Scope.Table (Scope.Last).Etyp := E_Name;
764          Scope.Table (Scope.Last).Lreq := False;
765          Scan; -- past DO
766          Hand_Seq := P_Handled_Sequence_Of_Statements;
767          Set_Handled_Statement_Sequence (Accept_Node, Hand_Seq);
768          End_Statements (Handled_Statement_Sequence (Accept_Node));
769
770          --  Exception handlers not allowed in Ada 95 node
771
772          if Present (Exception_Handlers (Hand_Seq)) then
773             if Ada_83 then
774                Error_Msg_N
775                  ("(Ada 83) exception handlers in accept not allowed",
776                   First_Non_Pragma (Exception_Handlers (Hand_Seq)));
777             end if;
778          end if;
779
780       else
781          Pop_Scope_Stack; -- discard unused entry
782          TF_Semicolon;
783       end if;
784
785       return Accept_Node;
786
787    --  If error, resynchronize past semicolon
788
789    exception
790       when Error_Resync =>
791          Resync_Past_Semicolon;
792          Pop_Scope_Stack; -- discard unused entry
793          return Error;
794
795    end P_Accept_Statement;
796
797    ------------------------
798    -- 9.5.2  Entry Index --
799    ------------------------
800
801    --  Parsed by P_Expression (4.4)
802
803    -----------------------
804    -- 9.5.2  Entry Body --
805    -----------------------
806
807    --  ENTRY_BODY ::=
808    --    entry DEFINING_IDENTIFIER ENTRY_BODY_FORMAL_PART ENTRY_BARRIER is
809    --      DECLARATIVE_PART
810    --    begin
811    --      HANDLED_SEQUENCE_OF_STATEMENTS
812    --    end [entry_IDENTIFIER];
813
814    --  The caller has checked that the initial token is ENTRY
815
816    --  Error_Recovery: cannot raise Error_Resync
817
818    function P_Entry_Body return Node_Id is
819       Entry_Node       : Node_Id;
820       Formal_Part_Node : Node_Id;
821       Name_Node        : Node_Id;
822
823    begin
824       Push_Scope_Stack;
825       Entry_Node := New_Node (N_Entry_Body, Token_Ptr);
826       Scan; -- past ENTRY
827
828       Scope.Table (Scope.Last).Ecol := Start_Column;
829       Scope.Table (Scope.Last).Lreq := False;
830       Scope.Table (Scope.Last).Etyp := E_Name;
831
832       Name_Node := P_Defining_Identifier;
833       Set_Defining_Identifier (Entry_Node, Name_Node);
834       Scope.Table (Scope.Last).Labl := Name_Node;
835
836       Formal_Part_Node := P_Entry_Body_Formal_Part;
837       Set_Entry_Body_Formal_Part (Entry_Node, Formal_Part_Node);
838
839       Set_Condition (Formal_Part_Node, P_Entry_Barrier);
840       Parse_Decls_Begin_End (Entry_Node);
841       return Entry_Node;
842    end P_Entry_Body;
843
844    -----------------------------------
845    -- 9.5.2  Entry Body Formal Part --
846    -----------------------------------
847
848    --  ENTRY_BODY_FORMAL_PART ::=
849    --    [(ENTRY_INDEX_SPECIFICATION)] [PARAMETER_PART]
850
851    --  Error_Recovery: cannot raise Error_Resync
852
853    function P_Entry_Body_Formal_Part return Node_Id is
854       Fpart_Node : Node_Id;
855       Scan_State : Saved_Scan_State;
856
857    begin
858       Fpart_Node := New_Node (N_Entry_Body_Formal_Part, Token_Ptr);
859
860       --  See if entry index specification present, and if so parse it
861
862       if Token = Tok_Left_Paren then
863          Save_Scan_State (Scan_State); -- at left paren
864          Scan; -- past left paren
865
866          if Token = Tok_For then
867             Set_Entry_Index_Specification
868               (Fpart_Node, P_Entry_Index_Specification);
869             T_Right_Paren;
870          else
871             Restore_Scan_State (Scan_State); -- to left paren
872          end if;
873
874       --  Check for (common?) case of left paren omitted before FOR. This
875       --  is a tricky case, because the corresponding missing left paren
876       --  can cause real havoc if a formal part is present which gets
877       --  treated as part of the discrete subtype definition of the
878       --  entry index specification, so just give error and resynchronize
879
880       elsif Token = Tok_For then
881          T_Left_Paren; -- to give error message
882          Resync_To_When;
883       end if;
884
885       Set_Parameter_Specifications (Fpart_Node, P_Parameter_Profile);
886       return Fpart_Node;
887    end P_Entry_Body_Formal_Part;
888
889    --------------------------
890    -- 9.5.2  Entry Barrier --
891    --------------------------
892
893    --  ENTRY_BARRIER ::= when CONDITION
894
895    --  Error_Recovery: cannot raise Error_Resync
896
897    function P_Entry_Barrier return Node_Id is
898       Bnode : Node_Id;
899
900    begin
901       if Token = Tok_When then
902          Scan; -- past WHEN;
903          Bnode := P_Expression_No_Right_Paren;
904
905          if Token = Tok_Colon_Equal then
906             Error_Msg_SC (""":="" should be ""=""");
907             Scan;
908             Bnode := P_Expression_No_Right_Paren;
909          end if;
910
911       else
912          T_When; -- to give error message
913          Bnode := Error;
914       end if;
915
916       TF_Is;
917       return Bnode;
918    end P_Entry_Barrier;
919
920    --------------------------------------
921    -- 9.5.2  Entry Index Specification --
922    --------------------------------------
923
924    --  ENTRY_INDEX_SPECIFICATION ::=
925    --    for DEFINING_IDENTIFIER in DISCRETE_SUBTYPE_DEFINITION
926
927    --  Error recovery: can raise Error_Resync
928
929    function P_Entry_Index_Specification return Node_Id is
930       Iterator_Node : Node_Id;
931
932    begin
933       Iterator_Node := New_Node (N_Entry_Index_Specification, Token_Ptr);
934       T_For; -- past FOR
935       Set_Defining_Identifier (Iterator_Node, P_Defining_Identifier);
936       T_In;
937       Set_Discrete_Subtype_Definition
938         (Iterator_Node, P_Discrete_Subtype_Definition);
939       return Iterator_Node;
940    end P_Entry_Index_Specification;
941
942    ---------------------------------
943    -- 9.5.3  Entry Call Statement --
944    ---------------------------------
945
946    --  Parsed by P_Name (4.1). Within a select, an entry call is parsed
947    --  by P_Select_Statement (9.7)
948
949    ------------------------------
950    -- 9.5.4  Requeue Statement --
951    ------------------------------
952
953    --  REQUEUE_STATEMENT ::= requeue entry_NAME [with abort];
954
955    --  The caller has checked that the initial token is requeue
956
957    --  Error recovery: can raise Error_Resync
958
959    function P_Requeue_Statement return Node_Id is
960       Requeue_Node : Node_Id;
961
962    begin
963       Requeue_Node := New_Node (N_Requeue_Statement, Token_Ptr);
964       Scan; -- past REQUEUE
965       Set_Name (Requeue_Node, P_Name);
966
967       if Token = Tok_With then
968          Scan; -- past WITH
969          T_Abort;
970          Set_Abort_Present (Requeue_Node, True);
971       end if;
972
973       TF_Semicolon;
974       return Requeue_Node;
975    end P_Requeue_Statement;
976
977    --------------------------
978    -- 9.6  Delay Statement --
979    --------------------------
980
981    --  DELAY_STATEMENT ::=
982    --    DELAY_UNTIL_STATEMENT
983    --  | DELAY_RELATIVE_STATEMENT
984
985    --  The caller has checked that the initial token is DELAY
986
987    --  Error recovery: cannot raise Error_Resync
988
989    function P_Delay_Statement return Node_Id is
990    begin
991       Scan; -- past DELAY
992
993       --  The following check for delay until misused in Ada 83 doesn't catch
994       --  all cases, but it's good enough to catch most of them!
995
996       if Token_Name = Name_Until then
997          Check_95_Keyword (Tok_Until, Tok_Left_Paren);
998          Check_95_Keyword (Tok_Until, Tok_Identifier);
999       end if;
1000
1001       if Token = Tok_Until then
1002          return P_Delay_Until_Statement;
1003       else
1004          return P_Delay_Relative_Statement;
1005       end if;
1006    end P_Delay_Statement;
1007
1008    --------------------------------
1009    -- 9.6  Delay Until Statement --
1010    --------------------------------
1011
1012    --  DELAY_UNTIL_STATEMENT ::= delay until delay_EXPRESSION;
1013
1014    --  The caller has checked that the initial token is DELAY, scanned it
1015    --  out and checked that the current token is UNTIL
1016
1017    --  Error recovery: cannot raise Error_Resync
1018
1019    function P_Delay_Until_Statement return Node_Id is
1020       Delay_Node : Node_Id;
1021
1022    begin
1023       Delay_Node := New_Node (N_Delay_Until_Statement, Prev_Token_Ptr);
1024       Scan; -- past UNTIL
1025       Set_Expression (Delay_Node, P_Expression_No_Right_Paren);
1026       TF_Semicolon;
1027       return Delay_Node;
1028    end P_Delay_Until_Statement;
1029
1030    -----------------------------------
1031    -- 9.6  Delay Relative Statement --
1032    -----------------------------------
1033
1034    --  DELAY_RELATIVE_STATEMENT ::= delay delay_EXPRESSION;
1035
1036    --  The caller has checked that the initial token is DELAY, scanned it
1037    --  out and determined that the current token is not UNTIL
1038
1039    --  Error recovery: cannot raise Error_Resync
1040
1041    function P_Delay_Relative_Statement return Node_Id is
1042       Delay_Node : Node_Id;
1043
1044    begin
1045       Delay_Node := New_Node (N_Delay_Relative_Statement, Prev_Token_Ptr);
1046       Set_Expression (Delay_Node, P_Expression_No_Right_Paren);
1047       Check_Simple_Expression_In_Ada_83 (Expression (Delay_Node));
1048       TF_Semicolon;
1049       return Delay_Node;
1050    end P_Delay_Relative_Statement;
1051
1052    ---------------------------
1053    -- 9.7  Select Statement --
1054    ---------------------------
1055
1056    --  SELECT_STATEMENT ::=
1057    --    SELECTIVE_ACCEPT
1058    --  | TIMED_ENTRY_CALL
1059    --  | CONDITIONAL_ENTRY_CALL
1060    --  | ASYNCHRONOUS_SELECT
1061
1062    --  SELECTIVE_ACCEPT ::=
1063    --    select
1064    --      [GUARD]
1065    --        SELECT_ALTERNATIVE
1066    --    {or
1067    --      [GUARD]
1068    --        SELECT_ALTERNATIVE
1069    --    [else
1070    --      SEQUENCE_OF_STATEMENTS]
1071    --    end select;
1072
1073    --  GUARD ::= when CONDITION =>
1074
1075    --  Note: the guard preceding a select alternative is included as part
1076    --  of the node generated for a selective accept alternative.
1077
1078    --  SELECT_ALTERNATIVE ::=
1079    --    ACCEPT_ALTERNATIVE
1080    --  | DELAY_ALTERNATIVE
1081    --  | TERMINATE_ALTERNATIVE
1082
1083    --  TIMED_ENTRY_CALL ::=
1084    --    select
1085    --      ENTRY_CALL_ALTERNATIVE
1086    --    or
1087    --      DELAY_ALTERNATIVE
1088    --    end select;
1089
1090    --  CONDITIONAL_ENTRY_CALL ::=
1091    --    select
1092    --      ENTRY_CALL_ALTERNATIVE
1093    --    else
1094    --      SEQUENCE_OF_STATEMENTS
1095    --    end select;
1096
1097    --  ENTRY_CALL_ALTERNATIVE ::=
1098    --    ENTRY_CALL_STATEMENT [SEQUENCE_OF_STATEMENTS]
1099
1100    --  ASYNCHRONOUS_SELECT ::=
1101    --    select
1102    --      TRIGGERING_ALTERNATIVE
1103    --    then abort
1104    --      ABORTABLE_PART
1105    --    end select;
1106
1107    --  TRIGGERING_ALTERNATIVE ::=
1108    --    TRIGGERING_STATEMENT [SEQUENCE_OF_STATEMENTS]
1109
1110    --  TRIGGERING_STATEMENT ::= ENTRY_CALL_STATEMENT | DELAY_STATEMENT
1111
1112    --  The caller has checked that the initial token is SELECT
1113
1114    --  Error recovery: can raise Error_Resync
1115
1116    function P_Select_Statement return Node_Id is
1117       Select_Node    : Node_Id;
1118       Select_Sloc    : Source_Ptr;
1119       Stmnt_Sloc     : Source_Ptr;
1120       Ecall_Node     : Node_Id;
1121       Alternative    : Node_Id;
1122       Select_Pragmas : List_Id;
1123       Alt_Pragmas    : List_Id;
1124       Statement_List : List_Id;
1125       Alt_List       : List_Id;
1126       Cond_Expr      : Node_Id;
1127       Delay_Stmnt    : Node_Id;
1128
1129    begin
1130       Push_Scope_Stack;
1131       Scope.Table (Scope.Last).Etyp := E_Select;
1132       Scope.Table (Scope.Last).Ecol := Start_Column;
1133       Scope.Table (Scope.Last).Sloc := Token_Ptr;
1134       Scope.Table (Scope.Last).Labl := Error;
1135
1136       Select_Sloc := Token_Ptr;
1137       Scan; -- past SELECT
1138       Stmnt_Sloc := Token_Ptr;
1139       Select_Pragmas := P_Pragmas_Opt;
1140
1141       --  If first token after select is designator, then we have an entry
1142       --  call, which must be the start of a conditional entry call, timed
1143       --  entry call or asynchronous select
1144
1145       if Token in Token_Class_Desig then
1146
1147          --  Scan entry call statement
1148
1149          begin
1150             Ecall_Node := P_Name;
1151
1152             --  ??  The following two clauses exactly parallel code in ch5
1153             --      and should be commoned sometime
1154
1155             if Nkind (Ecall_Node) = N_Indexed_Component then
1156                declare
1157                   Prefix_Node : constant Node_Id := Prefix (Ecall_Node);
1158                   Exprs_Node  : constant List_Id := Expressions (Ecall_Node);
1159
1160                begin
1161                   Change_Node (Ecall_Node, N_Procedure_Call_Statement);
1162                   Set_Name (Ecall_Node, Prefix_Node);
1163                   Set_Parameter_Associations (Ecall_Node, Exprs_Node);
1164                end;
1165
1166             elsif Nkind (Ecall_Node) = N_Function_Call then
1167                declare
1168                   Fname_Node  : constant Node_Id := Name (Ecall_Node);
1169                   Params_List : constant List_Id :=
1170                                   Parameter_Associations (Ecall_Node);
1171
1172                begin
1173                   Change_Node (Ecall_Node, N_Procedure_Call_Statement);
1174                   Set_Name (Ecall_Node, Fname_Node);
1175                   Set_Parameter_Associations (Ecall_Node, Params_List);
1176                end;
1177
1178             elsif Nkind (Ecall_Node) = N_Identifier
1179               or else Nkind (Ecall_Node) = N_Selected_Component
1180             then
1181                --  Case of a call to a parameterless entry.
1182
1183                declare
1184                   C_Node : constant Node_Id :=
1185                          New_Node (N_Procedure_Call_Statement, Stmnt_Sloc);
1186                begin
1187                   Set_Name (C_Node, Ecall_Node);
1188                   Set_Parameter_Associations (C_Node, No_List);
1189                   Ecall_Node := C_Node;
1190                end;
1191             end if;
1192
1193             TF_Semicolon;
1194
1195          exception
1196             when Error_Resync =>
1197                Resync_Past_Semicolon;
1198                return Error;
1199          end;
1200
1201          Statement_List := P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm);
1202
1203          --  OR follows, we have a timed entry call
1204
1205          if Token = Tok_Or then
1206             Scan; -- past OR
1207             Alt_Pragmas := P_Pragmas_Opt;
1208
1209             Select_Node := New_Node (N_Timed_Entry_Call, Select_Sloc);
1210             Set_Entry_Call_Alternative (Select_Node,
1211               Make_Entry_Call_Alternative (Stmnt_Sloc,
1212                 Entry_Call_Statement => Ecall_Node,
1213                 Pragmas_Before       => Select_Pragmas,
1214                 Statements           => Statement_List));
1215
1216             --  Only possibility is delay alternative. If we have anything
1217             --  else, give message, and treat as conditional entry call.
1218
1219             if Token /= Tok_Delay then
1220                Error_Msg_SC
1221                  ("only allowed alternative in timed entry call is delay!");
1222                Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq));
1223                Set_Delay_Alternative (Select_Node, Error);
1224
1225             else
1226                Set_Delay_Alternative (Select_Node, P_Delay_Alternative);
1227                Set_Pragmas_Before
1228                  (Delay_Alternative (Select_Node), Alt_Pragmas);
1229             end if;
1230
1231          --  ELSE follows, we have a conditional entry call
1232
1233          elsif Token = Tok_Else then
1234             Scan; -- past ELSE
1235             Select_Node := New_Node (N_Conditional_Entry_Call, Select_Sloc);
1236
1237             Set_Entry_Call_Alternative (Select_Node,
1238               Make_Entry_Call_Alternative (Stmnt_Sloc,
1239                 Entry_Call_Statement => Ecall_Node,
1240                 Pragmas_Before       => Select_Pragmas,
1241                 Statements           => Statement_List));
1242
1243             Set_Else_Statements
1244               (Select_Node, P_Sequence_Of_Statements (SS_Sreq));
1245
1246          --  Only remaining case is THEN ABORT (asynchronous select)
1247
1248          elsif Token = Tok_Abort then
1249             Select_Node :=
1250               Make_Asynchronous_Select (Select_Sloc,
1251                 Triggering_Alternative =>
1252                   Make_Triggering_Alternative (Stmnt_Sloc,
1253                     Triggering_Statement => Ecall_Node,
1254                     Pragmas_Before       => Select_Pragmas,
1255                     Statements           => Statement_List),
1256                 Abortable_Part => P_Abortable_Part);
1257
1258          --  Else error
1259
1260          else
1261             if Ada_83 then
1262                Error_Msg_BC ("OR or ELSE expected");
1263             else
1264                Error_Msg_BC ("OR or ELSE or THEN ABORT expected");
1265             end if;
1266
1267             Select_Node := Error;
1268          end if;
1269
1270          End_Statements;
1271
1272       --  Here we have a selective accept or an an asynchronous select (first
1273       --  token after SELECT is other than a designator token).
1274
1275       else
1276          --  If we have delay with no guard, could be asynchronous select
1277
1278          if Token = Tok_Delay then
1279             Delay_Stmnt := P_Delay_Statement;
1280             Statement_List := P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm);
1281
1282             --  Asynchronous select
1283
1284             if Token = Tok_Abort then
1285                Select_Node :=
1286                  Make_Asynchronous_Select (Select_Sloc,
1287                    Triggering_Alternative =>
1288                      Make_Triggering_Alternative (Stmnt_Sloc,
1289                        Triggering_Statement => Delay_Stmnt,
1290                        Pragmas_Before       => Select_Pragmas,
1291                        Statements           => Statement_List),
1292                      Abortable_Part => P_Abortable_Part);
1293
1294                End_Statements;
1295                return Select_Node;
1296
1297             --  Delay which was not an asynchronous select. Must be a selective
1298             --  accept, and since at least one accept statement is required,
1299             --  we must have at least one OR phrase present.
1300
1301             else
1302                Alt_List := New_List (
1303                  Make_Delay_Alternative (Stmnt_Sloc,
1304                    Delay_Statement => Delay_Stmnt,
1305                    Pragmas_Before  => Select_Pragmas,
1306                    Statements      => Statement_List));
1307                T_Or;
1308                Alt_Pragmas := P_Pragmas_Opt;
1309             end if;
1310
1311          --  If not a delay statement, then must be another possibility for
1312          --  a selective accept alternative, or perhaps a guard is present
1313
1314          else
1315             Alt_List := New_List;
1316             Alt_Pragmas := Select_Pragmas;
1317          end if;
1318
1319          Select_Node := New_Node (N_Selective_Accept, Select_Sloc);
1320          Set_Select_Alternatives (Select_Node, Alt_List);
1321
1322          --  Scan out selective accept alternatives. On entry to this loop,
1323          --  we are just past a SELECT or OR token, and any pragmas that
1324          --  immediately follow the SELECT or OR are in Alt_Pragmas.
1325
1326          loop
1327             if Token = Tok_When then
1328
1329                if Present (Alt_Pragmas) then
1330                   Error_Msg_SC ("pragmas may not precede guard");
1331                end if;
1332
1333                Scan; --  past WHEN
1334                Cond_Expr := P_Expression_No_Right_Paren;
1335                T_Arrow;
1336                Alt_Pragmas := P_Pragmas_Opt;
1337
1338             else
1339                Cond_Expr := Empty;
1340             end if;
1341
1342             if Token = Tok_Accept then
1343                Alternative := P_Accept_Alternative;
1344
1345                --  Check for junk attempt at asynchronous select using
1346                --  an Accept alternative as the triggering statement
1347
1348                if Token = Tok_Abort
1349                  and then Is_Empty_List (Alt_List)
1350                  and then No (Cond_Expr)
1351                then
1352                   Error_Msg
1353                     ("triggering statement must be entry call or delay",
1354                      Sloc (Alternative));
1355                   Scan; -- past junk ABORT
1356                   Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq));
1357                   End_Statements;
1358                   return Error;
1359                end if;
1360
1361             elsif Token = Tok_Delay then
1362                Alternative := P_Delay_Alternative;
1363
1364             elsif Token = Tok_Terminate then
1365                Alternative := P_Terminate_Alternative;
1366
1367             else
1368                Error_Msg_SC
1369                  ("Select alternative (ACCEPT, ABORT, DELAY) expected");
1370                Alternative := Error;
1371
1372                if Token = Tok_Semicolon then
1373                   Scan; -- past junk semicolon
1374                end if;
1375             end if;
1376
1377             --  THEN ABORT at this stage is just junk
1378
1379             if Token = Tok_Abort then
1380                Error_Msg_SP ("misplaced `THEN ABORT`");
1381                Scan; -- past junk ABORT
1382                Discard_Junk_List (P_Sequence_Of_Statements (SS_Sreq));
1383                End_Statements;
1384                return Error;
1385
1386             else
1387                if Alternative /= Error then
1388                   Set_Condition (Alternative, Cond_Expr);
1389                   Set_Pragmas_Before (Alternative, Alt_Pragmas);
1390                   Append (Alternative, Alt_List);
1391                end if;
1392
1393                exit when Token /= Tok_Or;
1394             end if;
1395
1396             T_Or;
1397             Alt_Pragmas := P_Pragmas_Opt;
1398          end loop;
1399
1400          if Token = Tok_Else then
1401             Scan; -- past ELSE
1402             Set_Else_Statements
1403               (Select_Node, P_Sequence_Of_Statements (SS_Ortm_Sreq));
1404
1405             if Token = Tok_Or then
1406                Error_Msg_SC ("select alternative cannot follow else part!");
1407             end if;
1408          end if;
1409
1410          End_Statements;
1411       end if;
1412
1413       return Select_Node;
1414    end P_Select_Statement;
1415
1416    -----------------------------
1417    -- 9.7.1  Selective Accept --
1418    -----------------------------
1419
1420    --  Parsed by P_Select_Statement (9.7)
1421
1422    ------------------
1423    -- 9.7.1  Guard --
1424    ------------------
1425
1426    --  Parsed by P_Select_Statement (9.7)
1427
1428    -------------------------------
1429    -- 9.7.1  Select Alternative --
1430    -------------------------------
1431
1432    --  SELECT_ALTERNATIVE ::=
1433    --    ACCEPT_ALTERNATIVE
1434    --  | DELAY_ALTERNATIVE
1435    --  | TERMINATE_ALTERNATIVE
1436
1437    --  Note: the guard preceding a select alternative is included as part
1438    --  of the node generated for a selective accept alternative.
1439
1440    --  Error recovery: cannot raise Error_Resync
1441
1442    -------------------------------
1443    -- 9.7.1  Accept Alternative --
1444    -------------------------------
1445
1446    --  ACCEPT_ALTERNATIVE ::=
1447    --    ACCEPT_STATEMENT [SEQUENCE_OF_STATEMENTS]
1448
1449    --  Error_Recovery: Cannot raise Error_Resync
1450
1451    --  Note: the caller is responsible for setting the Pragmas_Before
1452    --  field of the returned N_Terminate_Alternative node.
1453
1454    function P_Accept_Alternative return Node_Id is
1455       Accept_Alt_Node : Node_Id;
1456
1457    begin
1458       Accept_Alt_Node := New_Node (N_Accept_Alternative, Token_Ptr);
1459       Set_Accept_Statement (Accept_Alt_Node, P_Accept_Statement);
1460
1461       --  Note: the reason that we accept THEN ABORT as a terminator for
1462       --  the sequence of statements is for error recovery which allows
1463       --  for misuse of an accept statement as a triggering statememt.
1464
1465       Set_Statements
1466         (Accept_Alt_Node, P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm));
1467       return Accept_Alt_Node;
1468    end P_Accept_Alternative;
1469
1470    ------------------------------
1471    -- 9.7.1  Delay Alternative --
1472    ------------------------------
1473
1474    --  DELAY_ALTERNATIVE ::=
1475    --    DELAY_STATEMENT [SEQUENCE_OF_STATEMENTS]
1476
1477    --  Error_Recovery: Cannot raise Error_Resync
1478
1479    --  Note: the caller is responsible for setting the Pragmas_Before
1480    --  field of the returned N_Terminate_Alternative node.
1481
1482    function P_Delay_Alternative return Node_Id is
1483       Delay_Alt_Node : Node_Id;
1484
1485    begin
1486       Delay_Alt_Node := New_Node (N_Delay_Alternative, Token_Ptr);
1487       Set_Delay_Statement (Delay_Alt_Node, P_Delay_Statement);
1488
1489       --  Note: the reason that we accept THEN ABORT as a terminator for
1490       --  the sequence of statements is for error recovery which allows
1491       --  for misuse of an accept statement as a triggering statememt.
1492
1493       Set_Statements
1494         (Delay_Alt_Node, P_Sequence_Of_Statements (SS_Eltm_Ortm_Tatm));
1495       return Delay_Alt_Node;
1496    end P_Delay_Alternative;
1497
1498    ----------------------------------
1499    -- 9.7.1  Terminate Alternative --
1500    ----------------------------------
1501
1502    --  TERMINATE_ALTERNATIVE ::= terminate;
1503
1504    --  Error_Recovery: Cannot raise Error_Resync
1505
1506    --  Note: the caller is responsible for setting the Pragmas_Before
1507    --  field of the returned N_Terminate_Alternative node.
1508
1509    function P_Terminate_Alternative return Node_Id is
1510       Terminate_Alt_Node : Node_Id;
1511
1512    begin
1513       Terminate_Alt_Node := New_Node (N_Terminate_Alternative, Token_Ptr);
1514       Scan; -- past TERMINATE
1515       TF_Semicolon;
1516
1517       --  For all other select alternatives, the sequence of statements
1518       --  after the alternative statement will swallow up any pragmas
1519       --  coming in this position. But the terminate alternative has no
1520       --  sequence of statements, so the pragmas here must be treated
1521       --  specially.
1522
1523       Set_Pragmas_After (Terminate_Alt_Node, P_Pragmas_Opt);
1524       return Terminate_Alt_Node;
1525    end P_Terminate_Alternative;
1526
1527    -----------------------------
1528    -- 9.7.2  Timed Entry Call --
1529    -----------------------------
1530
1531    --  Parsed by P_Select_Statement (9.7)
1532
1533    -----------------------------------
1534    -- 9.7.2  Entry Call Alternative --
1535    -----------------------------------
1536
1537    --  Parsed by P_Select_Statement (9.7)
1538
1539    -----------------------------------
1540    -- 9.7.3  Conditional Entry Call --
1541    -----------------------------------
1542
1543    --  Parsed by P_Select_Statement (9.7)
1544
1545    --------------------------------
1546    -- 9.7.4  Asynchronous Select --
1547    --------------------------------
1548
1549    --  Parsed by P_Select_Statement (9.7)
1550
1551    -----------------------------------
1552    -- 9.7.4  Triggering Alternative --
1553    -----------------------------------
1554
1555    --  Parsed by P_Select_Statement (9.7)
1556
1557    ---------------------------------
1558    -- 9.7.4  Triggering Statement --
1559    ---------------------------------
1560
1561    --  Parsed by P_Select_Statement (9.7)
1562
1563    ---------------------------
1564    -- 9.7.4  Abortable Part --
1565    ---------------------------
1566
1567    --  ABORTABLE_PART ::= SEQUENCE_OF_STATEMENTS
1568
1569    --  The caller has verified that THEN ABORT is present, and Token is
1570    --  pointing to the ABORT on entry (or if not, then we have an error)
1571
1572    --  Error recovery: cannot raise Error_Resync
1573
1574    function P_Abortable_Part return Node_Id is
1575       Abortable_Part_Node : Node_Id;
1576
1577    begin
1578       Abortable_Part_Node := New_Node (N_Abortable_Part, Token_Ptr);
1579       T_Abort; -- scan past ABORT
1580
1581       if Ada_83 then
1582          Error_Msg_SP ("(Ada 83) asynchronous select not allowed!");
1583       end if;
1584
1585       Set_Statements (Abortable_Part_Node, P_Sequence_Of_Statements (SS_Sreq));
1586       return Abortable_Part_Node;
1587    end P_Abortable_Part;
1588
1589    --------------------------
1590    -- 9.8  Abort Statement --
1591    --------------------------
1592
1593    --  ABORT_STATEMENT ::= abort task_NAME {, task_NAME};
1594
1595    --  The caller has checked that the initial token is ABORT
1596
1597    --  Error recovery: cannot raise Error_Resync
1598
1599    function P_Abort_Statement return Node_Id is
1600       Abort_Node : Node_Id;
1601
1602    begin
1603       Abort_Node := New_Node (N_Abort_Statement, Token_Ptr);
1604       Scan; -- past ABORT
1605       Set_Names (Abort_Node, New_List);
1606
1607       loop
1608          Append (P_Name, Names (Abort_Node));
1609          exit when Token /= Tok_Comma;
1610          Scan; -- past comma
1611       end loop;
1612
1613       TF_Semicolon;
1614       return Abort_Node;
1615    end P_Abort_Statement;
1616
1617 end Ch9;