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

« back to all changes in this revision

Viewing changes to Puma/src/parser/ccparser/CCBuilder.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/CCBuilder.h"
 
20
#include "Puma/CCSyntax.h"
 
21
#include "Puma/CTokens.h"
 
22
 
 
23
namespace Puma {
 
24
 
 
25
 
 
26
/*****************************************************************************/
 
27
/*                                                                           */
 
28
/*                           A . 1   K e y w o r d s                         */
 
29
/*                                                                           */
 
30
/*****************************************************************************/
 
31
 
 
32
CTree *CCBuilder::namespace_name () {
 
33
  // 1: original_ns_name
 
34
  // 1: namespace_alias
 
35
  return get_node ();
 
36
}
 
37
 
 
38
/*****************************************************************************/
 
39
/*                                                                           */
 
40
/*                      A . 4   E x p r e s s i o n s                        */
 
41
/*                                                                           */
 
42
/*****************************************************************************/
 
43
 
 
44
CTree *CCBuilder::prim_expr () { 
 
45
  // 1: literal      => node
 
46
  // 1: THIS         => token
 
47
  // 1: id_expr      => node
 
48
  // 3: (  expr  )   => token  node  token
 
49
  if (nodes () == 3)
 
50
    return new CT_BracedExpr (get_node (0), get_node (1), get_node (2));
 
51
  else if (get_node ()->token ()->type () == TOK_THIS)
 
52
    return simple_name ();
 
53
  else
 
54
    return get_node ();
 
55
}
 
56
 
 
57
CTree *CCBuilder::id_expr () { 
 
58
  return get_node (); 
 
59
}
 
60
 
 
61
CTree *CCBuilder::unqual_id () { 
 
62
  // 1: template_id
 
63
  // 1: identifier
 
64
  // 1: oper_fct_id
 
65
  // 1: conv_fct_id
 
66
  // 2: ~  class_name
 
67
  if (nodes () == 2)
 
68
    return new CT_DestructorName (get_node (0), get_node (1));
 
69
  else
 
70
    return get_node (); 
 
71
}
 
72
 
 
73
CTree *CCBuilder::qual_id () { 
 
74
  // 2: ::  identifier
 
75
  // 2: ::  oper_fct_id
 
76
  // 2: ::  template_id
 
77
  // 2:     nested_name_spec                unqual_id
 
78
  // 3: ::  nested_name_spec                unqual_id
 
79
  // 3:     nested_name_spec  template_key  unqual_id
 
80
  // 4: ::  nested_name_spec  template_key  unqual_id
 
81
  CT_QualName *result;
 
82
  int root = 0, num = nodes ();
 
83
  if (get_node (0)->NodeName () != Container::NodeId ()) {
 
84
    root = 1;
 
85
    if (num == 2) {
 
86
      result = new CT_RootQualName (2);
 
87
      result->AddSon (get_node (0));
 
88
      result->AddSon (get_node (1));
 
89
      return result;
 
90
    }
 
91
  }
 
92
 
 
93
  Container *nns = (Container*)get_node (root);
 
94
  CT_SimpleName *sn = (CT_SimpleName*)get_node (num-1);
 
95
  // name prefixed by `template'
 
96
  if (get_node (num-2)->NodeName () != Container::NodeId ())
 
97
    sn->PrefixSon (get_node (num-2));
 
98
  if (root == 1) {
 
99
    result = new CT_RootQualName (nns->Sons ()+2);
 
100
    result->AddSon (get_node (0));
 
101
  } else 
 
102
    result = new CT_QualName (nns->Sons ()+1);
 
103
  copy_list (result, nns);
 
104
  result->AddSon (sn);
 
105
  delete nns;
 
106
  return result;
 
107
}
 
108
 
 
109
CTree *CCBuilder::nested_name_spec () { 
 
110
  Container *c, *nns = (Container*)get_node ();
 
111
  CT_SimpleName *sn;
 
112
  int sons;
 
113
  
 
114
  for (int i = 1; i < nodes (); i++) {
 
115
    c = (Container*)get_node (i);
 
116
    sons = c->Sons ();
 
117
    sn = (CT_SimpleName*)c->Son (sons-2);
 
118
    if (sons == 3) 
 
119
      sn->PrefixSon (c->Son (0));
 
120
    nns->AddSon (sn);
 
121
    nns->AddSon (c->Son (sons-1));
 
122
    delete c;
 
123
  }
 
124
  return nns; 
 
125
}
 
126
 
 
127
CTree *CCBuilder::nested_name_spec1 () { 
 
128
  return container (); 
 
129
}
 
130
 
 
131
CTree *CCBuilder::class_or_ns_name () { 
 
132
  // 1: class_name
 
133
  // 1: namespace_name
 
134
  return get_node ();
 
135
}
 
136
 
 
137
CTree *CCBuilder::postfix_expr (CTree *postfix) { 
 
138
  // 1 : postfix_expr2
 
139
  // 1+: postfix_expr2  postfix_expr1..
 
140
  CTree *result = postfix; 
 
141
  if (nodes () == 1) {
 
142
    result = get_node (0);
 
143
  } else {  
 
144
    Container *c = (Container*)get_node (nodes ()-1);
 
145
    // 1: --
 
146
    // 1: ++
 
147
    // 2: .  id_expr
 
148
    // 2: ->  id_expr
 
149
    // 2: .  pseudo_dtor_name
 
150
    // 2: ->  pseudo_dtor_name
 
151
    // 2: (  )
 
152
    // 3: .  template_key  id_expr
 
153
    // 3: ->  template_key  id_expr
 
154
    // 3: (  expr_list  )
 
155
    // 3: [  expr  ]
 
156
    int token = c->token ()->type ();
 
157
    if (token == TOK_DECR || token == TOK_INCR)
 
158
      result = new CT_PostfixExpr (result, c->Son (0));
 
159
    else if (token == TOK_OPEN_SQUARE)
 
160
      result = new CT_IndexExpr (result, c->Son (0), c->Son (1), c->Son (2));
 
161
    else if (token == TOK_DOT || token == TOK_PTS) {
 
162
      CT_SimpleName *sn = (CT_SimpleName*)c->Son (c->Sons ()-1);
 
163
      // name prefixed by `template'
 
164
      if (c->Sons () == 3)
 
165
        sn->PrefixSon (c->Son (1));
 
166
      if (token == TOK_DOT)
 
167
        result = new CT_MembRefExpr (result, c->Son (0), sn);
 
168
      else
 
169
        result = new CT_MembPtrExpr (result, c->Son (0), sn);
 
170
    } else if (token == TOK_OPEN_ROUND) {
 
171
      bool args = (c->Sons () == 3);
 
172
      CT_ExprList *el = args ? (CT_ExprList*)c->Son (1) : new CT_ExprList;
 
173
      el->AddProperties (CT_List::OPEN_CLOSE);
 
174
      el->PrefixSon (c->Son (0));
 
175
      el->AddSon (c->Son (args ? 2 : 1));
 
176
      result = new CT_CallExpr (result, el);
 
177
    } 
 
178
    delete c;
 
179
  }
 
180
  return result;
 
181
}
 
182
 
 
183
CTree *CCBuilder::postfix_expr2 () { 
 
184
  // 1 : cmpd_literal
 
185
  // 1 : prim_expr
 
186
  // 3 : simple_type_spec  (  )
 
187
  // 4 : simple_type_spec  (  expr_list  )
 
188
  // 4 : TYPEID  (  expr  )
 
189
  // 4 : TYPEID  (  type_id  )
 
190
  // 5 : TYPENAME  nested_name_spec  identifier  (  )
 
191
  // 5 : TYPENAME  nested_name_spec  template_id  (  )
 
192
  // 6 : TYPENAME  nested_name_spec  identifier  (  expr_list  )
 
193
  // 6 : TYPENAME  nested_name_spec  template_id  (  expr_list  )
 
194
  // 6 : TYPENAME  nested_name_spec  template_key  template_id  (  )
 
195
  // 6 : TYPENAME  ::  nested_name_spec  identifier  (  )
 
196
  // 6 : TYPENAME  ::  nested_name_spec  template_id  (  )
 
197
  // 7 : TYPENAME  ::  nested_name_spec  identifier  (  expr_list  )
 
198
  // 7 : TYPENAME  ::  nested_name_spec  template_id  (  expr_list  )
 
199
  // 7 : TYPENAME  ::  nested_name_spec  template_key  template_id  (  )
 
200
  // 7 : TYPENAME  nested_name_spec  template_key  template_id  (  expr_list  )
 
201
  // 7 : CONST_CAST  <  type_id  >  (  expr  )
 
202
  // 7 : REINT_CAST  <  type_id  >  (  expr  )
 
203
  // 7 : STATIC_CAST  <  type_id  >  (  expr  )
 
204
  // 7 : DYNAMIC_CAST  <  type_id  >  (  expr  )
 
205
  // 8 : TYPENAME  ::  nested_name_spec  template_key  template_id  (  expr_list  )
 
206
  CT_ExprList *el;
 
207
  CTree *result = get_node (0);
 
208
  int num = nodes (), offset = 0;
 
209
  // TYPENAME ...
 
210
  if (result->NodeName () == CT_Token::NodeId () &&
 
211
      result->token ()->type () == TOK_TYPENAME) {
 
212
    if (get_node (num-2)->NodeName () == CT_ExprList::NodeId ()) {
 
213
      el = (CT_ExprList*)get_node (num-2);
 
214
      el->PrefixSon (get_node (num-3));
 
215
      offset = 1;
 
216
    } else {
 
217
      el = new CT_ExprList;
 
218
      el->PrefixSon (get_node (num-2));
 
219
    }
 
220
    el->AddSon (get_node (num-1));
 
221
    el->AddProperties (CT_List::OPEN_CLOSE);
 
222
 
 
223
    CT_SimpleName *name = (CT_SimpleName*)get_node (num-3-offset);
 
224
    // name prefixed by `template'
 
225
    if (get_node (num-4-offset)->token ()->type () == TOK_TEMPLATE)
 
226
      name->PrefixSon (get_node (num-4-offset));
 
227
    CT_QualName *qn;
 
228
    int root = (get_node (1)->NodeName () == Container::NodeId ()) ? 0 : 1;
 
229
    Container *nns = (Container*)get_node (root+1);
 
230
    if (root) {
 
231
      qn = new CT_RootQualName (nns->Sons ()+2);
 
232
      qn->AddSon (get_node (1));
 
233
    } else
 
234
      qn = new CT_QualName (nns->Sons ()+1);
 
235
    copy_list (qn, nns);
 
236
    qn->AddSon (name);
 
237
    return new CT_ConstructExpr (new CT_ClassSpec (get_node (0), qn), el);
 
238
  }
 
239
  // typeid ( ... )
 
240
  else if (result->NodeName () == CT_Token::NodeId () &&
 
241
           result->token ()->type () == TOK_TYPEID) {
 
242
    return new CT_TypeidExpr (get_node (0), get_node (1),
 
243
                              get_node (2), get_node (3));
 
244
  }
 
245
  // construct expressions and "new style" casts
 
246
  else if (num > 1) {
 
247
    int type = get_node (1)->token ()->type ();
 
248
    // construct expression
 
249
    if (type == TOK_OPEN_ROUND) { 
 
250
      el = (num == 4) ? (CT_ExprList*)get_node (2) : new CT_ExprList;
 
251
      el->PrefixSon (get_node (1));
 
252
      el->AddSon (get_node (num - 1));
 
253
      el->AddProperties (CT_List::OPEN_CLOSE);
 
254
      return new CT_ConstructExpr (get_node (0), el);
 
255
    // "new style" cast
 
256
    } else { 
 
257
      int type = get_node (0)->token ()->type ();
 
258
      result = new CT_BracedExpr (get_node (4), get_node (5), get_node (6));
 
259
      if (type == TOK_REINT_CAST)
 
260
        return new CT_ReintCast (get_node (0), get_node (1), get_node (2),
 
261
                                 get_node (3), result);
 
262
      else if (type == TOK_CONST_CAST)
 
263
        return new CT_ConstCast (get_node (0), get_node (1), get_node (2),
 
264
                                 get_node (3), result);
 
265
      else if (type == TOK_STAT_CAST)
 
266
        return new CT_StaticCast (get_node (0), get_node (1), get_node (2),
 
267
                                  get_node (3), result);
 
268
      else if (type == TOK_DYN_CAST)
 
269
        return new CT_DynamicCast (get_node (0), get_node (1), get_node (2),
 
270
                                   get_node (3), result);
 
271
      else
 
272
        assert (false);
 
273
    }
 
274
  }
 
275
  return result;
 
276
}
 
277
 
 
278
CTree *CCBuilder::pseudo_dtor_name () { 
 
279
  // 2:                                      ~  type_name
 
280
  // 3: ::                                   ~  type_name
 
281
  // 3:     nested_name_spec                 ~  type_name
 
282
  // 4: ::  nested_name_spec                 ~  type_name
 
283
  // 4:                       type_name  ::  ~  type_name
 
284
  // 5: ::                    type_name  ::  ~  type_name
 
285
  // 5:     nested_name_spec  type_name  ::  ~  type_name
 
286
  // 6: ::  nested_name_spec  type_name  ::  ~  type_name
 
287
  // 6:     nested_name_spec  template_key  template_id  ::  ~  type_name
 
288
  // 7: ::  nested_name_spec  template_key  template_id  ::  ~  type_name
 
289
  int num = nodes ();
 
290
  CTree *dtor = new CT_DestructorName (get_node (num-2), get_node (num-1));
 
291
  if (num == 2) 
 
292
    return dtor;
 
293
    
 
294
  CT_QualName *result;
 
295
  int root = (get_node (0)->token ()->type () == TOK_COLON_COLON) ? 1 : 0;
 
296
  if (get_node (root)->NodeName () == Container::NodeId ()) {
 
297
    Container *nns = (Container*)get_node (root);
 
298
    if (root == 1) {
 
299
      result = new CT_RootQualName (nns->Sons () + (num > 4 ? 4 : 2));
 
300
      result->AddSon (get_node (0));
 
301
    } else 
 
302
      result = new CT_QualName (nns->Sons () + (num > 4 ? 3 : 1));
 
303
    copy_list (result, nns);
 
304
    delete nns;
 
305
  } else {
 
306
    if (root == 1) {
 
307
      result = new CT_RootQualName (num > 3 ? 4 : 2);
 
308
      result->AddSon (get_node (0));
 
309
    } else 
 
310
      result = new CT_QualName (3);
 
311
  }
 
312
  if (num > (get_node (root)->NodeName () == Container::NodeId () ? 4 : 3)) {
 
313
    CT_SimpleName *sn = (CT_SimpleName*)get_node (num-4);
 
314
    // name prefixed by `template'
 
315
    if ((num == 6 && ! root) || num == 7)
 
316
      sn->PrefixSon (get_node (num-5));
 
317
    result->AddSon (sn);
 
318
    result->AddSon (get_node (num-3));
 
319
  } 
 
320
  result->AddSon (dtor);
 
321
  return result;
 
322
}
 
323
 
 
324
CTree *CCBuilder::new_expr () { 
 
325
  // 2:     NEW                 new_type_id
 
326
  // 3:     NEW                 new_type_id    new_init
 
327
  // 3:     NEW  new_placement  new_type_id
 
328
  // 3: ::  NEW                 new_type_id
 
329
  // 4: ::  NEW                 new_type_id    new_init
 
330
  // 4: ::  NEW  new_placement  new_type_id
 
331
  // 4:     NEW  new_placement  new_type_id    new_init
 
332
  // 4:     NEW                 (  type_id  )
 
333
  // 5:     NEW                 (  type_id  )  new_init
 
334
  // 5:     NEW  new_placement  (  type_id  )
 
335
  // 5: ::  NEW  new_placement  new_type_id    new_init
 
336
  // 5: ::  NEW                 (  type_id  )
 
337
  // 6: ::  NEW                 (  type_id  )  new_init
 
338
  // 6:     NEW  new_placement  (  type_id  )  new_init
 
339
  // 6: ::  NEW  new_placement  (  type_id  )
 
340
  // 7: ::  NEW  new_placement  (  type_id  )  new_init
 
341
  int root = (get_node ()->token ()->type () == TOK_COLON_COLON) ? 2 : 1;
 
342
  CTree *opn = new CT_OperatorName (get_node (root-1));
 
343
  if (root == 2) {
 
344
    CT_RootQualName *rqn = new CT_RootQualName (2);
 
345
    rqn->AddSon (get_node (0));
 
346
    rqn->AddSon (opn);
 
347
    opn = rqn;
 
348
  }
 
349
  int np = (get_node (root)->NodeName () == CT_ExprList::NodeId ()) ? 1 : 0;
 
350
  int el = (get_node (root+np)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0;
 
351
  int num = nodes ();
 
352
  return new CT_NewExpr (opn, 
 
353
    np ? get_node (root) : 0, 
 
354
    el ? get_node (root+np) : 0,
 
355
    el ? get_node (root+np+1) : get_node (root+np),
 
356
    el ? get_node (root+np+2) : 0, 
 
357
    (num-root-np-el) == 2 ? get_node (num-1) : 0);
 
358
}
 
359
 
 
360
CTree *CCBuilder::new_placement () { 
 
361
  // 3: (  expr_list  )
 
362
  CT_ExprList *result = (CT_ExprList*)get_node (1);
 
363
  result->PrefixSon (get_node (0));
 
364
  result->AddSon (get_node (2));
 
365
  result->AddProperties (CT_List::OPEN_CLOSE);
 
366
  return result;
 
367
}
 
368
 
 
369
CTree *CCBuilder::direct_new_declarator () { 
 
370
  // 3 : [  expr  ]
 
371
  // 4+: [  expr  ]  direct_new_declarator1...
 
372
  int num = nodes ()-1;
 
373
  CTree *result = get_node (num);  // PrivateName, pushed by semantic
 
374
  result = new CT_ArrayDeclarator (result, get_node (0), 
 
375
             new CT_ArrayDelimiter (0, 0, 0, get_node (1)), get_node (2));
 
376
 
 
377
  for (int i = 3; i < num; i++) {
 
378
    Container *d1 = (Container*)get_node (i);
 
379
    result = new CT_ArrayDeclarator (result, d1->Son (0), 
 
380
               new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2));
 
381
    delete d1;
 
382
  }
 
383
  return result;
 
384
}
 
385
 
 
386
CTree *CCBuilder::direct_new_declarator1 () { 
 
387
  // 3: [  const_expr  ]
 
388
  return container ();
 
389
}
 
390
 
 
391
CTree *CCBuilder::new_init () { 
 
392
  // 2: (  )
 
393
  // 3: (  expr_list  )
 
394
  CT_ExprList *result = (nodes () == 3) ? 
 
395
    (CT_ExprList*)get_node (1) : new CT_ExprList;
 
396
  result->PrefixSon (get_node (0));
 
397
  result->AddSon (get_node (nodes () - 1));
 
398
  result->AddProperties (CT_List::OPEN_CLOSE);
 
399
  return result;
 
400
}
 
401
 
 
402
CTree *CCBuilder::delete_expr () { 
 
403
  // 2:     DELETE        cast_expr
 
404
  // 3: ::  DELETE        cast_expr
 
405
  // 4:     DELETE  [  ]  cast_expr
 
406
  // 5: ::  DELETE  [  ]  cast_expr
 
407
  int num = nodes (), root = (num == 3 || num == 5) ? 1 : 0;
 
408
  CTree *result;
 
409
  if (num > 3)
 
410
    result = new CT_OperatorName (0, get_node (root), get_node (root+1),
 
411
                                  get_node (root+2));
 
412
  else 
 
413
    result = new CT_OperatorName (get_node (root));
 
414
  if (root == 1) {
 
415
    CT_RootQualName *rqn = new CT_RootQualName;
 
416
    rqn->AddSon (get_node ());
 
417
    rqn->AddSon (result);
 
418
    result = rqn;
 
419
  }
 
420
  return new CT_DeleteExpr (result, get_node (num-1));
 
421
}
 
422
 
 
423
CTree *CCBuilder::pm_expr () { 
 
424
  return lr_bin_expr (); 
 
425
}
 
426
 
 
427
/*****************************************************************************/
 
428
/*                                                                           */
 
429
/*                      A . 5   S t a t e m e n t s                          */
 
430
/*                                                                           */
 
431
/*****************************************************************************/
 
432
 
 
433
CTree *CCBuilder::condition (CTree *cond) {
 
434
  // 1: expr
 
435
  // 2: type_spec_seq  declarator
 
436
  if (! cond) {
 
437
    if (nodes () == 1)
 
438
      return get_node ();
 
439
    else
 
440
      return new CT_Condition (get_node (0), get_node (1));
 
441
  // 4: type_spec_seq  declarator  =  ass_expr
 
442
  } else {
 
443
    if (nodes () != 4) {
 
444
      delete cond;
 
445
      return (CTree*)0;
 
446
    }
 
447
    CT_ExprList *el = new CT_ExprList;
 
448
//    Push (el);
 
449
    el->AddSon (get_node (2));
 
450
    el->AddSon (get_node (3));
 
451
    el->AddProperties (CT_List::INTRO);
 
452
    ((CT_Condition*)cond)->Initializer (el);
 
453
    return cond;
 
454
  }
 
455
}
 
456
 
 
457
CTree *CCBuilder::decl_stmt () {
 
458
  // 1: block_decl
 
459
  return new CT_DeclStmt (get_node ());
 
460
}
 
461
 
 
462
/*****************************************************************************/
 
463
/*                                                                           */
 
464
/*                     A . 6   D e c l a r a t i o n s                       */
 
465
/*                                                                           */
 
466
/*****************************************************************************/
 
467
 
 
468
CTree *CCBuilder::decl () { 
 
469
  // 1: block_decl
 
470
  // 1: fct_def
 
471
  // 1: explicit_specialization
 
472
  // 1: template_decl
 
473
  // 1: explicit_instantiation
 
474
  // 1: linkage_spec
 
475
  // 1: namespace_def
 
476
  // 3: EXTERN  str_literal  decl
 
477
  if (nodes () == 1)
 
478
    return get_node ();
 
479
  // nodes == 3
 
480
  return new CT_LinkageSpec (get_node (0), get_node (1), 0, get_node (2), 0);
 
481
}
 
482
 
 
483
CTree *CCBuilder::simple_type_spec () { 
 
484
  // 1: prim_types
 
485
  // 1: type_name
 
486
  // 2: nested_name_spec  type_name
 
487
  // 2: ::  type_name
 
488
  // 3: ::  nested_name_spec  type_name
 
489
  // 3: nested_name_spec  template_key  template_id
 
490
  // 4: ::  nested_name_spec  template_key  template_id
 
491
  int num = nodes ();
 
492
  if (num == 1) {
 
493
    if (get_node ()->NodeName () == CT_Token::NodeId ())
 
494
      return prim_ds ();
 
495
    else
 
496
      return get_node ();
 
497
  }
 
498
 
 
499
  CT_SimpleName *sn = (CT_SimpleName*)get_node (num-1);
 
500
  // name prefixed by `template'
 
501
  if (get_node (num-2)->token ()->type () == TOK_TEMPLATE)
 
502
    sn->PrefixSon (get_node (num-2));
 
503
 
 
504
  int root = (get_node ()->NodeName () == Container::NodeId ()) ? 0 : 1;
 
505
  CT_QualName *result;
 
506
  if (num == 2 && root) {
 
507
    result = new CT_RootQualName (2);
 
508
    result->AddSon (get_node (0));
 
509
  } else {
 
510
    Container *nns = (Container*)get_node (root);
 
511
    if (root) {
 
512
      result = new CT_RootQualName (nns->Sons ()+2);
 
513
      result->AddSon (get_node (0));
 
514
    } else
 
515
      result = new CT_QualName (nns->Sons ()+1);
 
516
    copy_list (result, nns);
 
517
    delete nns;
 
518
  }
 
519
  result->AddSon (sn);
 
520
  return result;
 
521
}
 
522
 
 
523
CTree *CCBuilder::elaborated_type_spec () { 
 
524
  // 2: TYPENAME                                       template_id
 
525
  // 2: class_key                                      identifier
 
526
  // 2: ENUM                                           identifier
 
527
  // 3: class_key  ::                                  identifier
 
528
  // 3: ENUM       ::                                  identifier
 
529
  // 3: class_key      nested_name_spec                identifier
 
530
  // 3: ENUM           nested_name_spec                identifier
 
531
  // 3: TYPENAME       nested_name_spec                identifier
 
532
  // 3: TYPENAME       nested_name_spec                template_id
 
533
  // 4: class_key  ::  nested_name_spec                identifier
 
534
  // 4: ENUM       ::  nested_name_spec                identifier
 
535
  // 4: TYPENAME       nested_name_spec  template_key  template_id
 
536
  // 4: TYPENAME   ::  nested_name_spec                identifier
 
537
  // 4: TYPENAME   ::  nested_name_spec                template_id
 
538
  // 5: TYPENAME   ::  nested_name_spec  template_key  template_id
 
539
  int num = nodes ();
 
540
  CT_SimpleName *name = (CT_SimpleName*)get_node (num-1);
 
541
  if (num > 2) {
 
542
    // name prefixed by `template'
 
543
    if (get_node (num-2)->token ()->type () == TOK_TEMPLATE)
 
544
      name->PrefixSon (get_node (num-2));
 
545
    CT_QualName *qn;
 
546
    int root = (get_node (1)->NodeName () == Container::NodeId ()) ? 0 : 1;
 
547
    if (root && num == 3) {
 
548
      qn = new CT_RootQualName (2);
 
549
      qn->AddSon (get_node (1));
 
550
    } else {
 
551
      Container *nns = (Container*)get_node (root+1);
 
552
      if (root) {
 
553
        qn = new CT_RootQualName (nns->Sons ()+2);
 
554
        qn->AddSon (get_node (1));
 
555
      } else
 
556
        qn = new CT_QualName (nns->Sons ()+1);
 
557
      copy_list (qn, nns);
 
558
    }
 
559
    qn->AddSon (name);
 
560
    name = qn;
 
561
  }
 
562
  int key = get_node ()->token ()->type ();
 
563
  if (key == TOK_CLASS || key == TOK_STRUCT || key == TOK_TYPENAME)
 
564
    return new CT_ClassSpec (get_node (0), name);
 
565
  else if (key == TOK_UNION)
 
566
    return new CT_UnionSpec (get_node (0), name);
 
567
  else // TOK_ENUM
 
568
    return new CT_EnumSpec (get_node (0), name);
 
569
}
 
570
 
 
571
CTree *CCBuilder::asm_def () { 
 
572
  // 1: ASM  (  str_literal  )  ;
 
573
  return new CT_AsmDef (get_node (0), get_node (1), get_node (2),
 
574
                        get_node (3), get_node (4));
 
575
}
 
576
 
 
577
CTree *CCBuilder::linkage_spec () { 
 
578
  // 3: EXTERN  str_literal  decl
 
579
  // 4: EXTERN  str_literal  {  }
 
580
  // 5: EXTERN  str_literal  {  decl_seq  }
 
581
  if (nodes () == 3)
 
582
    return new CT_LinkageSpec (get_node (0), get_node (1), 
 
583
      0, get_node (2), 0);
 
584
  else if (nodes () == 4)
 
585
    return new CT_LinkageSpec (get_node (0), get_node (1), 
 
586
      get_node (2), new CT_DeclList (1), get_node (3));
 
587
  else { // if (nodes () == 5)
 
588
    Container *decls = (Container*)get_node (3);
 
589
    CT_DeclList *dl = new CT_DeclList (decls->Sons ());
 
590
    copy_list (dl, decls);
 
591
    delete decls;
 
592
    return new CT_LinkageSpec (get_node (0), get_node (1), 
 
593
      get_node (2), dl, get_node (4));
 
594
  }
 
595
}
 
596
 
 
597
/*****************************************************************************/
 
598
/*                                                                           */
 
599
/*                    A . 6 . 1   N a m e s p a c e s                        */
 
600
/*                                                                           */
 
601
/*****************************************************************************/
 
602
 
 
603
CTree *CCBuilder::namespace_def () {
 
604
  // 1: named_ns_def
 
605
  // 1: unamed_ns_def
 
606
  return get_node ();
 
607
}
 
608
 
 
609
CTree *CCBuilder::named_ns_def () {
 
610
  // 1: original_ns_def
 
611
  // 1: extension_ns_def
 
612
  return get_node ();
 
613
}
 
614
 
 
615
CTree *CCBuilder::orig_namespace_def (CTree *nsd) {
 
616
  // 5: NAMESPACE  identifier  {  namespace_body  }
 
617
  if (nsd) {
 
618
    CT_MembList *ml;
 
619
    ml = (nodes () == 5) ? (CT_MembList*)get_node (3) : new CT_MembList (1);  
 
620
    ml->AddProperties (CT_List::OPEN_CLOSE);
 
621
    ml->PrefixSon (get_node (2));
 
622
    ml->AddSon (get_node (nodes ()-1));
 
623
    ((CT_NamespaceDef*)nsd)->Members (ml);
 
624
    return nsd;
 
625
  } else
 
626
    return new CT_NamespaceDef (get_node (0), get_node (1));
 
627
}
 
628
 
 
629
CTree *CCBuilder::namespace_body () {
 
630
  // 0: 
 
631
  // 1: decl_seq
 
632
  CT_MembList *ml;
 
633
  if (nodes ()) {
 
634
    Container *decls = (Container*)get_node ();
 
635
    ml = new CT_MembList (decls->Sons ());
 
636
    copy_list (ml, decls);
 
637
    delete decls;
 
638
  } else
 
639
    ml = new CT_MembList (1);
 
640
  return ml;
 
641
}
 
642
 
 
643
CTree *CCBuilder::ns_alias_def () {
 
644
  // 5: NAMESPACE  identifier  =  qual_ns_spec  ;
 
645
  return new CT_NamespaceAliasDef (get_node (0), get_node (1), get_node (2),
 
646
                                   get_node (3), get_node (4));
 
647
}
 
648
 
 
649
CTree *CCBuilder::qual_ns_spec () {
 
650
  // 1: namespace_name
 
651
  // 2: nested_name_spec  namespace_name
 
652
  // 2: colon_colon  namespace_name
 
653
  // 3: colon_colon  nested_name_spec  namespace_name
 
654
  int num = nodes ();
 
655
  if (num == 1)
 
656
    return get_node ();
 
657
 
 
658
  CT_QualName *result;
 
659
  int root = 0;
 
660
  if (get_node (0)->NodeName () != Container::NodeId ()) {
 
661
    root = 1;
 
662
    if (nodes () == 2) {
 
663
      result = new CT_RootQualName (2);
 
664
      result->AddSon (get_node (0));
 
665
      result->AddSon (get_node (1));
 
666
      return result;
 
667
    }
 
668
  }
 
669
 
 
670
  Container *nns = (Container*)get_node (root);
 
671
  if (root == 1) {
 
672
    result = new CT_RootQualName (nns->Sons ()+2);
 
673
    result->AddSon (get_node (0));
 
674
  } else 
 
675
    result = new CT_QualName (nns->Sons ()+1);
 
676
  copy_list (result, nns);
 
677
  result->AddSon (get_node (1+root));
 
678
  delete nns;
 
679
  return result;
 
680
}
 
681
 
 
682
CTree *CCBuilder::using_decl () {
 
683
  // 4: USING            ::                    unqual_id  ;
 
684
  // 4: USING                nested_name_spec  unqual_id  ;
 
685
  // 5: USING            ::  nested_name_spec  unqual_id  ;
 
686
  // 5: USING  TYPENAME      nested_name_spec  unqual_id  ;
 
687
  // 6: USING  TYPENAME  ::  nested_name_spec  unqual_id  ;
 
688
  CT_QualName *qn;
 
689
  int root = 0, num = nodes ();
 
690
  if (get_node (1)->token ()->type () == TOK_TYPENAME)
 
691
    root++;
 
692
  if (get_node (root+1)->NodeName () != Container::NodeId ())
 
693
    root = 2;
 
694
  if (root == 2 && num == 4) {
 
695
    qn = new CT_RootQualName (2);
 
696
    qn->AddSon (get_node (1));
 
697
    qn->AddSon (get_node (num-2));
 
698
  } else {
 
699
    Container *nns = (Container*)get_node (num-3);
 
700
    if (root == 2) {
 
701
      qn = new CT_RootQualName (nns->Sons ()+2);
 
702
      qn->AddSon (get_node (num-4));
 
703
    } else 
 
704
      qn = new CT_QualName (nns->Sons ()+1);
 
705
    copy_list (qn, nns);
 
706
    qn->AddSon (get_node (num-2));
 
707
  }
 
708
  if (root && get_node (1)->token ()->type () == TOK_TYPENAME)
 
709
    return new CT_UsingDecl (get_node (0), get_node (1), qn, get_node (num-1));
 
710
  return new CT_UsingDecl (get_node (0), qn, get_node (num-1));
 
711
}
 
712
 
 
713
CTree *CCBuilder::using_directive () {
 
714
  // 4: USING  NAMESPACE                        namespace_name  ;
 
715
  // 5: USING  NAMESPACE  ::                    namespace_name  ;
 
716
  // 5: USING  NAMESPACE      nested_name_spec  namespace_name  ;
 
717
  // 6: USING  NAMESPACE  ::  nested_name_spec  namespace_name  ;
 
718
  CTree *n;
 
719
  int root = 0, num = nodes ();
 
720
  if (get_node (2)->NodeName () != Container::NodeId ())
 
721
    root = 1;
 
722
  if (num == 4) {
 
723
    n = get_node (2);
 
724
  } else if (num == 5 && root) {
 
725
    n = new CT_RootQualName (2);
 
726
    ((CT_QualName*)n)->AddSon (get_node (2));
 
727
    ((CT_QualName*)n)->AddSon (get_node (3));
 
728
  } else {
 
729
    Container *nns = (Container*)get_node (num-3);
 
730
    if (root) {
 
731
      n = new CT_RootQualName (nns->Sons ()+2);
 
732
      ((CT_QualName*)n)->AddSon (get_node (2));
 
733
    } else 
 
734
      n = new CT_QualName (nns->Sons ()+1);
 
735
    copy_list ((CT_QualName*)n, nns);
 
736
    ((CT_QualName*)n)->AddSon (get_node (num-2));
 
737
  }
 
738
  return new CT_UsingDirective (get_node (0), get_node (1), n, get_node (num-1));
 
739
}
 
740
 
 
741
/*****************************************************************************/
 
742
/*                                                                           */
 
743
/*                     A . 7   D e c l a r a t o r s                         */
 
744
/*                                                                           */
 
745
/*****************************************************************************/
 
746
 
 
747
CTree *CCBuilder::declarator () {
 
748
  // 1 : direct_declarator
 
749
  // 2+: ptr_operator..  direct_declarator
 
750
  int num = nodes ();
 
751
  CTree *result = get_node (num-1);
 
752
  for (int i = num-1; i > 0; i--) {
 
753
    // 1: &
 
754
    // 1: *
 
755
    // 2: *  cv_qual_seq
 
756
    // 2: nested_name_spec  *
 
757
    // 3: nested_name_spec  *  cv_qual_seq
 
758
    // 3: ::  nested_name_spec  *
 
759
    // 4: ::  nested_name_spec  *  cv_qual_seq
 
760
    Container *p = (Container*)get_node (i-1); // ptr-operator
 
761
    int type = p->Son (0)->token ()->type ();
 
762
    if (type == TOK_AND)
 
763
      result = new CT_RefDeclarator (p->Son (0), result);
 
764
    else if (type == TOK_MUL && p->Sons () == 1)
 
765
      result = new CT_PtrDeclarator (p->Son (0), 0, result);
 
766
    else if (type == TOK_MUL && p->Sons () == 2)
 
767
      result = new CT_PtrDeclarator (p->Son (0), p->Son (1), result);
 
768
    else {
 
769
      int root = (type == TOK_COLON_COLON) ? 1 : 0;
 
770
      Container *nns = (Container*)p->Son (root);
 
771
      CT_QualName *qn = 0;
 
772
      if (root) {
 
773
        qn = new CT_RootQualName (nns->Sons ());
 
774
        qn->AddSon (p->Son (0));
 
775
      } else if (nns->Sons () > 2)
 
776
        qn = new CT_QualName (nns->Sons ()-1);
 
777
 
 
778
      if (nns->Sons () == 2)
 
779
        qn = (CT_QualName*)nns->Son (0);
 
780
      else {
 
781
        for (int i = 0; i < nns->Sons ()-1; i++)
 
782
          qn->AddSon (nns->Son (i));
 
783
      }
 
784
 
 
785
      result = new CT_MembPtrDeclarator (qn, 
 
786
        nns->Son (nns->Sons ()-1), p->Son (root+1), 
 
787
        (p->Sons () == (root+3)) ? p->Son (root+2) : 0, result);
 
788
      delete nns;
 
789
    }
 
790
    delete p;
 
791
  }
 
792
  return result;
 
793
}
 
794
 
 
795
CTree *CCBuilder::declarator_id () { 
 
796
  // 1: id_expr                 => node
 
797
  // 1: type_name               => node
 
798
  // 2: nest_name type_name     => cont node
 
799
  // 2: :: type_name            => node node
 
800
  // 3: :: nest_name type_name  => node cont node
 
801
  int num = nodes ();
 
802
  if (num == 1) 
 
803
    return get_node ();
 
804
    
 
805
  CT_QualName *result;
 
806
  int root = (get_node (0)->NodeName () == CT_Token::NodeId ()) ? 1 : 0;
 
807
  if ((num-root) == 2) {
 
808
    Container *nns = (Container*)get_node (root);
 
809
    if (root) {
 
810
      result = new CT_RootQualName (nns->Sons ()+2);
 
811
      result->AddSon (get_node (0));
 
812
    } else
 
813
      result = new CT_QualName (nns->Sons ()+1);
 
814
    copy_list (result, nns);
 
815
    delete nns;
 
816
  } else {
 
817
    result = new CT_RootQualName (2);
 
818
    result->AddSon (get_node (0));
 
819
  }
 
820
  result->AddSon (get_node (num-1));
 
821
  return result;
 
822
}
 
823
 
 
824
CTree *CCBuilder::param_init () {
 
825
  // 2: =  ass_expr
 
826
  CT_ExprList *el = new CT_ExprList;
 
827
  el->AddSon (get_node (0));
 
828
  el->AddSon (get_node (1));
 
829
  el->AddProperties (CT_List::INTRO);
 
830
  return el;
 
831
}
 
832
 
 
833
/*****************************************************************************/
 
834
/*                                                                           */
 
835
/*                          A . 8   C l a s s e s                            */
 
836
/*                                                                           */
 
837
/*****************************************************************************/
 
838
 
 
839
CTree *CCBuilder::class_head (CTree *result) {
 
840
  // 1: class_key  private_name
 
841
  // 2: class_key  identifier
 
842
  // 2: class_key  template_id
 
843
  // 2: class_key  private_name  base_clause
 
844
  // 3: class_key  identifier  base_clause
 
845
  // 3: class_key  template_id  base_clause
 
846
  // 3: class_key  nested_name_spec  identifier
 
847
  // 3: class_key  nested_name_spec  template_id
 
848
  // 4: class_key  nested_name_spec  identifier  base_clause
 
849
  // 4: class_key  nested_name_spec  template_id  base_clause
 
850
  // base_clause not yet parsed
 
851
  if (! result) {  
 
852
    result = get_node (1);
 
853
    // nested (qualified) name
 
854
    if (result->NodeName () == Container::NodeId ()) { 
 
855
      Container *nns = (Container*)result;
 
856
      CT_QualName *qn = new CT_QualName (nns->Sons ()+1);
 
857
      copy_list (qn, nns);
 
858
      qn->AddSon (get_node (2));
 
859
      result = qn;
 
860
    } 
 
861
    if (get_node (0)->token ()->type () == TOK_UNION)
 
862
      result = new CT_UnionDef (get_node (0), result, 0);
 
863
    else 
 
864
      result = new CT_ClassDef (get_node (0), result, 0);
 
865
  // base_clause parsed successfully
 
866
  } else {
 
867
    int num = nodes ();
 
868
    if (get_node (num-1)->NodeName () == CT_BaseSpecList::NodeId ()) 
 
869
      ((CT_ClassDef*)result)->BaseClasses (get_node (num-1));
 
870
  }
 
871
  return result;
 
872
}
 
873
 
 
874
CTree *CCBuilder::class_spec () {
 
875
  // 3: class_head  {  }
 
876
  // 4: class_head  {  member_spec  }
 
877
  int num = nodes ();
 
878
  CT_MembList *ml = (num == 4) ? 
 
879
    (CT_MembList*)get_node (2) : new CT_MembList;
 
880
  ml->PrefixSon (get_node (1));
 
881
  ml->AddSon (get_node (num-1));
 
882
  ml->AddProperties (CT_List::OPEN_CLOSE);
 
883
  CT_ClassDef *result = (CT_ClassDef*)get_node (0);
 
884
  result->Members (ml);
 
885
  return result;
 
886
}
 
887
 
 
888
CTree *CCBuilder::member_decl () { 
 
889
  // 1: member_decl1
 
890
  // 1: fct_def
 
891
  // 1: access_decl
 
892
  // 2: access_spec  :
 
893
  if (nodes () == 1) 
 
894
    return get_node ();
 
895
  else
 
896
    return new CT_AccessSpec (get_node (0), get_node (1));
 
897
}
 
898
 
 
899
CTree *CCBuilder::member_decl1 () { 
 
900
  // 1: ;
 
901
  // 2: decl_spec_seq                          ;
 
902
  // 2:                member_declarator_list  ;
 
903
  // 3: decl_spec_seq  member_declarator_list  ;
 
904
  int num = nodes ();
 
905
  if (num == 1)
 
906
    return new CT_ObjDecl (new CT_DeclSpecSeq, new CT_DeclaratorList, get_node (0));
 
907
  else if (num == 2) {
 
908
    if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
 
909
      return new CT_ObjDecl (get_node (0), new CT_DeclaratorList, get_node (1));
 
910
    else
 
911
      return new CT_ObjDecl (new CT_DeclSpecSeq, get_node (0), get_node (1));
 
912
  } else // if (num == 3)
 
913
    return new CT_ObjDecl (get_node (0), get_node (1), get_node (2));
 
914
}
 
915
 
 
916
CTree *CCBuilder::access_decl () { 
 
917
  // 3:     nested_name_spec                unqual_id  ;
 
918
  // 4: ::  nested_name_spec                unqual_id  ;
 
919
  // 4:     nested_name_spec  template_key  unqual_id  ;
 
920
  // 5: ::  nested_name_spec  template_key  unqual_id  ;
 
921
  int num = nodes ();
 
922
  int root = (get_node ()->NodeName () != Container::NodeId ()) ? 1 : 0;
 
923
  Container *nns = (Container*)get_node (root);
 
924
  CT_QualName *qn;
 
925
  if (root) {
 
926
    qn = new CT_RootQualName (nns->Sons ()+2);
 
927
    qn->AddSon (get_node (0));
 
928
  } else
 
929
    qn = new CT_QualName (nns->Sons ()+1);
 
930
  copy_list (qn, nns);
 
931
  CT_SimpleName *sn = (CT_SimpleName*)get_node (num-2);
 
932
  // name prefixed by `template'
 
933
  if (get_node (num-3)->token ()->type () == TOK_TEMPLATE)
 
934
    sn->PrefixSon (get_node (num-3));
 
935
  qn->AddSon (sn);
 
936
  delete nns;
 
937
  return new CT_AccessDecl (qn, get_node (num-1));
 
938
}
 
939
 
 
940
CTree *CCBuilder::member_declarator () { 
 
941
  // 1: declarator
 
942
  // 2: declarator  pure_spec
 
943
  // 2: declarator  const_init
 
944
  // 3: identifier  :  const_expr
 
945
  // 3: private_name  :  const_expr
 
946
  int num = nodes ();
 
947
  if (num == 3)
 
948
    return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2));
 
