OSDN Git Service

Delete all lines containing "$Revision:".
[pf3gnuchains/gcc-fork.git] / gcc / ada / par-sync.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             P A R . S Y N C                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                                                                          --
10 --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
11 --                                                                          --
12 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
13 -- terms of the  GNU General Public License as published  by the Free Soft- --
14 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
15 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
18 -- for  more details.  You should have  received  a copy of the GNU General --
19 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
20 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
21 -- MA 02111-1307, USA.                                                      --
22 --                                                                          --
23 -- GNAT was originally developed  by the GNAT team at  New York University. --
24 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
25 --                                                                          --
26 ------------------------------------------------------------------------------
27
28 separate (Par)
29 package body Sync is
30
31    procedure Resync_Init;
32    --  This routine is called on initiating a resynchronization action
33
34    procedure Resync_Resume;
35    --  This routine is called on completing a resynchronization action
36
37    -------------------
38    -- Resync_Choice --
39    -------------------
40
41    procedure Resync_Choice is
42    begin
43       Resync_Init;
44
45       --  Loop till we get a token that terminates a choice. Note that EOF is
46       --  one such token, so we are sure to get out of this loop eventually!
47
48       while Token not in Token_Class_Cterm loop
49          Scan;
50       end loop;
51
52       Resync_Resume;
53    end Resync_Choice;
54
55    ------------------
56    -- Resync_Cunit --
57    ------------------
58
59    procedure Resync_Cunit is
60    begin
61       Resync_Init;
62
63       while Token not in Token_Class_Cunit
64         and then Token /= Tok_EOF
65       loop
66          Scan;
67       end loop;
68
69       Resync_Resume;
70    end Resync_Cunit;
71
72    -----------------------
73    -- Resync_Expression --
74    -----------------------
75
76    procedure Resync_Expression is
77       Paren_Count : Int;
78
79    begin
80       Resync_Init;
81       Paren_Count := 0;
82
83       loop
84          --  Terminating tokens are those in class Eterm and also RANGE,
85          --  DIGITS or DELTA if not preceded by an apostrophe (if they are
86          --  preceded by an apostrophe, then they are attributes). In addiion,
87          --  at the outer parentheses level only, we also consider a comma,
88          --  right parenthesis or vertical bar to terminate an expression.
89
90          if Token in Token_Class_Eterm
91
92            or else (Token in Token_Class_Atkwd
93                      and then Prev_Token /= Tok_Apostrophe)
94
95            or else (Paren_Count = 0
96                      and then
97                        (Token = Tok_Comma
98                          or else Token = Tok_Right_Paren
99                          or else Token = Tok_Vertical_Bar))
100          then
101             --  A special check: if we stop on the ELSE of OR ELSE or the
102             --  THEN of AND THEN, keep going, because this is not really an
103             --  expression terminator after all. Also, keep going past WITH
104             --  since this can be part of an extension aggregate
105
106             if (Token = Tok_Else and then Prev_Token = Tok_Or)
107                or else (Token = Tok_Then and then Prev_Token = Tok_And)
108                or else Token = Tok_With
109             then
110                null;
111             else
112                exit;
113             end if;
114          end if;
115
116          if Token = Tok_Left_Paren then
117             Paren_Count := Paren_Count + 1;
118
119          elsif Token = Tok_Right_Paren then
120             Paren_Count := Paren_Count - 1;
121
122          end if;
123
124          Scan; -- past token to be skipped
125       end loop;
126
127       Resync_Resume;
128    end Resync_Expression;
129
130    -----------------
131    -- Resync_Init --
132    -----------------
133
134    procedure Resync_Init is
135    begin
136       --  The following check makes sure we do not get stuck in an infinite
137       --  loop resynchonizing and getting nowhere. If we are called to do a
138       --  resynchronize and we are exactly at the same point that we left off
139       --  on the last resynchronize call, then we force at least one token to
140       --  be skipped so that we make progress!
141
142       if Token_Ptr = Last_Resync_Point then
143          Scan; -- to skip at least one token
144       end if;
145
146       --  Output extra error message if debug R flag is set
147
148       if Debug_Flag_R then
149          Error_Msg_SC ("resynchronizing!");
150       end if;
151    end Resync_Init;
152
153    ---------------------------
154    -- Resync_Past_Semicolon --
155    ---------------------------
156
157    procedure Resync_Past_Semicolon is
158    begin
159       Resync_Init;
160
161       loop
162          --  Done if we are at a semicolon
163
164          if Token = Tok_Semicolon then
165             Scan; -- past semicolon
166             exit;
167
168          --  Done if we are at a token which normally appears only after
169          --  a semicolon. One special glitch is that the keyword private is
170          --  in this category only if it does NOT appear after WITH.
171
172          elsif Token in Token_Class_After_SM
173             and then (Token /= Tok_Private or else Prev_Token /= Tok_With)
174          then
175             exit;
176
177          --  Otherwise keep going
178
179          else
180             Scan;
181          end if;
182       end loop;
183
184       --  Fall out of loop with resyncrhonization complete
185
186       Resync_Resume;
187    end Resync_Past_Semicolon;
188
189    ----------------------------------------------
190    -- Resync_Past_Semicolon_Or_To_Loop_Or_Then --
191    ----------------------------------------------
192
193    procedure Resync_Past_Semicolon_Or_To_Loop_Or_Then is
194    begin
195       Resync_Init;
196
197       loop
198          --  Done if at semicolon
199
200          if Token = Tok_Semicolon then
201             Scan; -- past the semicolon
202             exit;
203
204          --  Done if we are at a token which normally appears only after
205          --  a semicolon. One special glitch is that the keyword private is
206          --  in this category only if it does NOT appear after WITH.
207
208          elsif (Token in Token_Class_After_SM
209                   and then (Token /= Tok_Private
210                               or else Prev_Token /= Tok_With))
211          then
212             exit;
213
214          --  Done if we are at THEN or LOOP
215
216          elsif Token = Tok_Then or else Token = Tok_Loop then
217             exit;
218
219          --  Otherwise keep going
220
221          else
222             Scan;
223          end if;
224       end loop;
225
226       --  Fall out of loop with resyncrhonization complete
227
228       Resync_Resume;
229    end Resync_Past_Semicolon_Or_To_Loop_Or_Then;
230
231    -------------------
232    -- Resync_Resume --
233    -------------------
234
235    procedure Resync_Resume is
236    begin
237       --  Save resync point (see special test in Resync_Init)
238
239       Last_Resync_Point := Token_Ptr;
240
241       if Debug_Flag_R then
242          Error_Msg_SC ("resuming here!");
243       end if;
244    end Resync_Resume;
245
246    --------------------
247    -- Resync_To_When --
248    --------------------
249
250    procedure Resync_To_When is
251    begin
252       Resync_Init;
253
254       loop
255          --  Done if at semicolon, WHEN or IS
256
257          if Token = Tok_Semicolon
258            or else Token = Tok_When
259            or else Token = Tok_Is
260          then
261             exit;
262
263          --  Otherwise keep going
264
265          else
266             Scan;
267          end if;
268       end loop;
269
270       --  Fall out of loop with resyncrhonization complete
271
272       Resync_Resume;
273    end Resync_To_When;
274
275    ---------------------------
276    -- Resync_Semicolon_List --
277    ---------------------------
278
279    procedure Resync_Semicolon_List is
280       Paren_Count : Int;
281
282    begin
283       Resync_Init;
284       Paren_Count := 0;
285
286       loop
287          if Token = Tok_EOF
288            or else Token = Tok_Semicolon
289            or else Token = Tok_Is
290            or else Token in Token_Class_After_SM
291          then
292             exit;
293
294          elsif Token = Tok_Left_Paren then
295             Paren_Count := Paren_Count + 1;
296
297          elsif Token = Tok_Right_Paren then
298             if Paren_Count = 0 then
299                exit;
300             else
301                Paren_Count := Paren_Count - 1;
302             end if;
303          end if;
304
305          Scan;
306       end loop;
307
308       Resync_Resume;
309    end Resync_Semicolon_List;
310
311 end Sync;