~ubuntu-branches/ubuntu/wily/aspectc++/wily

« back to all changes in this revision

Viewing changes to Puma/gen-release/step1/src/Syntax.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2005-12-23 10:49:40 UTC
  • Revision ID: james.westby@ubuntu.com-20051223104940-ig4klhoi991zs7km
Tags: upstream-0.99+1.0pre2
ImportĀ upstreamĀ versionĀ 0.99+1.0pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// This file is part of PUMA.
 
2
// Copyright (C) 1999-2003  The PUMA developer team.
 
3
//                                                                
 
4
// This program is free software;  you can redistribute it and/or 
 
5
// modify it under the terms of the GNU General Public License as 
 
6
// published by the Free Software Foundation; either version 2 of 
 
7
// the License, or (at your option) any later version.            
 
8
//                                                                
 
9
// This program is distributed in the hope that it will be useful,
 
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
 
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 
12
// GNU General Public License for more details.                   
 
13
//                                                                
 
14
// You should have received a copy of the GNU General Public      
 
15
// License along with this program; if not, write to the Free     
 
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 
17
// MA  02111-1307  USA                                            
 
18
 
 
19
#include "Puma/Syntax.h"
 
20
#include "Puma/CTree.h"
 
21
#include "Puma/CTokens.h"
 
22
#include "Puma/Semantic.h"
 
23
 
 
24
namespace Puma {
 
25
 
 
26
 
 
27
CTree *Syntax::run (TokenProvider &tp) {
 
28
  token_provider = &tp;
 
29
  _have_error = false;
 
30
  _problem_token = (Token*)0;
 
31
  locate_token ();
 
32
  return parse (&Syntax::trans_unit) ? builder ().Top () : (CTree*)0;
 
33
}
 
34
 
 
35
 
 
36
Token *Syntax::locate_token () {
 
37
  Token *token;
 
38
  while ((token = token_provider->current ()) && ! token->is_core ()) {
 
39
    if (token->is_directive ())
 
40
      handle_directive ();
 
41
    else
 
42
      token_provider->next ();
 
43
  }
 
44
  return token;
 
45
}
 
46
 
 
47
bool Syntax::look_ahead (int token_type, unsigned n) {
 
48
  Token *token;
 
49
  State state;
 
50
  bool result;
 
51
  
 
52
  result = false;
 
53
  if (n == 1) {
 
54
    token = token_provider->current ();
 
55
    result = (token && token->type () == token_type);
 
56
  } else {
 
57
    state = token_provider->get_state ();
 
58
    while ((--n) > 0)
 
59
      token_provider->next ();
 
60
    token = token_provider->current ();
 
61
    result = (token && token->type () == token_type);
 
62
    token_provider->set_state (state);
 
63
  }
 
64
  return result;
 
65
}
 
66
 
 
67
bool Syntax::look_ahead (int *token_types, unsigned n) {
 
68
  Token *token;
 
69
  State state;
 
70
  bool result;
 
71
  
 
72
  result = false;
 
73
  if (n == 1) {
 
74
    token = token_provider->current ();
 
75
    if (token) {
 
76
      while (*token_types) {
 
77
        if (*token_types == token->type ()) {
 
78
          result = true;
 
79
          break;
 
80
        }
 
81
        ++token_types;
 
82
      }
 
83
    }
 
84
  } else {
 
85
    state = token_provider->get_state ();
 
86
    while ((--n) > 0)
 
87
      token_provider->next ();
 
88
    token = token_provider->current ();
 
89
    if (token) {
 
90
      while (*token_types) {
 
91
        if (*token_types == token->type ()) {
 
92
          result = true;
 
93
          break;
 
94
        }
 
95
        ++token_types;
 
96
      }
 
97
    }
 
98
    token_provider->set_state (state);
 
99
  }
 
100
  return result;
 
101
}
 
102
 
 
103
Syntax::State Syntax::save_state () {
 
104
  builder ().save_state (); 
 
105
  semantic ().save_state ();
 
106
  return token_provider->get_state ();
 
107
}
 
108
 
 
109
void Syntax::forget_state () {
 
110
  builder ().forget_state ();
 
111
  semantic ().forget_state ();
 
112
}
 
113
 
 
114
void Syntax::restore_state () {
 
115
#ifndef __puma
 
116
  for (long i = builder ().Length () - 1; i >= 0; i--)
 
117
    semantic ().undo (builder ().Get (i));
 
118
#endif // __puma
 
119
  builder ().restore_state ();
 
120
  semantic ().restore_state ();
 
121
}
 
122
 
 
123
void Syntax::restore_state (State state) {
 
124
  token_provider->set_state (state);
 
125
#ifndef __puma
 
126
  for (long i = builder ().Length () - 1; i >= 0; i--)
 
127
    semantic ().undo (builder ().Get (i));
 
128
#endif // __puma
 
129
  builder ().restore_state ();
 
130
  semantic ().restore_state ();
 
131
}
 
132
 
 
133
void Syntax::set_state (State state) {
 
134
  token_provider->set_state (state);
 
135
}
 
136
 
 
137
bool Syntax::accept (CTree *result, State s) {
 
138
  if (result) {
 
139
    forget_state ();
 
140
    builder ().Push (result); 
 
141
    return true;
 
142
  } else {
 
143
    set_state (s);
 
144
    restore_state ();
 
145
    return false;
 
146
  }
 
147
}
 
148
 
 
149
bool Syntax::parse_token (int token_type) {
 
150
  Token *t = token_provider->current ();
 
151
 
 
152
#if 0
 
153
  if (t)
 
154
    cout<<t->location()<<": `"<<t->text()<<"'"<<endl;
 
155
#endif /* 0 */
 
156
 
 
157
  if (t && t->type () == token_type) {
 
158
    _problem_token = (Token*)0;
 
159
    token_provider->next ();
 
160
    locate_token ();
 
161
    builder ().Push (builder ().token (t));
 
162
    return true;
 
163
  } else {
 
164
    if (! _problem_token)
 
165
      _problem_token = token_provider->current ();
 
166
    return false;
 
167
  }
 
168
}
 
169
 
 
170
#ifndef __puma
 
171
bool Syntax::parse (int *token) {
 
172
  while (*token) {
 
173
    if (parse (*token))
 
174
      return true;
 
175
    token++;
 
176
  }
 
177
  return false;
 
178
}
 
179
#endif
 
180
 
 
181
void Syntax::skip_block (int open, int close) {
 
182
  Token *current;
 
183
  int token;
 
184
  int depth = 0;
 
185
  while ((current = token_provider->current ())) {
 
186
    token = current->type ();
 
187
    token_provider->next ();
 
188
    locate_token ();
 
189
    if (token == open)
 
190
      depth++;
 
191
    else if (token == close)
 
192
      depth--;
 
193
    if (depth == 0)
 
194
      break;
 
195
  }
 
196
}
 
197
 
 
198
void Syntax::skip_round_block () {
 
199
  skip_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND);
 
200
}
 