949
  else if (num == 2 && get_node (1)->token ()->type () == TOK_COLON)
 
950
    return new CT_BitFieldDeclarator (get_node (0), get_node (1));
 
951
  else 
 
952
    return new CT_InitDeclarator (get_node (0), (num == 2) ? get_node (1) : 0);
 
953
}
 
954
 
 
955
CTree *CCBuilder::pure_spec () { 
 
956
  CT_ExprList *el = new CT_ExprList;
 
957
  el->AddSon (get_node (0));
 
958
  el->AddSon (new CT_Integer (get_node (1)));
 
959
  el->AddProperties (CT_List::INTRO);
 
960
  return el;
 
961
}
 
962
 
 
963
CTree *CCBuilder::const_init () { 
 
964
  CT_ExprList *el = new CT_ExprList;
 
965
  el->AddSon (get_node (0));
 
966
  el->AddSon (get_node (1));
 
967
  el->AddProperties (CT_List::INTRO);
 
968
  return el;
 
969
}
 
970
 
 
971
/*****************************************************************************/
 
972
/*                                                                           */
 
973
/*                   A . 9   D e r i v e d  c l a s s e s                    */
 
974
/*                                                                           */
 
975
/*****************************************************************************/
 
976
 
 
977
CTree *CCBuilder::base_clause () { 
 
978
  // 2: :  base_spec_list
 
979
  CT_BaseSpecList *bsl = (CT_BaseSpecList*)get_node (1);
 
980
  bsl->PrefixSon (get_node (0));
 
981
  return bsl;
 
982
}
 
