OSDN Git Service

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