OSDN Git Service

2005-02-09 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-ch2.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                              P A R . C H 2                               --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2005 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 Ch2 is
33
34    --  Local functions, used only in this chapter
35
36    function P_Pragma_Argument_Association return Node_Id;
37
38    ---------------------
39    -- 2.3  Identifier --
40    ---------------------
41
42    --  IDENTIFIER ::= LETTER {[UNDERLINE] LETTER_OR_DIGIT}
43
44    --  LETTER_OR_DIGIT ::= IDENTIFIER_LETTER | DIGIT
45
46    --  An IDENTIFIER shall not be a reserved word
47
48    --  Error recovery: can raise Error_Resync (cannot return Error)
49
50    function P_Identifier (C : Id_Check := None) return Node_Id is
51       Ident_Node : Node_Id;
52
53    begin
54       --  All set if we do indeed have an identifier
55
56       if Token = Tok_Identifier then
57
58          --  Ada 2005 (AI-284): Compiling in Ada95 mode we notify
59          --  that interface, overriding, and synchronized are
60          --  new reserved words
61
62          if Ada_Version = Ada_95 then
63             if Token_Name = Name_Overriding
64               or else Token_Name = Name_Synchronized
65               or else (Token_Name = Name_Interface
66                         and then Prev_Token /= Tok_Pragma)
67             then
68                Error_Msg_N ("& is a reserved word in Ada 2005?", Token_Node);
69             end if;
70          end if;
71
72          Ident_Node := Token_Node;
73          Scan; -- past Identifier
74          return Ident_Node;
75
76       --  If we have a reserved identifier, manufacture an identifier with
77       --  a corresponding name after posting an appropriate error message
78
79       elsif Is_Reserved_Identifier (C) then
80          Scan_Reserved_Identifier (Force_Msg => False);
81          Ident_Node := Token_Node;
82          Scan; -- past the node
83          return Ident_Node;
84
85       --  Otherwise we have junk that cannot be interpreted as an identifier
86
87       else
88          T_Identifier; -- to give message
89          raise Error_Resync;
90       end if;
91    end P_Identifier;
92
93    --------------------------
94    -- 2.3  Letter Or Digit --
95    --------------------------
96
97    --  Parsed by P_Identifier (2.3)
98
99    --------------------------
100    -- 2.4  Numeric Literal --
101    --------------------------
102
103    --  NUMERIC_LITERAL ::= DECIMAL_LITERAL | BASED_LITERAL
104
105    --  Numeric literal is returned by the scanner as either
106    --  Tok_Integer_Literal or Tok_Real_Literal
107
108    ----------------------------
109    -- 2.4.1  Decimal Literal --
110    ----------------------------
111
112    --  DECIMAL_LITERAL ::= NUMERAL [.NUMERAL] [EXPONENT]
113
114    --  Handled by scanner as part of numeric lIteral handing (see 2.4)
115
116    --------------------
117    -- 2.4.1  Numeral --
118    --------------------
119
120    --  NUMERAL ::= DIGIT {[UNDERLINE] DIGIT}
121
122    --  Handled by scanner as part of numeric literal handling (see 2.4)
123
124    ---------------------
125    -- 2.4.1  Exponent --
126    ---------------------
127
128    --  EXPONENT ::= E [+] NUMERAL | E - NUMERAL
129
130    --  Handled by scanner as part of numeric literal handling (see 2.4)
131
132    --------------------------
133    -- 2.4.2  Based Literal --
134    --------------------------
135
136    --  BASED_LITERAL ::=
137    --   BASE # BASED_NUMERAL [.BASED_NUMERAL] # [EXPONENT]
138
139    --  Handled by scanner as part of numeric literal handling (see 2.4)
140
141    -----------------
142    -- 2.4.2  Base --
143    -----------------
144
145    --  BASE ::= NUMERAL
146
147    --  Handled by scanner as part of numeric literal handling (see 2.4)
148
149    --------------------------
150    -- 2.4.2  Based Numeral --
151    --------------------------
152
153    --  BASED_NUMERAL ::=
154    --    EXTENDED_DIGIT {[UNDERLINE] EXTENDED_DIGIT}
155
156    --  Handled by scanner as part of numeric literal handling (see 2.4)
157
158    ---------------------------
159    -- 2.4.2  Extended Digit --
160    ---------------------------
161
162    --  EXTENDED_DIGIT ::= DIGIT | A | B | C | D | E | F
163
164    --  Handled by scanner as part of numeric literal handling (see 2.4)
165
166    ----------------------------
167    -- 2.5  Character Literal --
168    ----------------------------
169
170    --  CHARACTER_LITERAL ::= ' GRAPHIC_CHARACTER '
171
172    --  Handled by the scanner and returned as Tok_Character_Literal
173
174    -------------------------
175    -- 2.6  String Literal --
176    -------------------------
177
178    --  STRING LITERAL ::= "{STRING_ELEMENT}"
179
180    --  Handled by the scanner and returned as Tok_Character_Literal
181    --  or if the string looks like an operator as Tok_Operator_Symbol.
182
183    -------------------------
184    -- 2.6  String Element --
185    -------------------------
186
187    --  STRING_ELEMENT ::= "" | non-quotation_mark_GRAPHIC_CHARACTER
188
189    --  A STRING_ELEMENT is either a pair of quotation marks ("),
190    --  or a single GRAPHIC_CHARACTER other than a quotation mark.
191
192    --  Handled by scanner as part of string literal handling (see 2.4)
193
194    ------------------
195    -- 2.7  Comment --
196    ------------------
197
198    --  A COMMENT starts with two adjacent hyphens and extends up to the
199    --  end of the line. A COMMENT may appear on any line of a program.
200
201    --  Handled by the scanner which simply skips past encountered comments
202
203    -----------------
204    -- 2.8  Pragma --
205    -----------------
206
207    --  PRAGMA ::= pragma IDENTIFIER
208    --    [(PRAGMA_ARGUMENT_ASSOCIATION {, PRAGMA_ARGUMENT_ASSOCIATION})];
209
210    --  The caller has checked that the initial token is PRAGMA
211
212    --  Error recovery: cannot raise Error_Resync
213
214    --  One special piece of processing is needed in this routine. As described
215    --  in the section on "Handling semicolon used in place of IS" in module
216    --  Parse, the parser detects the case of missing subprogram bodies to
217    --  allow recovery from this syntactic error. Pragma INTERFACE (and, for
218    --  Ada 95, pragma IMPORT) can appear in place of the body. The parser must
219    --  recognize the use of these two pragmas in this context, otherwise it
220    --  will think there are missing bodies, and try to change ; to IS, when
221    --  in fact the bodies ARE present, supplied by these pragmas.
222
223    function P_Pragma return Node_Id is
224
225       Interface_Check_Required : Boolean := False;
226       --  Set True if check of pragma INTERFACE is required
227
228       Import_Check_Required : Boolean := False;
229       --  Set True if check of pragma IMPORT is required
230
231       Arg_Count : Int := 0;
232       --  Number of argument associations processed
233
234       Pragma_Node   : Node_Id;
235       Pragma_Name   : Name_Id;
236       Semicolon_Loc : Source_Ptr;
237       Ident_Node    : Node_Id;
238       Assoc_Node    : Node_Id;
239       Result        : Node_Id;
240
241       procedure Skip_Pragma_Semicolon;
242       --  Skip past semicolon at end of pragma
243
244       ---------------------------
245       -- Skip_Pragma_Semicolon --
246       ---------------------------
247
248       procedure Skip_Pragma_Semicolon is
249       begin
250          if Token /= Tok_Semicolon then
251             T_Semicolon;
252             Resync_Past_Semicolon;
253          else
254             Scan; -- past semicolon
255          end if;
256       end Skip_Pragma_Semicolon;
257
258    --  Start of processing for P_Pragma
259
260    begin
261       Pragma_Node := New_Node (N_Pragma, Token_Ptr);
262       Scan; -- past PRAGMA
263       Pragma_Name := Token_Name;
264
265       if Style_Check then
266          Style.Check_Pragma_Name;
267       end if;
268
269       --  Ada 2005 (AI-284): INTERFACE is a new reserved word but it is
270       --  allowed as a pragma name.
271
272       if Ada_Version >= Ada_05
273         and then Token = Tok_Interface
274       then
275          Pragma_Name := Name_Interface;
276          Ident_Node  := Token_Node;
277          Scan; -- past INTERFACE
278       else
279          Ident_Node := P_Identifier;
280          Delete_Node (Ident_Node);
281       end if;
282
283       Set_Chars (Pragma_Node, Pragma_Name);
284
285       --  See if special INTERFACE/IMPORT check is required
286
287       if SIS_Entry_Active then
288          Interface_Check_Required := (Pragma_Name = Name_Interface);
289          Import_Check_Required    := (Pragma_Name = Name_Import);
290       else
291          Interface_Check_Required := False;
292          Import_Check_Required    := False;
293       end if;
294
295       --  Scan arguments. We assume that arguments are present if there is
296       --  a left paren, or if a semicolon is missing and there is another
297       --  token on the same line as the pragma name.
298
299       if Token = Tok_Left_Paren
300         or else (Token /= Tok_Semicolon
301                    and then not Token_Is_At_Start_Of_Line)
302       then
303          Set_Pragma_Argument_Associations (Pragma_Node, New_List);
304          T_Left_Paren;
305
306          loop
307             Arg_Count := Arg_Count + 1;
308             Assoc_Node := P_Pragma_Argument_Association;
309
310             if Arg_Count = 2
311               and then (Interface_Check_Required or else Import_Check_Required)
312             then
313                --  Here is where we cancel the SIS active status if this pragma
314                --  supplies a body for the currently active subprogram spec.
315
316                if Nkind (Expression (Assoc_Node)) in N_Direct_Name
317                  and then Chars (Expression (Assoc_Node)) = Chars (SIS_Labl)
318                then
319                   SIS_Entry_Active := False;
320                end if;
321             end if;
322
323             Append (Assoc_Node, Pragma_Argument_Associations (Pragma_Node));
324             exit when Token /= Tok_Comma;
325             Scan; -- past comma
326          end loop;
327
328          --  If we have := for pragma Debug, it is worth special casing
329          --  the error message (it is easy to think of pragma Debug as
330          --  taking a statement, and an assignment statement is the most
331          --  likely candidate for this error)
332
333          if Token = Tok_Colon_Equal and then Pragma_Name = Name_Debug then
334             Error_Msg_SC ("argument for pragma Debug must be procedure call");
335             Resync_To_Semicolon;
336
337          --  Normal case, we expect a right paren here
338
339          else
340             T_Right_Paren;
341          end if;
342       end if;
343
344       Semicolon_Loc := Token_Ptr;
345
346       --  Now we have two tasks left, we need to scan out the semicolon
347       --  following the pragma, and we have to call Par.Prag to process
348       --  the pragma. Normally we do them in this order, however, there
349       --  is one exception namely pragma Style_Checks where we like to
350       --  skip the semicolon after processing the pragma, since that way
351       --  the style checks for the scanning of the semicolon follow the
352       --  settings of the pragma.
353
354       --  You might think we could just unconditionally do things in
355       --  the opposite order, but there are other pragmas, notably the
356       --  case of pragma Source_File_Name, which assume the semicolon
357       --  is already scanned out.
358
359       if Chars (Pragma_Node) = Name_Style_Checks then
360          Result := Par.Prag (Pragma_Node, Semicolon_Loc);
361          Skip_Pragma_Semicolon;
362          return Result;
363       else
364          Skip_Pragma_Semicolon;
365          return Par.Prag (Pragma_Node, Semicolon_Loc);
366       end if;
367
368    exception
369       when Error_Resync =>
370          Resync_Past_Semicolon;
371          return Error;
372
373    end P_Pragma;
374
375    --  This routine is called if a pragma is encountered in an inappropriate
376    --  position, the pragma is scanned out and control returns to continue.
377
378    --  The caller has checked that the initial token is pragma
379
380    --  Error recovery: cannot raise Error_Resync
381
382    procedure P_Pragmas_Misplaced is
383    begin
384       while Token = Tok_Pragma loop
385          Error_Msg_SC ("pragma not allowed here");
386          Discard_Junk_Node (P_Pragma);
387       end loop;
388    end P_Pragmas_Misplaced;
389
390    --  This function is called to scan out an optional sequence of pragmas.
391    --  If no pragmas are found, then No_List is returned.
392
393    --  Error recovery: Cannot raise Error_Resync
394
395    function P_Pragmas_Opt return List_Id is
396       L : List_Id;
397
398    begin
399       if Token = Tok_Pragma then
400          L := New_List;
401          P_Pragmas_Opt (L);
402          return L;
403
404       else
405          return No_List;
406       end if;
407    end P_Pragmas_Opt;
408
409    --  This procedure is called to scan out an optional sequence of pragmas.
410    --  Any pragmas found are appended to the list provided as an argument.
411
412    --  Error recovery: Cannot raise Error_Resync
413
414    procedure P_Pragmas_Opt (List : List_Id) is
415       P : Node_Id;
416
417    begin
418       while Token = Tok_Pragma loop
419          P := P_Pragma;
420
421          if Chars (P) = Name_Assert or else Chars (P) = Name_Debug then
422             Error_Msg_Name_1 := Chars (P);
423             Error_Msg_N
424               ("pragma% must be in declaration/statement context", P);
425          else
426             Append (P, List);
427          end if;
428       end loop;
429    end P_Pragmas_Opt;
430
431    --------------------------------------
432    -- 2.8  Pragma_Argument Association --
433    --------------------------------------
434
435    --  PRAGMA_ARGUMENT_ASSOCIATION ::=
436    --    [pragma_argument_IDENTIFIER =>] NAME
437    --  | [pragma_argument_IDENTIFIER =>] EXPRESSION
438
439    --  Error recovery: cannot raise Error_Resync
440
441    function P_Pragma_Argument_Association return Node_Id is
442       Scan_State      : Saved_Scan_State;
443       Pragma_Arg_Node : Node_Id;
444       Identifier_Node : Node_Id;
445
446    begin
447       Pragma_Arg_Node := New_Node (N_Pragma_Argument_Association, Token_Ptr);
448       Set_Chars (Pragma_Arg_Node, No_Name);
449
450       if Token = Tok_Identifier then
451          Identifier_Node := Token_Node;
452          Save_Scan_State (Scan_State); -- at Identifier
453          Scan; -- past Identifier
454
455          if Token = Tok_Arrow then
456             Scan; -- past arrow
457             Set_Chars (Pragma_Arg_Node, Chars (Identifier_Node));
458             Delete_Node (Identifier_Node);
459          else
460             Restore_Scan_State (Scan_State); -- to Identifier
461          end if;
462       end if;
463
464       Set_Expression (Pragma_Arg_Node, P_Expression);
465       return Pragma_Arg_Node;
466
467    end P_Pragma_Argument_Association;
468
469 end Ch2;