983
 
 
984
CTree *CCBuilder::base_spec_list () { 
 
985
  return list (new CT_BaseSpecList);
 
986
}
 
987
 
 
988
CTree *CCBuilder::base_spec () { 
 
989
  // 1: class_name
 
990
  // 2: ::  class_name
 
991
  // 2: VIRTUAL  class_name
 
992
  // 2: access_spec  class_name
 
993
  // 2: nested_name_spec  class_name
 
994
  // 3: ::  nested_name_spec  class_name
 
995
  // 3: VIRTUAL  ::  class_name
 
996
  // 3: access_spec  ::  class_name
 
997
  // 3: VIRTUAL  nested_name_spec  class_name
 
998
  // 3: access_spec  nested_name_spec  class_name
 
999
  // 3: VIRTUAL  access_spec  class_name
 
1000
  // 3: access_spec  VIRTUAL  class_name
 
1001
  // 4: VIRTUAL  ::  nested_name_spec  class_name
 
1002
  // 4: access_spec  ::  nested_name_spec  class_name
 
1003
  // 4: VIRTUAL  access_spec  nested_name_spec  class_name
 
1004
  // 4: access_spec  VIRTUAL  nested_name_spec  class_name
 
1005
  // 4: VIRTUAL  access_spec  ::  class_name
 
1006
  // 4: access_spec  VIRTUAL  ::  class_name
 
1007
  // 5: VIRTUAL  access_spec  ::  nested_name_spec  class_name
 
1008
  // 5: access_spec  VIRTUAL  ::  nested_name_spec  class_name
 
1009
  int num = nodes (), i;
 
1010
  CTree *v, *a = v = (CTree*)0;
 
1011
  CTree *n = get_node (num-1);
 
1012
  if (num > 1) {
 
1013
    if ((i = 0, get_node (i)->token ()->type () == TOK_VIRTUAL) ||
 
1014
        (i = 1, get_node (i)->token ()->type () == TOK_VIRTUAL))
 
1015
      v = get_node (i);
 
1016
    if ((i = 0, get_node (i)->token ()->type () == TOK_PUBLIC ||
 
1017
                get_node (i)->token ()->type () == TOK_PRIVATE ||
 
1018
                get_node (i)->token ()->type () == TOK_PROTECTED) ||
 
1019
        (i = 1, get_node (i)->token ()->type () == TOK_PUBLIC ||
 
1020
                get_node (i)->token ()->type () == TOK_PRIVATE ||
 
1021
                get_node (i)->token ()->type () == TOK_PROTECTED))
 
1022
      a = get_node (i);
 
1023
    
 
1024
    CT_QualName *qn;
 
1025
    if (get_node (num-2)->NodeName () == Container::NodeId ()) {
 
1026
      Container *nns = (Container*)get_node (num-2);
 
1027
      if (num > 2 && get_node (num-3)->token ()->type () == TOK_COLON_COLON) {
 
1028
        qn = new CT_RootQualName (nns->Sons ()+2);
 
1029
        qn->AddSon (get_node (num-3));
 
1030
      } else
 
1031
        qn = new CT_QualName (nns->Sons ()+1);
 
1032
      copy_list (qn, nns);
 
1033
      qn->AddSon (n);
 
1034
      delete nns;
 
1035
      n = qn;
 
1036
    } else if (get_node (num-2)->token ()->type () == TOK_COLON_COLON) {
 
1037
      qn = new CT_RootQualName (2);
 
1038
      qn->AddSon (get_node (num-2));
 
1039
      qn->AddSon (n);
 
1040
      n = qn;
 
1041
    }
 
1042
  }
 
1043
  return new CT_BaseSpec (v, a, n);
 
1044
}
 