201
 
 
202
void Syntax::skip_curly_block () {
 
203
  skip_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY);
 
204
}
 
205
 
 
206
void Syntax::parse_block (int open, int close) {
 
207
  int depth = 0;
 
208
  int token;
 
209
  while ((token = look_ahead ())) {
 
210
    consume ();
 
211
    if (token == open)
 
212
      depth++;
 
213
    else if (token == close)
 
214
      depth--;
 
215
    if (depth == 0)
 
216
      break;
 
217
  }
 
218
}
 
219
 
 
220
void Syntax::parse_round_block () {
 
221
  parse_block (TOK_OPEN_ROUND, TOK_CLOSE_ROUND);
 
222
}
 
223
 
 
224
void Syntax::parse_curly_block () {
 
225
  parse_block (TOK_OPEN_CURLY, TOK_CLOSE_CURLY);
 
226
}
 
227
 
 
228
bool Syntax::skip (int *stop_tokens, bool inclusive) {
 
229
  Token *current;
 
230
  int token;
 
231
 
 
232
  while ((current = token_provider->current ())) {
 
233
    token = current->type ();
 
234
 
 
235
    if (is_in (token, stop_tokens))
 
236
      break;
 
237
 
 
238
    if (token == TOK_OPEN_CURLY)
 
239
      skip_curly_block ();
 
240
    else if (token == TOK_OPEN_ROUND)
 
241
      skip_round_block ();
 
242
    else {
 
243
      token_provider->next ();
 
244
      locate_token ();
 
245
    }
 
246
  }
 
247
 
 
248
  if (current && inclusive && current->type () != TOK_CLOSE_CURLY) {
 
249
    token_provider->next ();
 
250
    locate_token ();
 
251
  }
 
252
 
 
253
  return false;
 
254
}
 
255
 
 
256
bool Syntax::skip (int stop_token, bool inclusive) {
 
257
  Token *current;
 
258
  int token;
 
259
 
 
260
  while ((current = token_provider->current ())) {
 
261
    token = current->type ();
 
262
 
 
263
    if (token == stop_token)
 
264
      break;
 
265
 
 
266
    if (token == TOK_OPEN_CURLY)
 
267
      skip_curly_block ();
 
268
    else if (token == TOK_OPEN_ROUND)
 
269
      skip_round_block ();
 
270
    else {
 
271
      token_provider->next ();
 
272
      locate_token ();
 
273
    }
 
274
  }
 
275
 
 
276
  if (current && inclusive && current->type () != TOK_CLOSE_CURLY) {
 
277
    token_provider->next ();
 
278
    locate_token ();
 
279
  }
 
280
 
 
281
  return false;
 
282
}
 
283
 
 
284
void Syntax::skip () {
 
285
  token_provider->next ();
 
286
  locate_token ();
 
287
}
 
288
 
 
289
bool Syntax::is_in (int token, int *set) const {
 
290
  int i = 0;
 
291
  while (set[i] && set[i] != token) 
 
292
    i++;
 
293
  return (set[i] != 0);
 
294
}
 
295
 
 
296
 
 
297
} // namespace Puma