1045
 
 
1046
CTree *CCBuilder::access_spec () { 
 
1047
  return get_node ();
 
1048
}
 
1049
 
 
1050
/*****************************************************************************/
 
1051
/*                                                                           */
 
1052
/*        A . 1 0   S p e c i a l  m e m b e r  f u n c t i o n s            */
 
1053
/*                                                                           */
 
1054
/*****************************************************************************/
 
1055
 
 
1056
CTree *CCBuilder::conv_fct_id () { 
 
1057
  // 2: OPERATOR  conv_type_id
 
1058
  return new CT_ConversionName (get_node (0), get_node (1));
 
1059
}
 
1060
 
 
1061
CTree *CCBuilder::ctor_init () { 
 
1062
  // 2: :  mem_init_list
 
1063
  CT_MembInitList *mil = (CT_MembInitList*)get_node (1);
 
1064
  mil->PrefixSon (get_node (0));
 
1065
  return mil;
 
1066
}
 
1067
 
 
1068
CTree *CCBuilder::mem_init_list () { 
 
1069
  return list (new CT_MembInitList);
 
1070
}
 
1071
 
 
1072
CTree *CCBuilder::mem_init () { 
 
1073
  // 3: mem_init_id  (  )
 
1074
  // 4: mem_init_id  (  expr_list  )
 
1075
  int num = nodes ();
 
1076
  CT_ExprList *el = (num == 4) ? (CT_ExprList*)get_node (2) : new CT_ExprList;
 
1077
//  if (num != 4)
 
1078
//    Push (el);
 
1079
  el->PrefixSon (get_node (1));
 
1080
  el->AddSon (get_node (num-1));
 
1081
  el->AddProperties (CT_List::OPEN_CLOSE);
 
1082
  return new CT_MembInit (get_node (0), el);
 
1083
}
 
1084
 
 
1085
CTree *CCBuilder::mem_init_id () { 
 
1086
  // 1: identifier
 
1087
  // 1: class_name
 
1088
  // 2: nested_name_spec  class_name
 
1089
  // 2: ::  class_name
 
1090
  // 3: ::  nested_name_spec  class_name
 
1091
  int num = nodes ();
 
1092
  if (num == 1)
 
1093
    return get_node ();
 
1094
  CT_QualName *result;
 
1095
  if (get_node (num-2)->NodeName () == Container::NodeId ()) {
 
1096
    Container *nns = (Container*)get_node (num-2);
 
1097
    if (num == 3) {
 
1098
      result = new CT_RootQualName (nns->Sons ()+2);
 
1099
      result->AddSon (get_node (0));
 
1100
    } else
 
1101
      result = new CT_QualName (nns->Sons ()+1);
 
1102
    copy_list (result, nns);
 
1103
    delete nns;
 
1104
  } else {
 
1105
    result = new CT_RootQualName (2);
 
1106
    result->AddSon (get_node (0));
 
1107
  }
 
1108
  result->AddSon (get_node (num-1));
 
1109
  return result;
 
1110
}
 
1111
 
 
1112
/*****************************************************************************/
 
1113
/*                                                                           */
 
1114
/*                     A . 1 1   O v e r l o a d i n g                       */
 
1115
/*                                                                           */
 
1116
/*****************************************************************************/
 
1117
 
 
1118
CTree *CCBuilder::oper_fct_id () { 
 
1119
  // 2: OPERATOR  any_operator
 
1120
  // 2: OPERATOR  NEW
 
1121
  // 2: OPERATOR  DELETE
 
1122
  // 3: OPERATOR  (  )
 
1123
  // 3: OPERATOR  [  ]
 
1124
  // 4: OPERATOR  NEW  [  ]
 
1125
  // 4: OPERATOR  DELETE  [  ]
 
1126
  int num = nodes ();
 
1127
  if (num == 2)
 
1128
    return new CT_OperatorName (get_node (0), get_node (1), 0, 0);
 
1129
  else if (num == 3)
 
1130
    return new CT_OperatorName (get_node (0), 0, get_node (1), get_node (2));
 
1131
  else // if (num == 4)
 
1132
    return new CT_OperatorName (get_node (0), get_node (1), get_node (2), 
 
1133
                                get_node (3));
 
1134
}
 
1135
 
 
1136
/*****************************************************************************/
 
1137
/*                                                                           */
 
1138
/*                       A . 1 2   T e m p l a t e s                         */
 
1139
/*                                                                           */
 
1140
/*****************************************************************************/
 
1141
 
 
1142
CTree *CCBuilder::template_decl () {
 
1143
  // 5: TEMPLATE  <  template_param_list  >  decl
 
1144
  // 6: EXPORT  TEMPLATE  <  template_param_list  >  decl
 
1145
  int offset = (nodes () == 6) ? 1 : 0;
 
1146
  CT_TemplateParamList *pl = (CT_TemplateParamList*) get_node (2 + offset);
 
1147
  pl->AddSon (get_node (3 + offset));
 
1148
  pl->PrefixSon (get_node (1 + offset));
 
1149
  pl->PrefixSon (get_node (0 + offset));
 
1150
  return new CT_TemplateDecl (offset ? get_node (0) : (CTree*)0,
 
1151
                              pl, get_node (4 + offset));
 
1152
}
 
1153
 
 
1154
CTree *CCBuilder::template_param_list () {
 
1155
  // 1 : template_param
 
1156
  // 3+: template_param  ,  template_param ..
 
1157
  return list (new CT_TemplateParamList);
 
1158
}
 
1159
 
 
1160
CTree *CCBuilder::template_param () {
 
1161
  // 1: type_param
 
1162
  // 1: non_type_param
 
1163
  return get_node ();
 
1164
}
 
1165
 
 
1166
CTree *CCBuilder::type_param () {
 
1167
  // 2: CLASS  identifier
 
1168
  // 2: TYPENAME  identifier
 
1169
  // 4: CLASS  identifier  =  type_id
 
1170
  // 4: TYPENAME  identifier  =  type_id
 
1171
  // 6: TEMPLATE  <  template_param_list  >  CLASS  identifier
 
1172
  // 8: TEMPLATE  <  template_param_list  >  CLASS  identifier  =  id_expr
 
1173
  CT_TemplateParamList *pl = (CT_TemplateParamList*)0;
 
1174
  if (nodes () >= 6) {
 
1175
    pl = (CT_TemplateParamList*)get_node (2);
 
1176
    pl->AddSon (get_node (3));
 
1177
    pl->PrefixSon (get_node (1));
 
1178
    pl->PrefixSon (get_node (0));
 
1179
  }
 
1180
  int num = nodes ();
 
1181
  if (num == 2 || num == 6)
 
1182
    return new CT_TypeParamDecl (pl, get_node (num-2), get_node (num-1)); 
 
1183
  CT_ExprList *el = new CT_ExprList;
 
1184
  el->AddSon (get_node (num-2));
 
1185
  el->AddSon (get_node (num-1));
 
1186
  el->AddProperties (CT_List::INTRO);
 
1187
  return new CT_TypeParamDecl (pl, get_node (num-4), get_node (num-3), el); 
 
1188
}
 
1189
 
 
1190
CTree *CCBuilder::non_type_param (CTree *result) {
 
1191
  // 2: decl_spec_seq  private_name
 
1192
  // 2: decl_spec_seq  abst_declarator
 
1193
  // 2: decl_spec_seq  declarator
 
1194
  // 3: decl_spec_seq  private_name  param_init
 
1195
  // 3: decl_spec_seq  abst_declarator  param_init
 
1196
  // 3: decl_spec_seq  declarator  param_init
 
1197
  if (! result)
 
1198
    result = new CT_NonTypeParamDecl (get_node (0), get_node (1));
 
1199
  else if (nodes () == 3)
 
1200
    ((CT_NonTypeParamDecl*)result)->Initializer (get_node (2));
 
1201
  return result;
 
1202
}
 
1203
 
 
1204
CTree *CCBuilder::template_id () {
 
1205
  // 3: template_name  <  >
 
1206
  // 4: template_name  <  template_arg_list  >
 
1207
  CT_TemplateArgList *tal;
 
1208
  if (nodes () == 3) 
 
1209
    tal = new CT_TemplateArgList;
 
1210
  else
 
1211
    tal = (CT_TemplateArgList*)get_node (2);
 
1212
  tal->PrefixSon (get_node (1));
 
1213
  tal->AddSon (get_node (nodes ()-1));
 
1214
  return new CT_TemplateName (get_node (0), tal);
 
1215
}
 
1216
 
 
1217
CTree *CCBuilder::template_arg_list () {
 
1218
  // 1 : template_arg
 
1219
  // 3+: template_arg  ,  template_arg ..
 
1220
  return list (new CT_TemplateArgList);
 
1221
}
 
1222
 
 
1223
CTree *CCBuilder::template_arg () {
 
1224
  // 1: ass_expr
 
1225
  // 1: type_id
 
1226
  // 1: id_expr
 
1227
  return get_node ();
 
1228
}
 
1229
 
 
1230
CTree *CCBuilder::explicit_instantiation () {
 
1231
  // 2: TEMPLATE  decl
 
1232
  // 3: EXTERN  TEMPLATE  decl  => GCC EXTENSION!!!
 
1233
  CT_TemplateParamList *tpl = new CT_TemplateParamList;
 
1234
  tpl->AddSon (get_node (nodes ()-2));
 
1235
  if (nodes () == 3)
 
1236
    return new CT_LinkageSpec (get_node (0), 0, 0, 
 
1237
      new CT_TemplateDecl (0, tpl, get_node (nodes ()-1)), 0);
 
1238
  return new CT_TemplateDecl (0, tpl, get_node (nodes ()-1));
 
1239
}
 
1240
 
 
1241
CTree *CCBuilder::explicit_specialization () {
 
1242
  // 4: TEMPLATE  <  >  decl
 
1243
  CT_TemplateParamList *tpl = new CT_TemplateParamList;
 
1244
  tpl->AddSon (get_node (0));
 
1245
  tpl->AddSon (get_node (1));
 
1246
  tpl->AddSon (get_node (2));
 
1247
  return new CT_TemplateDecl (0, tpl, get_node (3));
 
1248
}
 
1249
 
 
1250
/*****************************************************************************/
 
1251
/*                                                                           */
 
1252
/*                A . 1 3  E x c e p t i o n  h a n d l i n g                */
 
1253
/*                                                                           */
 
1254
/*****************************************************************************/
 
1255
 
 
1256
CTree *CCBuilder::try_block () { 
 
1257
  // 3: TRY  cmpd_stmt  handler_seq
 
1258
  return new CT_TryStmt (get_node (0), get_node (1), get_node (2));
 
1259
}
 
1260
 
 
1261
CTree *CCBuilder::fct_try_block () { 
 
1262
  // 3+: TRY  fct_body  handler_seq
 
1263
  // 4+: TRY  ctor_init  fct_body  handler_seq
 
1264
  return container ();
 
1265
}
 
1266
 
 
1267
CTree *CCBuilder::handler_seq () { 
 
1268
  // 1+: handler..
 
1269
  return list (new CT_HandlerSeq);
 
1270
}
 
1271
 
 
1272
CTree *CCBuilder::handler () { 
 
1273
  // 5: CATCH  (  exception_decl  )  cmpd_stmt
 
1274
  CT_ArgDeclList *adl = new CT_ArgDeclList (3);
 
1275
  adl->AddSon (get_node (1));
 
1276
  adl->AddSon (get_node (2));
 
1277
  adl->AddSon (get_node (3));
 
1278
  return new CT_Handler (get_node (0), adl, get_node (4));
 
1279
}
 
1280
 
 
1281
CTree *CCBuilder::exception_decl () { 
 
1282
  // 1: ...
 
1283
  // 1: type_spec_seq 
 
1284
  // 2: type_spec_seq  abst_declarator
 
1285
  // 2: type_spec_seq  declarator
 
1286
  if (nodes () == 2)
 
1287
    return new CT_ArgDecl (get_node (0), get_node (1));
 
1288
  return new CT_ArgDecl (get_node (0));
 
1289
}
 
1290
 
 
1291
CTree *CCBuilder::throw_expr () { 
 
1292
  // 1: THROW
 
1293
  // 2: THROW  ass_expr
 
1294
  if (nodes () == 1)
 
1295
    return new CT_ThrowExpr (get_node (0));
 
1296
  return new CT_ThrowExpr (get_node (0), get_node (1));
 
1297
}
 
1298
 
 
1299
CTree *CCBuilder::exception_spec () { 
 
1300
  // 3: THROW  (  )
 
1301
  // 4: THROW  (  ...  )
 
1302
  // 4: THROW  (  type_id_list  )
 
1303
  CT_ArgDeclList *adl;
 
1304
  if (nodes () == 3 || get_node (2)->NodeName () != CT_ArgDeclList::NodeId ()) {
 
1305
    adl = new CT_ArgDeclList;
 
1306
    if (nodes () == 4)
 
1307
      adl->AddSon (get_node (2));
 
1308
  } else
 
1309
    adl = (CT_ArgDeclList*)get_node (2);  
 
1310
  adl->PrefixSon (get_node (1));
 
1311
  adl->AddSon (get_node (nodes ()-1));
 
1312
  return new CT_ExceptionSpec (get_node (0), adl);
 
1313
}
 
1314
 
 
1315
CTree *CCBuilder::type_id_list () { 
 
1316
  // 1 : type_id
 
1317
  // 3+: type_id  ,  type_id ..
 
1318
  return list (new CT_ArgDeclList (3));
 
1319
}
 
1320
 
 
1321
 
 
1322
} // namespace Puma