~ubuntu-branches/ubuntu/quantal/aspectc++/quantal

« back to all changes in this revision

Viewing changes to Puma/src/parser/cparser/CBuilder.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-04-10 17:40:52 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080410174052-xdnsm7oi8hauyyf1
Tags: 1.0pre4~svn.20080409+dfsg-3
Fix another missing include, this time in Ag++/StdSystem.cc

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
17
17
// MA  02111-1307  USA                                            
18
18
 
19
 
#include "Puma/CBuilder.h"
20
 
#include "Puma/CSyntax.h"
21
 
#include "Puma/CTokens.h"
22
 
 
 
19
#include "Puma/CBuilder.h"
 
20
#include "Puma/CSyntax.h"
 
21
#include "Puma/CTokens.h"
 
22
 
23
23
namespace Puma {
24
24
 
25
25
 
26
 
/*****************************************************************************/
27
 
/*                                                                           */
28
 
/*                           A . 1   K e y w o r d s                         */
29
 
/*                                                                           */
30
 
/*****************************************************************************/
31
 
 
32
 
CTree *CBuilder::simple_name () {
33
 
  return new CT_SimpleName (get_node ());
34
 
}
35
 
   
36
 
/*****************************************************************************/
37
 
/*                                                                           */
38
 
/*               A . 2   L e x i c a l  c o n v e n t i o n s                */
39
 
/*                                                                           */
40
 
/*****************************************************************************/
41
 
 
42
 
CTree *CBuilder::literal () {
43
 
  if (get_node (0)->NodeName () == CT_String::NodeId () ||
44
 
      get_node (0)->NodeName () == CT_WideString::NodeId ())
45
 
    return get_node ();
46
 
  
47
 
  CTree *result;
48
 
  const char *txt = get_node (0)->token ()->text ();
49
 
  switch (get_node (0)->token ()->type ()) {
50
 
    case TOK_INT_VAL:
51
 
    case TOK_ZERO_VAL: 
52
 
      result = new CT_Integer ((CT_Token*)get_node (0)); break;
53
 
    case TOK_CHAR_VAL: 
54
 
      result = (txt[0] == 'L') ? 
55
 
               (CTree*)new CT_WideCharacter ((CT_Token*)get_node (0)) :
56
 
               (CTree*)new CT_Character ((CT_Token*)get_node (0)); 
57
 
      break;
58
 
    case TOK_FLT_VAL: 
59
 
      result = new CT_Float ((CT_Token*)get_node (0)); break;
60
 
    case TOK_BOOL_VAL: 
61
 
      result = new CT_Bool ((CT_Token*)get_node (0)); break;
62
 
    default: 
63
 
      result = (CTree*)0;
64
 
  };
65
 
  return result;
66
 
}
67
 
 
68
 
CTree *CBuilder::cmpd_str () {
69
 
  bool wide = false;
70
 
  for (int i = 0; (i < nodes ()) && ! wide; i++) 
71
 
    if (*(get_node (i)->token ()->text ().c_str()) == 'L')
72
 
      wide = true;
73
 
      
74
 
  return (wide) ? list (new CT_WideString (nodes ())) :
75
 
                  list (new CT_String (nodes ()));
76
 
}
77
 
 
78
 
CTree *CBuilder::str_literal () {
79
 
  return get_node ();
80
 
}
81
 
 
82
 
/*****************************************************************************/
83
 
/*                                                                           */
84
 
/*                   A . 3   B a s i c  c o n c e p t s                      */
85
 
/*                                                                           */
86
 
/*****************************************************************************/
87
 
 
88
 
CTree *CBuilder::trans_unit () {
89
 
  Container *declarations = (Container*)get_node ();
90
 
  CT_Program *result = new CT_Program (declarations->Sons ());
91
 
  copy_list (result, declarations);
92
 
  delete declarations;
93
 
  return result;
94
 
}
95
 
 
96
 
/*****************************************************************************/
97
 
/*                                                                           */
98
 
/*                      A . 4   E x p r e s s i o n s                        */
99
 
/*                                                                           */
100
 
/*****************************************************************************/
101
 
 
102
 
CTree *CBuilder::prim_expr () { 
103
 
  // 1: literal      => node
104
 
  // 1: id_expr      => node
105
 
  // 3: (  expr  )   => token  node  token
106
 
  if (nodes () == 3)
107
 
    return new CT_BracedExpr (get_node (0), get_node (1), get_node (2));
108
 
  else
109
 
    return get_node ();
110
 
}
111
 
 
112
 
CTree *CBuilder::cmpd_literal () { 
113
 
  // 6 : (  type_id  )  {  init_list  }
114
 
  CT_ExprList *el = (CT_ExprList*)get_node (4);
115
 
  if ((el->Sons () % 2) == 0)
116
 
    el->AddProperties (CT_List::END_SEP);
117
 
  el->PrefixSon (get_node (3));
118
 
  el->AddSon (get_node (5));
119
 
  el->AddProperties (CT_List::OPEN_CLOSE);
120
 
  return new CT_CmpdLiteral (get_node (0), get_node (1), get_node (2), el);
121
 
}
122
 
 
123
 
CTree *CBuilder::postfix_expr () { 
124
 
  // 1 : prim_expr
125
 
  // 1 : cmpd_literal
126
 
  // 1+: prim_expr  postfix_expr1...
127
 
  // 1+: cmpd_literal  postfix_expr1...
128
 
  CTree *result = get_node (0); 
129
 
  int num = nodes ();
130
 
  for (int n = 1; n < num; n++) {
131
 
    Container *c = (Container*)get_node (n);
132
 
    // 1: --
133
 
    // 1: ++
134
 
    // 2: .  identifier
135
 
    // 2: ->  identifier
136
 
    // 2: (  )
137
 
    // 3: (  expr_list  )
138
 
    // 3: [  expr  ]
139
 
    int token = c->token ()->type ();
140
 
    if (token == TOK_DECR || token == TOK_INCR)
141
 
      result = new CT_PostfixExpr (result, c->Son (0));
142
 
    else if (token == TOK_DOT)
143
 
      result = new CT_MembRefExpr (result, c->Son (0), c->Son (1));
144
 
    else if (token == TOK_PTS)
145
 
      result = new CT_MembPtrExpr (result, c->Son (0), c->Son (1));
146
 
    else if (token == TOK_OPEN_SQUARE)
147
 
      result = new CT_IndexExpr (result, c->Son (0), c->Son (1), c->Son (2));
148
 
    else if (token == TOK_OPEN_ROUND) {
149
 
      bool args = (c->Sons () == 3);
150
 
      CT_ExprList *el = args ? (CT_ExprList*)c->Son (1) : new CT_ExprList;
151
 
      if (! args)
152
 
        Push (el);
153
 
      el->AddProperties (CT_List::OPEN_CLOSE);
154
 
      el->PrefixSon (c->Son (0));
155
 
      el->AddSon (c->Son (args ? 2 : 1));
156
 
      result = new CT_CallExpr (result, el);
157
 
    } 
158
 
    delete c;
159
 
  }
160
 
  return result;
161
 
}
162
 
 
163
 
CTree *CBuilder::postfix_expr1 () { 
164
 
  return container ();
165
 
}
166
 
 
167
 
CTree *CBuilder::expr_list () { 
168
 
  return list (new CT_ExprList); 
169
 
}
170
 
 
171
 
CTree *CBuilder::unary_expr () { 
172
 
  // 1: postfix_expr
173
 
  // 2: --  unary_expr
174
 
  // 2: ++  unary_expr
175
 
  // 2: any_unary_op  cast_expr
176
 
  // 2: sizeof  unary_expr
177
 
  // 2: sizeof  unary_expr1
178
 
  if (nodes () == 1)
179
 
    return get_node ();
180
 
  int token = get_node ()->token ()->type ();
181
 
  if (token == TOK_AND)
182
 
    return new CT_AddrExpr (get_node (0), get_node (1));
183
 
  if (token == TOK_MUL)
184
 
    return new CT_DerefExpr (get_node (0), get_node (1));
185
 
  if (token == TOK_SIZEOF) {
186
 
    if (get_node (1)->NodeName () == Container::NodeId ()) {
187
 
      Container *c = (Container*) get_node (1);
188
 
      CTree *result = new CT_SizeofExpr (get_node (0), 
189
 
        c->Son (0), c->Son (1), c->Son (2));
190
 
      delete c;
191
 
      return result;
192
 
    } else
193
 
      return new CT_SizeofExpr (get_node (0), get_node (1));
194
 
  }
195
 
  return new CT_UnaryExpr (get_node (0), get_node (1));
196
 
}
197
 
 
198
 
CTree *CBuilder::unary_expr1 () { 
199
 
  // 3: (  type_id  )
200
 
  return container ();
201
 
}
202
 
 
203
 
CTree *CBuilder::cast_expr () { 
204
 
  // 1 : unary_expr
205
 
  // 2+: cast_expr1...  unary_expr
206
 
  int num = nodes ();
207
 
  CTree *result = get_node (num - 1);
208
 
  for (int i = num - 2; i >= 0; i--) {
209
 
    Container *c = (Container*) get_node (i);
210
 
    result = new CT_CastExpr (c->Son (0), c->Son (1), c->Son (2), result);
211
 
    delete c;
212
 
  }
213
 
  return result;  
214
 
}
215
 
 
216
 
CTree *CBuilder::cast_expr1 () { 
217
 
  // 3: (  type_id  )
218
 
  return container ();
219
 
}
220
 
 
221
 
// helper function for binary expression
222
 
CTree *CBuilder::lr_bin_expr () {
223
 
  CTree *result = get_node (0);
224
 
  for (int n = 1; n < nodes (); n += 2)
225
 
    result = new CT_BinaryExpr (result, get_node (n), get_node (n + 1));
226
 
  return result;
227
 
}
228
 
 
229
 
CTree *CBuilder::mul_expr ()     { return lr_bin_expr (); }
230
 
CTree *CBuilder::add_expr ()     { return lr_bin_expr (); }
231
 
CTree *CBuilder::shift_expr ()   { return lr_bin_expr (); }
232
 
CTree *CBuilder::rel_expr ()     { return lr_bin_expr (); }
233
 
CTree *CBuilder::equ_expr ()     { return lr_bin_expr (); }
234
 
CTree *CBuilder::and_expr ()     { return lr_bin_expr (); }
235
 
CTree *CBuilder::excl_or_expr () { return lr_bin_expr (); }
236
 
CTree *CBuilder::incl_or_expr () { return lr_bin_expr (); }
237
 
CTree *CBuilder::log_and_expr () { return lr_bin_expr (); }
238
 
CTree *CBuilder::log_or_expr ()  { return lr_bin_expr (); }
239
 
CTree *CBuilder::expr ()         { return lr_bin_expr (); }
240
 
 
241
 
CTree *CBuilder::cond_expr () {
242
 
  CTree *result = get_node (0);
243
 
  if (nodes () == 5)
244
 
    result = new CT_IfThenExpr (result, get_node (1), get_node (2),
245
 
                                get_node (3), get_node (4));
246
 
  return result;
247
 
}
248
 
 
249
 
CTree *CBuilder::ass_expr () { 
250
 
  // 1 : cond_expr
251
 
  // 2+: ass_expr1...  cond_expr
252
 
  int num = nodes ();
253
 
  CTree *result = get_node (num - 1);
254
 
  for (int i = num - 2; i >= 0; i--) {
255
 
    Container *c = (Container*) get_node (i);
256
 
    result = new CT_BinaryExpr (c->Son (0), c->Son (1), result);
257
 
    delete c;
258
 
  }
259
 
  return result;  
260
 
}
261
 
 
262
 
CTree *CBuilder::ass_expr1 () { 
263
 
  return container (); 
264
 
}
265
 
 
266
 
CTree *CBuilder::const_expr () { 
267
 
  return get_node (); 
268
 
}
269
 
 
270
 
/*****************************************************************************/
271
 
/*                                                                           */
272
 
/*                      A . 5   S t a t e m e n t s                          */
273
 
/*                                                                           */
274
 
/*****************************************************************************/
275
 
 
276
 
CTree *CBuilder::stmt () {
277
 
  return get_node (); 
278
 
}
279
 
 
280
 
CTree *CBuilder::label_stmt () {
281
 
  // 3: identifier  :  stmt         => node token node
282
 
  // 3: DEFAULT  :  stmt            => token token node
283
 
  // 4: CASE  const_expr  :  stmt   => token node token node
284
 
  if (nodes () == 3) {
285
 
    if (get_node (0)->NodeName () == CT_SimpleName::NodeId ()) {
286
 
      return new CT_LabelStmt (get_node (0), get_node (1), get_node (2));
287
 
    } else
288
 
      return new CT_DefaultStmt (get_node (0), get_node (1), get_node (2));
289
 
  } else 
290
 
    return new CT_CaseStmt (get_node (0), get_node (1), get_node (2), 
291
 
                            get_node (3));
292
 
}
293
 
 
294
 
CTree *CBuilder::expr_stmt () {
295
 
  // 1: ;
296
 
  // 2: expr  ;
297
 
  if (nodes () == 1)
298
 
    return new CT_ExprStmt ((CTree*)0, get_node (0));
299
 
  else
300
 
    return new CT_ExprStmt (get_node (0), get_node (1));
301
 
}
302
 
 
303
 
CTree *CBuilder::cmpd_stmt () {
304
 
  // 2: {  }              => token token
305
 
  // 3: {  stmt_seq  }    => token cont token
306
 
  CT_CmpdStmt *result = new CT_CmpdStmt;
307
 
  result->AddSon (get_node (0));
308
 
  if (nodes () == 3) {
309
 
    Container *container = (Container*)get_node (1);
310
 
    for (int i = 0; i < container->Sons (); i++)
311
 
      result->AddSon (container->Son (i));
312
 
    delete container;
313
 
    result->AddSon (get_node (2));
314
 
  } else
315
 
    result->AddSon (get_node (1));
316
 
  return result;
317
 
}
318
 
 
319
 
CTree *CBuilder::stmt_seq () {
320
 
  return container (); 
321
 
}
322
 
 
323
 
CTree *CBuilder::select_stmt () {
324
 
  // 5: SWITCH  (  condition  )  sub_stmt
325
 
  // 5: IF  (  condition  )  sub_stmt
326
 
  // 7: IF  (  condition  )  sub_stmt  ELSE  sub_stmt
327
 
  if (get_node (0)->token ()->type () == TOK_SWITCH)
328
 
    return new CT_SwitchStmt (get_node (0), get_node (1), get_node (2),
329
 
                              get_node (3), get_node (4));
330
 
  else if (nodes () == 5)
331
 
    return new CT_IfStmt (get_node (0), get_node (1), get_node (2),
332
 
                          get_node (3), get_node (4));
333
 
  else
334
 
    return new CT_IfElseStmt (get_node (0), get_node (1), get_node (2),
335
 
                get_node (3), get_node (4), get_node (5), get_node (6));
336
 
}
337
 
 
338
 
CTree *CBuilder::sub_stmt () {
339
 
  return get_node ();
340
 
}
341
 
 
342
 
CTree *CBuilder::condition (CTree *) {
343
 
  return get_node ();
344
 
}
345
 
 
346
 
CTree *CBuilder::iter_stmt () {
347
 
  // 5: WHILE  (  condition  )  sub_stmt
348
 
  // 6: FOR  (  for_init_stmt  ;  )  sub_stmt
349
 
  // 7: DO  sub_stmt  WHILE  (  expr  )  ;
350
 
  // 7: FOR  (  for_init_stmt  ;  expr  )  sub_stmt
351
 
  // 7: FOR  (  for_init_stmt  condition  ;  )  sub_stmt
352
 
  // 8: FOR  (  for_init_stmt  condition  ;  expr  )  sub_stmt
353
 
  if (nodes () == 5) {
354
 
    return new CT_WhileStmt (get_node (0), get_node (1), get_node (2), 
355
 
                             get_node (3), get_node (4));
356
 
  } else if (nodes () == 6) {
357
 
    return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
358
 
                           (CTree*)0, get_node (3), (CTree*)0, 
359
 
                           get_node (4), get_node (5));
360
 
  } else if (nodes () == 7) {
361
 
    if (get_node (0)->token ()->type () == TOK_DO) {
362
 
      return new CT_DoStmt (get_node (0), get_node (1), get_node (2), 
363
 
                            get_node (3), get_node (4), get_node (5), 
364
 
                            get_node (6));
365
 
    } else if (get_node (3)->token ()->type () == TOK_SEMI_COLON) {
366
 
      return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
367
 
                            (CTree*)0, get_node (3), get_node (4), 
368
 
                            get_node (5), get_node (6));
369
 
    } else {
370
 
      return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
371
 
                             get_node (3), get_node (4), (CTree*)0, 
372
 
                             get_node (5), get_node (6));
373
 
    }
374
 
  } else { // nodes () == 8
375
 
    return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
376
 
                           get_node (3), get_node (4), get_node (5), 
377
 
                           get_node (6), get_node (7));
378
 
  }
379
 
}
380
 
 
381
 
CTree *CBuilder::for_init_stmt () {
382
 
  // 1: expr_stmt
383
 
  // 1: simple_decl
384
 
  return get_node ();
385
 
}
386
 
 
387
 
CTree *CBuilder::jump_stmt () {
388
 
  // 2: BREAK  ;
389
 
  // 2: CONTINUE  ;
390
 
  // 2: RETURN  ;
391
 
  // 3: RETURN  expression  ;
392
 
  // 3: GOTO  identifier  ;
393
 
  CT_Token *token = (CT_Token*)get_node (0);
394
 
  if (token->token ()->type () == TOK_BREAK)
395
 
    return new CT_BreakStmt (token, get_node (1));
396
 
  else if (token->token ()->type () == TOK_CONTINUE)
397
 
    return new CT_ContinueStmt (token, get_node (1));
398
 
  else if (token->token ()->type () == TOK_GOTO)
399
 
    return new CT_GotoStmt (token, get_node (1), get_node (2));
400
 
  else { // RETURN
401
 
    if (nodes () == 2) {
402
 
      return new CT_ReturnStmt (token, (CTree*)0, get_node (1));
403
 
    } else {
404
 
      return new CT_ReturnStmt (token, get_node (1), get_node (2));
405
 
    }
406
 
  } 
407
 
}
408
 
 
409
 
/*****************************************************************************/
410
 
/*                                                                           */
411
 
/*                     A . 6   D e c l a r a t i o n s                       */
412
 
/*                                                                           */
413
 
/*****************************************************************************/
414
 
 
415
 
CTree *CBuilder::decl_seq () { 
416
 
  return container (); 
417
 
}
418
 
 
419
 
CTree *CBuilder::decl () { 
420
 
  return get_node (); 
421
 
}
422
 
 
423
 
CTree *CBuilder::block_decl () { 
424
 
  return get_node (); 
425
 
}
426
 
 
427
 
CTree *CBuilder::simple_decl () { 
428
 
  int offset = 0;
429
 
  CT_DeclSpecSeq *dss;
430
 
  if (get_node ()->NodeName () == CT_DeclSpecSeq::NodeId ())
431
 
    dss = (CT_DeclSpecSeq*)get_node (offset++);
432
 
  else //{
433
 
    dss = new CT_DeclSpecSeq;
434
 
//    Push (dss);
435
 
//  }
436
 
  CT_DeclaratorList *dl;
437
 
  if (offset + 1 < nodes ())
438
 
    dl = (CT_DeclaratorList*)get_node (offset++);
439
 
  else //{
440
 
    dl = new CT_DeclaratorList;
441
 
//    Push (dl);
442
 
//  }
443
 
  return new CT_ObjDecl (dss, dl, get_node (offset));
444
 
}
445
 
 
446
 
CTree *CBuilder::decl_spec () { 
447
 
  return get_node (); 
448
 
}
449
 
 
450
 
CTree *CBuilder::decl_spec_seq () { 
451
 
  return list (new CT_DeclSpecSeq); 
452
 
}
453
 
 
454
 
CTree *CBuilder::decl_spec_seq1 () { 
455
 
  return get_node (); 
456
 
}
457
 
 
458
 
// helper function for primitive declaration specifiers
459
 
CTree *CBuilder::prim_ds () { 
460
 
  return new CT_PrimDeclSpec ((CT_Token*)get_node ()); 
461
 
}
462
 
 
463
 
CTree *CBuilder::misc_spec ()          { return prim_ds (); }
464
 
CTree *CBuilder::storage_class_spec () { return prim_ds (); }
465
 
CTree *CBuilder::fct_spec ()           { return prim_ds (); }
466
 
 
467
 
CTree *CBuilder::type_spec () { 
468
 
  return get_node (); 
469
 
}
470
 
 
471
 
CTree *CBuilder::simple_type_spec () { 
472
 
  return (get_node ()->NodeName () == CT_Token::NodeId ()) ?
473
 
    prim_ds () : get_node ();
474
 
}
475
 
 
476
 
CTree *CBuilder::type_name () { 
477
 
  return get_node (); 
478
 
}
479
 
 
480
 
CTree *CBuilder::elaborated_type_spec () { 
481
 
  // 2: class_key  identifier
482
 
  // 2: ENUM  identifier
483
 
  int token = get_node ()->token ()->type ();
484
 
  if (token == TOK_CLASS || token == TOK_STRUCT)
485
 
    return new CT_ClassSpec (get_node (0), get_node (1));
486
 
  if (token == TOK_UNION)
487
 
    return new CT_UnionSpec (get_node (0), get_node (1));
488
 
  else // TOK_ENUM
489
 
    return new CT_EnumSpec (get_node (0), get_node (1));
490
 
}
491
 
 
492
 
CTree *CBuilder::enum_spec (CTree *result) { 
493
 
  // 5: ENUM  identifier {  enumerator_list  }
494
 
  // 5: ENUM  private_name {  enumerator_list  }
495
 
  if (! result) {
496
 
    result = new CT_EnumDef (get_node (0), get_node (1));
497
 
  } else {
498
 
    CT_EnumeratorList *el = (CT_EnumeratorList*)get_node (3);
499
 
    if (el->Sons () > 0 && (el->Sons () % 2) == 0)
500
 
      el->AddProperties (CT_List::END_SEP);
501
 
    el->PrefixSon (get_node (2));
502
 
    el->AddSon (get_node (4));
503
 
    ((CT_EnumDef*)result)->Enumerators (el);
504
 
  }
505
 
  return result;
506
 
}
507
 
 
508
 
CTree *CBuilder::enum_spec_err (CTree *es) { 
509
 
  delete es;
510
 
  return (CTree*)0;
511
 
}
512
 
 
513
 
CTree *CBuilder::enumerator_list () { 
514
 
  return list (new CT_EnumeratorList);
515
 
}
516
 
 
517
 
CTree *CBuilder::enumerator_def () { 
518
 
  // 1: enumerator
519
 
  // 3: enumerator  =  const_expr
520
 
  CT_Enumerator *e = (CT_Enumerator*)get_node (0);
521
 
  if (nodes () == 3) {
522
 
    CT_ExprList *el = new CT_ExprList;
523
 
//    Push (el);
524
 
    el->AddSon (get_node (1));
525
 
    el->AddSon (get_node (2));
526
 
    el->AddProperties (CT_List::INTRO);
527
 
    e->Initializer (el);
528
 
  }
529
 
  return e;
530
 
}
531
 
 
532
 
CTree *CBuilder::enumerator () { 
533
 
  return new CT_Enumerator (get_node ());
534
 
}
535
 
 
536
 
/*****************************************************************************/
537
 
/*                                                                           */
538
 
/*                     A . 7   D e c l a r a t o r s                         */
539
 
/*                                                                           */
540
 
/*****************************************************************************/
541
 
 
542
 
CTree *CBuilder::init_declarator_list () { 
543
 
  return list (new CT_DeclaratorList); 
544
 
}
545
 
 
546
 
CTree *CBuilder::init_declarator (CTree* id) {
547
 
  if (! id) 
548
 
    return new CT_InitDeclarator (get_node (0));
549
 
  if (nodes () == 2)
550
 
    ((CT_InitDeclarator*)id)->Initializer (get_node (1));
551
 
  return id;
552
 
}
553
 
 
554
 
CTree *CBuilder::declarator () {
555
 
  // 1 : direct_declarator
556
 
  // 2+: ptr_operator..  direct_declarator
557
 
  int num = nodes ();
558
 
  CTree *result = get_node (num-1);
559
 
  for (int i = num-1; i > 0; i--) {
560
 
    Container *p = (Container*)get_node (i-1); // ptr-operator
561
 
    if (p->Sons () == 1)
562
 
      result = new CT_PtrDeclarator (p->Son (0), (CTree*)0, result);
563
 
    else if (p->Sons () == 2)
564
 
      result = new CT_PtrDeclarator (p->Son (0), p->Son (1), result);
565
 
    delete p;
566
 
  }
567
 
  return result;
568
 
}
569
 
 
570
 
CTree *CBuilder::direct_declarator () { 
571
 
  // 1 : declarator_id                            => node
572
 
  // 2+: declarator_id  direct_declarator1...     => node cont...
573
 
  // 3 : (  declarator  )                         => token node token
574
 
  // 3+: (  declarator  )  direct_declarator1...  => token node token cont...
575
 
  if (nodes () == 1)
576
 
    return get_node (0); 
577
 
 
578
 
  CTree *result;
579
 
  int braced = (get_node (0)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0;
580
 
  if (! braced)
581
 
    result = get_node (0);
582
 
  else {
583
 
    // win specific declaration specifier
584
 
    if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
585
 
      braced++;
586
 
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
587
 
    } else
588
 
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
589
 
    // braced declarator only
590
 
    if (nodes () == braced+1)
591
 
      return result;
592
 
  }
593
 
  
594
 
  for (int i = 1 + braced; i < nodes (); i++) {
595
 
    Container *d1 = (Container*)get_node (i);
596
 
    if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) 
597
 
      result = new CT_ArrayDeclarator (result, d1->Son (0), d1->Son (1), 
598
 
                                       d1->Son (2));
599
 
    else {
600
 
      CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1);
601
 
      args->PrefixSon (d1->Son (0));
602
 
      args->AddSon (d1->Son (2));
603
 
      if (d1->Sons () == 4) {
604
 
        if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ())
605
 
          result = new CT_FctDeclarator (result, args, d1->Son (3), 0);
606
 
        else
607
 
          result = new CT_FctDeclarator (result, args, 0, d1->Son (3));
608
 
      } else if (d1->Sons () == 5) {
609
 
        result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4));
610
 
      } else
611
 
        result = new CT_FctDeclarator (result, args, 0, 0);
612
 
    }
613
 
    delete d1;
614
 
  }
615
 
  return result;
616
 
617
 
 
618
 
CTree *CBuilder::direct_declarator1 () { 
619
 
  // 3: [  array_delim  ]
620
 
  // 3: (  param_decl_clause  )
621
 
  // 3: (  identifier_list  )
622
 
  return container ();
623
 
624
 
 
625
 
CTree *CBuilder::identifier_list () { 
626
 
  return list (new CT_ArgNameList);
627
 
628
 
 
629
 
CTree *CBuilder::array_delim () { 
630
 
  // 0:
631
 
  // 1: *
632
 
  // 1: ass_expr
633
 
  // 1: cv_qual_seq
634
 
  // 2: cv_qual_seq  *
635
 
  // 2: cv_qual_seq  ass_expr
636
 
  // 2: STATIC  ass_expr
637
 
  // 3: STATIC  cv_qual_seq  ass_expr
638
 
  // 3: cv_qual_seq  STATIC  ass_expr
639
 
  bool pos0 = false;
640
 
  CTree *star, *stat, *quals, *expr = star = stat = quals = (CTree*)0;
641
 
  if (nodes () == 1) {
642
 
    if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
643
 
      quals = get_node (0);
644
 
    else if (get_node (0)->NodeName () == CT_Token::NodeId () && 
645
 
             get_node (0)->token ()->type () == TOK_MUL) 
646
 
      star = get_node (0);
647
 
    else
648
 
      expr = get_node (0);
649
 
  } else if (nodes () == 2) {
650
 
    if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
651
 
      stat = get_node (0);
652
 
      expr = get_node (1);
653
 
    } else {
654
 
      quals = get_node (0);
655
 
      if (get_node (1)->NodeName () == CT_Token::NodeId () && 
656
 
          get_node (1)->token ()->type () == TOK_MUL)
657
 
        star = get_node (1);
658
 
      else
659
 
        expr = get_node (1);
660
 
    }
661
 
  } else if (nodes () == 3) {
662
 
    if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
 
26
/*****************************************************************************/
 
27
/*                                                                           */
 
28
/*                           A . 1   K e y w o r d s                         */
 
29
/*                                                                           */
 
30
/*****************************************************************************/
 
31
 
 
32
CTree *CBuilder::simple_name () {
 
33
  return new CT_SimpleName (get_node ());
 
34
}
 
35
   
 
36
/*****************************************************************************/
 
37
/*                                                                           */
 
38
/*               A . 2   L e x i c a l  c o n v e n t i o n s                */
 
39
/*                                                                           */
 
40
/*****************************************************************************/
 
41
 
 
42
CTree *CBuilder::literal () {
 
43
  if (get_node (0)->NodeName () == CT_String::NodeId () ||
 
44
      get_node (0)->NodeName () == CT_WideString::NodeId ())
 
45
    return get_node ();
 
46
  
 
47
  CTree *result;
 
48
  const char *txt = get_node (0)->token ()->text ();
 
49
  switch (get_node (0)->token ()->type ()) {
 
50
    case TOK_INT_VAL:
 
51
    case TOK_ZERO_VAL: 
 
52
      result = new CT_Integer ((CT_Token*)get_node (0)); break;
 
53
    case TOK_CHAR_VAL: 
 
54
      result = (txt[0] == 'L') ? 
 
55
               (CTree*)new CT_WideCharacter ((CT_Token*)get_node (0)) :
 
56
               (CTree*)new CT_Character ((CT_Token*)get_node (0)); 
 
57
      break;
 
58
    case TOK_FLT_VAL: 
 
59
      result = new CT_Float ((CT_Token*)get_node (0)); break;
 
60
    case TOK_BOOL_VAL: 
 
61
      result = new CT_Bool ((CT_Token*)get_node (0)); break;
 
62
    default: 
 
63
      result = (CTree*)0;
 
64
  };
 
65
  return result;
 
66
}
 
67
 
 
68
CTree *CBuilder::cmpd_str () {
 
69
  bool wide = false;
 
70
  for (int i = 0; (i < nodes ()) && ! wide; i++) 
 
71
    if (*(get_node (i)->token ()->text ()) == 'L')
 
72
      wide = true;
 
73
      
 
74
  return (wide) ? list (new CT_WideString (nodes ())) :
 
75
                  list (new CT_String (nodes ()));
 
76
}
 
77
 
 
78
CTree *CBuilder::str_literal () {
 
79
  return get_node ();
 
80
}
 
81
 
 
82
/*****************************************************************************/
 
83
/*                                                                           */
 
84
/*                   A . 3   B a s i c  c o n c e p t s                      */
 
85
/*                                                                           */
 
86
/*****************************************************************************/
 
87
 
 
88
CTree *CBuilder::trans_unit () {
 
89
  Container *declarations = (Container*)get_node ();
 
90
  CT_Program *result = new CT_Program (declarations->Sons ());
 
91
  copy_list (result, declarations);
 
92
  delete declarations;
 
93
  return result;
 
94
}
 
95
 
 
96
/*****************************************************************************/
 
97
/*                                                                           */
 
98
/*                      A . 4   E x p r e s s i o n s                        */
 
99
/*                                                                           */
 
100
/*****************************************************************************/
 
101
 
 
102
CTree *CBuilder::prim_expr () { 
 
103
  // 1: literal      => node
 
104
  // 1: id_expr      => node
 
105
  // 3: (  expr  )   => token  node  token
 
106
  if (nodes () == 3)
 
107
    return new CT_BracedExpr (get_node (0), get_node (1), get_node (2));
 
108
  else
 
109
    return get_node ();
 
110
}
 
111
 
 
112
CTree *CBuilder::cmpd_literal () { 
 
113
  // 5 : (  type_id  )  {  init_list  }
 
114
  // 6 : (  type_id  )  {  init_list  }
 
115
  CT_ExprList *el;
 
116
  int num = nodes ();
 
117
  if (num == 5) {
 
118
    el = new CT_ExprList ();
 
119
  } else {
 
120
    el = (CT_ExprList*)get_node (4);
 
121
    if ((el->Sons () % 2) == 0)
 
122
      el->AddProperties (CT_List::END_SEP);
 
123
  }
 
124
  el->PrefixSon (get_node (3));
 
125
  el->AddSon (get_node (num-1));
 
126
  el->AddProperties (CT_List::OPEN_CLOSE);
 
127
  return new CT_CmpdLiteral (get_node (0), get_node (1), get_node (2), el);
 
128
}
 
129
 
 
130
CTree *CBuilder::postfix_expr () { 
 
131
  // 1 : prim_expr
 
132
  // 1 : cmpd_literal
 
133
  // 1+: prim_expr  postfix_expr1...
 
134
  // 1+: cmpd_literal  postfix_expr1...
 
135
  CTree *result = get_node (0); 
 
136
  int num = nodes ();
 
137
  for (int n = 1; n < num; n++) {
 
138
    Container *c = (Container*)get_node (n);
 
139
    // 1: --
 
140
    // 1: ++
 
141
    // 2: .  identifier
 
142
    // 2: ->  identifier
 
143
    // 2: (  )
 
144
    // 3: (  expr_list  )
 
145
    // 3: [  expr  ]
 
146
    int token = c->token ()->type ();
 
147
    if (token == TOK_DECR || token == TOK_INCR)
 
148
      result = new CT_PostfixExpr (result, c->Son (0));
 
149
    else if (token == TOK_DOT)
 
150
      result = new CT_MembRefExpr (result, c->Son (0), c->Son (1));
 
151
    else if (token == TOK_PTS)
 
152
      result = new CT_MembPtrExpr (result, c->Son (0), c->Son (1));
 
153
    else if (token == TOK_OPEN_SQUARE)
 
154
      result = new CT_IndexExpr (result, c->Son (0), c->Son (1), c->Son (2));
 
155
    else if (token == TOK_OPEN_ROUND) {
 
156
      bool args = (c->Sons () == 3);
 
157
      CT_ExprList *el = args ? (CT_ExprList*)c->Son (1) : new CT_ExprList;
 
158
      if (! args)
 
159
        Push (el);
 
160
      el->AddProperties (CT_List::OPEN_CLOSE);
 
161
      el->PrefixSon (c->Son (0));
 
162
      el->AddSon (c->Son (args ? 2 : 1));
 
163
      result = new CT_CallExpr (result, el);
 
164
    } 
 
165
    delete c;
 
166
  }
 
167
  return result;
 
168
}
 
169
 
 
170
CTree *CBuilder::postfix_expr1 () { 
 
171
  return container ();
 
172
}
 
173
 
 
174
CTree *CBuilder::expr_list () { 
 
175
  return list (new CT_ExprList); 
 
176
}
 
177
 
 
178
CTree *CBuilder::unary_expr () { 
 
179
  // 1: postfix_expr
 
180
  // 2: --  unary_expr
 
181
  // 2: ++  unary_expr
 
182
  // 2: any_unary_op  cast_expr
 
183
  // 2: sizeof  unary_expr
 
184
  // 2: sizeof  unary_expr1
 
185
  if (nodes () == 1)
 
186
    return get_node ();
 
187
  int token = get_node ()->token ()->type ();
 
188
  if (token == TOK_AND)
 
189
    return new CT_AddrExpr (get_node (0), get_node (1));
 
190
  if (token == TOK_MUL)
 
191
    return new CT_DerefExpr (get_node (0), get_node (1));
 
192
  if (token == TOK_SIZEOF) {
 
193
    if (get_node (1)->NodeName () == Container::NodeId ()) {
 
194
      Container *c = (Container*) get_node (1);
 
195
      CTree *result = new CT_SizeofExpr (get_node (0), 
 
196
        c->Son (0), c->Son (1), c->Son (2));
 
197
      delete c;
 
198
      return result;
 
199
    } else
 
200
      return new CT_SizeofExpr (get_node (0), get_node (1));
 
201
  }
 
202
  return new CT_UnaryExpr (get_node (0), get_node (1));
 
203
}
 
204
 
 
205
CTree *CBuilder::unary_expr1 () { 
 
206
  // 3: (  type_id  )
 
207
  return container ();
 
208
}
 
209
 
 
210
CTree *CBuilder::cast_expr () { 
 
211
  // 1: cast_expr1
 
212
  // 1: unary_expr
 
213
  return get_node ();
 
214
}
 
215
 
 
216
CTree *CBuilder::cast_expr1 () { 
 
217
  // 2+: cast_expr2... unary_expr
 
218
  int num = nodes ();
 
219
  CTree *result = get_node (num - 1);
 
220
  for (int i = num - 2; i >= 0; i--) {
 
221
    Container *c = (Container*) get_node (i);
 
222
    result = new CT_CastExpr (c->Son (0), c->Son (1), c->Son (2), result);
 
223
    delete c;
 
224
  }
 
225
  return result;  
 
226
}
 
227
 
 
228
CTree *CBuilder::cast_expr2 () { 
 
229
  // 3: (  type_id  )
 
230
  return container ();
 
231
}
 
232
 
 
233
// helper function for binary expression
 
234
CTree *CBuilder::lr_bin_expr () {
 
235
  CTree *result = get_node (0);
 
236
  for (int n = 1; n < nodes (); n += 2)
 
237
    result = new CT_BinaryExpr (result, get_node (n), get_node (n + 1));
 
238
  return result;
 
239
}
 
240
 
 
241
CTree *CBuilder::mul_expr ()     { return lr_bin_expr (); }
 
242
CTree *CBuilder::add_expr ()     { return lr_bin_expr (); }
 
243
CTree *CBuilder::shift_expr ()   { return lr_bin_expr (); }
 
244
CTree *CBuilder::rel_expr ()     { return lr_bin_expr (); }
 
245
CTree *CBuilder::equ_expr ()     { return lr_bin_expr (); }
 
246
CTree *CBuilder::and_expr ()     { return lr_bin_expr (); }
 
247
CTree *CBuilder::excl_or_expr () { return lr_bin_expr (); }
 
248
CTree *CBuilder::incl_or_expr () { return lr_bin_expr (); }
 
249
CTree *CBuilder::log_and_expr () { return lr_bin_expr (); }
 
250
CTree *CBuilder::log_or_expr ()  { return lr_bin_expr (); }
 
251
CTree *CBuilder::expr ()         { return lr_bin_expr (); }
 
252
 
 
253
CTree *CBuilder::cond_expr () {
 
254
  CTree *result = get_node (0);
 
255
  if (nodes () == 5)
 
256
    result = new CT_IfThenExpr (result, get_node (1), get_node (2),
 
257
                                get_node (3), get_node (4));
 
258
  return result;
 
259
}
 
260
 
 
261
CTree *CBuilder::ass_expr () { 
 
262
  // 1 : cond_expr
 
263
  // 2+: ass_expr1...  cond_expr
 
264
  int num = nodes ();
 
265
  CTree *result = get_node (num - 1);
 
266
  for (int i = num - 2; i >= 0; i--) {
 
267
    Container *c = (Container*) get_node (i);
 
268
    result = new CT_BinaryExpr (c->Son (0), c->Son (1), result);
 
269
    delete c;
 
270
  }
 
271
  return result;  
 
272
}
 
273
 
 
274
CTree *CBuilder::ass_expr1 () { 
 
275
  return container (); 
 
276
}
 
277
 
 
278
CTree *CBuilder::const_expr () { 
 
279
  return get_node (); 
 
280
}
 
281
 
 
282
/*****************************************************************************/
 
283
/*                                                                           */
 
284
/*                      A . 5   S t a t e m e n t s                          */
 
285
/*                                                                           */
 
286
/*****************************************************************************/
 
287
 
 
288
CTree *CBuilder::stmt () {
 
289
  return get_node (); 
 
290
}
 
291
 
 
292
CTree *CBuilder::label_stmt () {
 
293
  // 3: identifier  :  stmt         => node token node
 
294
  // 3: DEFAULT  :  stmt            => token token node
 
295
  // 4: CASE  const_expr  :  stmt   => token node token node
 
296
  if (nodes () == 3) {
 
297
    if (get_node (0)->NodeName () == CT_SimpleName::NodeId ()) {
 
298
      return new CT_LabelStmt (get_node (0), get_node (1), get_node (2));
 
299
    } else
 
300
      return new CT_DefaultStmt (get_node (0), get_node (1), get_node (2));
 
301
  } else 
 
302
    return new CT_CaseStmt (get_node (0), get_node (1), get_node (2), 
 
303
                            get_node (3));
 
304
}
 
305
 
 
306
CTree *CBuilder::expr_stmt () {
 
307
  // 1: ;
 
308
  // 2: expr  ;
 
309
  if (nodes () == 1)
 
310
    return new CT_ExprStmt ((CTree*)0, get_node (0));
 
311
  else
 
312
    return new CT_ExprStmt (get_node (0), get_node (1));
 
313
}
 
314
 
 
315
CTree *CBuilder::cmpd_stmt () {
 
316
  // 2: {  }              => token token
 
317
  // 3: {  stmt_seq  }    => token cont token
 
318
  CT_CmpdStmt *result = new CT_CmpdStmt;
 
319
  result->AddSon (get_node (0));
 
320
  if (nodes () == 3) {
 
321
    Container *container = (Container*)get_node (1);
 
322
    for (int i = 0; i < container->Sons (); i++)
 
323
      result->AddSon (container->Son (i));
 
324
    delete container;
 
325
    result->AddSon (get_node (2));
 
326
  } else
 
327
    result->AddSon (get_node (1));
 
328
  return result;
 
329
}
 
330
 
 
331
CTree *CBuilder::stmt_seq () {
 
332
  return container (); 
 
333
}
 
334
 
 
335
CTree *CBuilder::select_stmt () {
 
336
  // 5: SWITCH  (  condition  )  sub_stmt
 
337
  // 5: IF  (  condition  )  sub_stmt
 
338
  // 7: IF  (  condition  )  sub_stmt  ELSE  sub_stmt
 
339
  if (get_node (0)->token ()->type () == TOK_SWITCH)
 
340
    return new CT_SwitchStmt (get_node (0), get_node (1), get_node (2),
 
341
                              get_node (3), get_node (4));
 
342
  else if (nodes () == 5)
 
343
    return new CT_IfStmt (get_node (0), get_node (1), get_node (2),
 
344
                          get_node (3), get_node (4));
 
345
  else
 
346
    return new CT_IfElseStmt (get_node (0), get_node (1), get_node (2),
 
347
                get_node (3), get_node (4), get_node (5), get_node (6));
 
348
}
 
349
 
 
350
CTree *CBuilder::sub_stmt () {
 
351
  return get_node ();
 
352
}
 
353
 
 
354
CTree *CBuilder::condition (CTree *) {
 
355
  return get_node ();
 
356
}
 
357
 
 
358
CTree *CBuilder::iter_stmt () {
 
359
  // 5: WHILE  (  condition  )  sub_stmt
 
360
  // 6: FOR  (  for_init_stmt  ;  )  sub_stmt
 
361
  // 7: DO  sub_stmt  WHILE  (  expr  )  ;
 
362
  // 7: FOR  (  for_init_stmt  ;  expr  )  sub_stmt
 
363
  // 7: FOR  (  for_init_stmt  condition  ;  )  sub_stmt
 
364
  // 8: FOR  (  for_init_stmt  condition  ;  expr  )  sub_stmt
 
365
  if (nodes () == 5) {
 
366
    return new CT_WhileStmt (get_node (0), get_node (1), get_node (2), 
 
367
                             get_node (3), get_node (4));
 
368
  } else if (nodes () == 6) {
 
369
    return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
 
370
                           (CTree*)0, get_node (3), (CTree*)0, 
 
371
                           get_node (4), get_node (5));
 
372
  } else if (nodes () == 7) {
 
373
    if (get_node (0)->token ()->type () == TOK_DO) {
 
374
      return new CT_DoStmt (get_node (0), get_node (1), get_node (2), 
 
375
                            get_node (3), get_node (4), get_node (5), 
 
376
                            get_node (6));
 
377
    } else if (get_node (3)->token ()->type () == TOK_SEMI_COLON) {
 
378
      return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
 
379
                            (CTree*)0, get_node (3), get_node (4), 
 
380
                            get_node (5), get_node (6));
 
381
    } else {
 
382
      return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
 
383
                             get_node (3), get_node (4), (CTree*)0, 
 
384
                             get_node (5), get_node (6));
 
385
    }
 
386
  } else { // nodes () == 8
 
387
    return new CT_ForStmt (get_node (0), get_node (1), get_node (2), 
 
388
                           get_node (3), get_node (4), get_node (5), 
 
389
                           get_node (6), get_node (7));
 
390
  }
 
391
}
 
392
 
 
393
CTree *CBuilder::for_init_stmt () {
 
394
  // 1: expr_stmt
 
395
  // 1: simple_decl
 
396
  return get_node ();
 
397
}
 
398
 
 
399
CTree *CBuilder::jump_stmt () {
 
400
  // 2: BREAK  ;
 
401
  // 2: CONTINUE  ;
 
402
  // 2: RETURN  ;
 
403
  // 3: RETURN  expression  ;
 
404
  // 3: GOTO  identifier  ;
 
405
  CT_Token *token = (CT_Token*)get_node (0);
 
406
  if (token->token ()->type () == TOK_BREAK)
 
407
    return new CT_BreakStmt (token, get_node (1));
 
408
  else if (token->token ()->type () == TOK_CONTINUE)
 
409
    return new CT_ContinueStmt (token, get_node (1));
 
410
  else if (token->token ()->type () == TOK_GOTO)
 
411
    return new CT_GotoStmt (token, get_node (1), get_node (2));
 
412
  else { // RETURN
 
413
    if (nodes () == 2) {
 
414
      return new CT_ReturnStmt (token, (CTree*)0, get_node (1));
 
415
    } else {
 
416
      return new CT_ReturnStmt (token, get_node (1), get_node (2));
 
417
    }
 
418
  } 
 
419
}
 
420
 
 
421
/*****************************************************************************/
 
422
/*                                                                           */
 
423
/*                     A . 6   D e c l a r a t i o n s                       */
 
424
/*                                                                           */
 
425
/*****************************************************************************/
 
426
 
 
427
CTree *CBuilder::decl_seq () { 
 
428
  return container (); 
 
429
}
 
430
 
 
431
CTree *CBuilder::decl () { 
 
432
  return get_node (); 
 
433
}
 
434
 
 
435
CTree *CBuilder::block_decl () { 
 
436
  return get_node (); 
 
437
}
 
438
 
 
439
CTree *CBuilder::simple_decl () { 
 
440
  int offset = 0;
 
441
  CT_DeclSpecSeq *dss;
 
442
  if (get_node ()->NodeName () == CT_DeclSpecSeq::NodeId ())
 
443
    dss = (CT_DeclSpecSeq*)get_node (offset++);
 
444
  else //{
 
445
    dss = new CT_DeclSpecSeq;
 
446
//    Push (dss);
 
447
//  }
 
448
  CT_DeclaratorList *dl;
 
449
  if (offset + 1 < nodes ())
 
450
    dl = (CT_DeclaratorList*)get_node (offset++);
 
451
  else //{
 
452
    dl = new CT_DeclaratorList;
 
453
//    Push (dl);
 
454
//  }
 
455
  return new CT_ObjDecl (dss, dl, get_node (offset));
 
456
}
 
457
 
 
458
CTree *CBuilder::decl_spec () { 
 
459
  return get_node (); 
 
460
}
 
461
 
 
462
CTree *CBuilder::decl_spec_seq () { 
 
463
  return list (new CT_DeclSpecSeq); 
 
464
}
 
465
 
 
466
CTree *CBuilder::decl_spec_seq1 () { 
 
467
  return get_node (); 
 
468
}
 
469
 
 
470
// helper function for primitive declaration specifiers
 
471
CTree *CBuilder::prim_ds () { 
 
472
  return new CT_PrimDeclSpec ((CT_Token*)get_node ()); 
 
473
}
 
474
 
 
475
CTree *CBuilder::misc_spec ()          { return prim_ds (); }
 
476
CTree *CBuilder::storage_class_spec () { return prim_ds (); }
 
477
CTree *CBuilder::fct_spec ()           { return prim_ds (); }
 
478
 
 
479
CTree *CBuilder::type_spec () { 
 
480
  return get_node (); 
 
481
}
 
482
 
 
483
CTree *CBuilder::simple_type_spec () { 
 
484
  return (get_node ()->NodeName () == CT_Token::NodeId ()) ?
 
485
    prim_ds () : get_node ();
 
486
}
 
487
 
 
488
CTree *CBuilder::type_name () { 
 
489
  return get_node (); 
 
490
}
 
491
 
 
492
CTree *CBuilder::elaborated_type_spec () { 
 
493
  // 2: class_key  identifier
 
494
  // 2: ENUM  identifier
 
495
  int token = get_node ()->token ()->type ();
 
496
  if (token == TOK_CLASS || token == TOK_STRUCT)
 
497
    return new CT_ClassSpec (get_node (0), get_node (1));
 
498
  if (token == TOK_UNION)
 
499
    return new CT_UnionSpec (get_node (0), get_node (1));
 
500
  else // TOK_ENUM
 
501
    return new CT_EnumSpec (get_node (0), get_node (1));
 
502
}
 
503
 
 
504
CTree *CBuilder::enum_spec (CTree *result) { 
 
505
  // 5: ENUM  identifier {  enumerator_list  }
 
506
  // 5: ENUM  private_name {  enumerator_list  }
 
507
  if (! result) {
 
508
    result = new CT_EnumDef (get_node (0), get_node (1));
 
509
  } else {
 
510
    CT_EnumeratorList *el = (CT_EnumeratorList*)get_node (3);
 
511
    if (el->Sons () > 0 && (el->Sons () % 2) == 0)
 
512
      el->AddProperties (CT_List::END_SEP);
 
513
    el->PrefixSon (get_node (2));
 
514
    el->AddSon (get_node (4));
 
515
    ((CT_EnumDef*)result)->Enumerators (el);
 
516
  }
 
517
  return result;
 
518
}
 
519
 
 
520
CTree *CBuilder::enum_spec_err (CTree *es) { 
 
521
  delete es;
 
522
  return (CTree*)0;
 
523
}
 
524
 
 
525
CTree *CBuilder::enumerator_list () { 
 
526
  return list (new CT_EnumeratorList);
 
527
}
 
528
 
 
529
CTree *CBuilder::enumerator_def () { 
 
530
  // 1: enumerator
 
531
  // 3: enumerator  =  const_expr
 
532
  CT_Enumerator *e = (CT_Enumerator*)get_node (0);
 
533
  if (nodes () == 3) {
 
534
    CT_ExprList *el = new CT_ExprList;
 
535
//    Push (el);
 
536
    el->AddSon (get_node (1));
 
537
    el->AddSon (get_node (2));
 
538
    el->AddProperties (CT_List::INTRO);
 
539
    e->Initializer (el);
 
540
  }
 
541
  return e;
 
542
}
 
543
 
 
544
CTree *CBuilder::enumerator () { 
 
545
  return new CT_Enumerator (get_node ());
 
546
}
 
547
 
 
548
CTree *CBuilder::asm_def () { 
 
549
  // 1: ASM  (  str_literal  )  ;
 
550
  return new CT_AsmDef (get_node (0), get_node (1), get_node (2),
 
551
                        get_node (3), get_node (4));
 
552
}
 
553
 
 
554
 
 
555
/*****************************************************************************/
 
556
/*                                                                           */
 
557
/*                     A . 7   D e c l a r a t o r s                         */
 
558
/*                                                                           */
 
559
/*****************************************************************************/
 
560
 
 
561
CTree *CBuilder::init_declarator_list () { 
 
562
  return list (new CT_DeclaratorList); 
 
563
}
 
564
 
 
565
CTree *CBuilder::init_declarator (CTree* id) {
 
566
  if (! id)
 
567
    return new CT_InitDeclarator (get_node (0), (nodes () == 2 ? get_node (1):0));
 
568
  if (get_node (nodes () - 1)->NodeName () == CT_ExprList::NodeId ())
 
569
    ((CT_InitDeclarator*)id)->Initializer (get_node (nodes () - 1));
 
570
  return id;
 
571
}
 
572
 
 
573
CTree *CBuilder::declarator () {
 
574
  // 1 : direct_declarator
 
575
  // 2+: ptr_operator..  direct_declarator
 
576
  int num = nodes ();
 
577
  CTree *result = get_node (num-1);
 
578
  for (int i = num-1; i > 0; i--) {
 
579
    Container *p = (Container*)get_node (i-1); // ptr-operator
 
580
    if (p->Sons () == 1)
 
581
      result = new CT_PtrDeclarator (p->Son (0), (CTree*)0, result);
 
582
    else if (p->Sons () == 2)
 
583
      result = new CT_PtrDeclarator (p->Son (0), p->Son (1), result);
 
584
    delete p;
 
585
  }
 
586
  return result;
 
587
}
 
588
 
 
589
CTree *CBuilder::direct_declarator () { 
 
590
  // 1 : declarator_id                            => node
 
591
  // 2+: declarator_id  direct_declarator1...     => node cont...
 
592
  // 3 : (  declarator  )                         => token node token
 
593
  // 3+: (  declarator  )  direct_declarator1...  => token node token cont...
 
594
  if (nodes () == 1)
 
595
    return get_node (0); 
 
596
 
 
597
  CTree *result;
 
598
  int braced = (get_node (0)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0;
 
599
  if (! braced)
 
600
    result = get_node (0);
 
601
  else {
 
602
    // win specific declaration specifier
 
603
    if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
 
604
      braced++;
 
605
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
 
606
    } else
 
607
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
 
608
    // braced declarator only
 
609
    if (nodes () == braced+1)
 
610
      return result;
 
611
  }
 
612
  
 
613
  for (int i = 1 + braced; i < nodes (); i++) {
 
614
    Container *d1 = (Container*)get_node (i);
 
615
    if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) 
 
616
      result = new CT_ArrayDeclarator (result, d1->Son (0), d1->Son (1), 
 
617
                                       d1->Son (2));
 
618
    else {
 
619
      CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1);
 
620
      args->PrefixSon (d1->Son (0));
 
621
      args->AddSon (d1->Son (2));
 
622
      if (d1->Sons () == 4) {
 
623
        if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ())
 
624
          result = new CT_FctDeclarator (result, args, d1->Son (3), 0);
 
625
        else
 
626
          result = new CT_FctDeclarator (result, args, 0, d1->Son (3));
 
627
      } else if (d1->Sons () == 5) {
 
628
        result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4));
 
629
      } else
 
630
        result = new CT_FctDeclarator (result, args, 0, 0);
 
631
    }
 
632
    delete d1;
 
633
  }
 
634
  return result;
 
635
 
636
 
 
637
CTree *CBuilder::direct_declarator1 () { 
 
638
  // 3: [  array_delim  ]
 
639
  // 3: (  param_decl_clause  )
 
640
  // 3: (  identifier_list  )
 
641
  return container ();
 
642
 
643
 
 
644
CTree *CBuilder::identifier_list () { 
 
645
  return list (new CT_ArgNameList);
 
646
 
647
 
 
648
CTree *CBuilder::array_delim () { 
 
649
  // 0:
 
650
  // 1: *
 
651
  // 1: ass_expr
 
652
  // 1: cv_qual_seq
 
653
  // 2: cv_qual_seq  *
 
654
  // 2: cv_qual_seq  ass_expr
 
655
  // 2: STATIC  ass_expr
 
656
  // 3: STATIC  cv_qual_seq  ass_expr
 
657
  // 3: cv_qual_seq  STATIC  ass_expr
 
658
  bool pos0 = false;
 
659
  CTree *star, *stat, *quals, *expr = star = stat = quals = (CTree*)0;
 
660
  if (nodes () == 1) {
 
661
    if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
 
662
      quals = get_node (0);
 
663
    else if (get_node (0)->NodeName () == CT_Token::NodeId () && 
 
664
             get_node (0)->token ()->type () == TOK_MUL) 
 
665
      star = get_node (0);
 
666
    else
 
667
      expr = get_node (0);
 
668
  } else if (nodes () == 2) {
 
669
    if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
 
670
      stat = get_node (0);
 
671
      expr = get_node (1);
 
672
    } else {
 
673
      quals = get_node (0);
 
674
      if (get_node (1)->NodeName () == CT_Token::NodeId () && 
 
675
          get_node (1)->token ()->type () == TOK_MUL)
 
676
        star = get_node (1);
 
677
      else
 
678
        expr = get_node (1);
 
679
    }
 
680
  } else if (nodes () == 3) {
 
681
    if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
663
682
      stat = get_node (0); 
664
 
      quals = get_node (1);
665
 
    } else {
666
 
      quals = get_node (0); pos0 = true;
667
 
      stat = get_node (1);
668
 
    }
669
 
    expr = get_node (2);
670
 
  }
 
683
      quals = get_node (1);
 
684
    } else {
 
685
      quals = get_node (0); pos0 = true;
 
686
      stat = get_node (1);
 
687
    }
 
688
    expr = get_node (2);
 
689
  }
671
690
  if (pos0)
672
 
    return new CT_ArrayDelimiter (star, quals, stat, expr, pos0);
673
 
  return new CT_ArrayDelimiter (star, stat, quals, expr, pos0);
674
 
}
675
 
 
676
 
CTree *CBuilder::ptr_operator () { 
677
 
  return container (); 
678
 
}
679
 
 
680
 
CTree *CBuilder::cv_qual_seq () { 
681
 
  return list (new CT_DeclSpecSeq); 
682
 
}
683
 
 
684
 
CTree *CBuilder::cv_qual () { 
685
 
  return prim_ds (); 
686
 
}
687
 
 
688
 
CTree *CBuilder::declarator_id () { 
689
 
  return get_node (); 
690
 
}
691
 
 
692
 
CTree *CBuilder::type_id () { 
693
 
  return new CT_NamedType (get_node (0), get_node (1));
694
 
}
695
 
 
696
 
CTree *CBuilder::abst_declarator () {
697
 
  // 1 : direct_abst_declarator
698
 
  // 1+: ptr_operator..
699
 
  // 2+: ptr_operator..  direct_abst_declarator
700
 
  return declarator ();
701
 
}
702
 
 
703
 
CTree *CBuilder::direct_abst_declarator () { 
704
 
  // 1 : direct_abst_declarator1                              => cont
705
 
  // 2+: direct_abst_declarator1  direct_abst_declarator1...  => cont cont...
706
 
  // 3 : ( abst_declarator )                                  => token node token
707
 
  // 3+: ( abst_declarator )  direct_abst_declarator1...      => token node token cont...
708
 
  CTree *result;
709
 
  int braced = (get_node (0)->NodeName () != Container::NodeId ()) ? 3 : 0;
710
 
  if (! braced)
711
 
    result = get_node (nodes () - 1); // PrivateName, pushed by semantic
712
 
  else {
713
 
    // win specific declaration specifier
714
 
    if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
715
 
      braced++;
716
 
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
717
 
    } else
718
 
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
719
 
    // braced declarator only
720
 
    if (nodes () == braced)
721
 
      return result;
722
 
  }
723
 
  
724
 
  int num = nodes () - (braced ? 0 : 1);
725
 
  for (int i = 0 + braced; i < num; i++) {
726
 
    Container *d1 = (Container*)get_node (i);
727
 
    if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) {
728
 
      if (d1->Son (1)->NodeName () == CT_ArrayDelimiter::NodeId ()) {
729
 
        result = new CT_ArrayDeclarator (result, d1->Son (0), 
730
 
          d1->Son (1), d1->Son (2));
731
 
      } else if (d1->Son (1)->token ()->type () == TOK_CLOSE_SQUARE) {
732
 
        result = new CT_ArrayDeclarator (result, d1->Son (0),
733
 
          new CT_ArrayDelimiter (0, 0, 0, 0), d1->Son (1));
734
 
      } else if (d1->Son (1)->NodeName () == CT_Token::NodeId () &&
735
 
                 d1->Son (1)->token ()->type () == TOK_MUL) {
736
 
        result = new CT_ArrayDeclarator (result, d1->Son (0),
737
 
          new CT_ArrayDelimiter (d1->Son (1), 0, 0, 0), d1->Son (2));
738
 
      }
739
691
else {
740
 
        result = new CT_ArrayDeclarator (result, d1->Son (0),
741
 
          new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2));
742
 
      }
743
 
    } else {
744
 
      CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1);
745
 
      args->PrefixSon (d1->Son (0));
746
 
      args->AddSon (d1->Son (2));
747
 
      if (d1->Sons () == 4) {
748
 
        if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ())
749
 
          result = new CT_FctDeclarator (result, args, d1->Son (3), 0);
750
 
        else
751
 
          result = new CT_FctDeclarator (result, args, 0, d1->Son (3));
752
 
      } else if (d1->Sons () == 5) {
753
 
        result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4));
754
 
      } else
755
 
        result = new CT_FctDeclarator (result, args, 0, 0);
756
 
    }
757
 
    delete d1;
758
 
  }
759
 
  return result;
760
 
761
 
 
762
 
CTree *CBuilder::direct_abst_declarator1 () { 
763
 
  // 2: [  ]
764
 
  // 3: [  *  ]
765
 
  // 3: [  ass_expr  ]
766
 
  // 3: (  param_decl_clause  )
767
 
  return container ();
768
 
769
 
 
770
 
CTree *CBuilder::param_decl_clause () {
771
 
  // 0:                             => 
772
 
  // 1: ...                         => token
773
 
  // 1: param_decl_list             => cont
774
 
  // 2: param_decl_list  ...        => cont token
775
 
  if (nodes () == 0)
776
 
    return new CT_ArgDeclList ();
777
 
    
778
 
  CT_ArgDeclList *result;
779
 
  if (get_node (0)->NodeName () != Container::NodeId ()) {
780
 
    result = new CT_ArgDeclList ();
781
 
    result->AddSon (new CT_ArgDecl (get_node (0)));
782
 
    return result;
783
 
  }
784
 
  
785
 
  Container *al = (Container*)get_node (0);
786
 
  int add_args = (nodes () == 2) ? 1 : 0;
787
 
  result = new CT_ArgDeclList (al->Sons () + add_args);  
788
 
  copy_list (result, al);
789
 
  if (add_args) { 
790
 
    if ((al->Sons () % 2) == 1)
791
 
      result->AddProperties (CT_List::NO_LAST_SEP);
792
 
    result->AddSon (new CT_ArgDecl (get_node (nodes ()-1))); // ...
793
 
  }
794
 
  
795
 
  delete al;
796
 
  return result;
797
 
}
798
 
 
799
 
CTree *CBuilder::param_decl_list () {
800
 
  return container ();  
801
 
}
802
 
 
803
 
CTree *CBuilder::param_decl () {
804
 
  // 1: param_decl1 
805
 
  // 3: param_decl1  param_init
806
 
  CT_ArgDecl *ad = (CT_ArgDecl*)get_node (0);
807
 
  if (nodes () == 2)
808
 
    ad->Initializer (get_node (1));
809
 
  return ad;
810
 
}
811
 
 
812
 
CTree *CBuilder::param_decl1 () {
813
 
  // 2: decl_spec_seq  abst_declarator
814
 
  // 2: decl_spec_seq  declarator
815
 
  // 2: decl_spec_seq  private_name
816
 
  return new CT_ArgDecl (get_node (0), get_node (1));
817
 
}
818
 
 
819
 
CTree *CBuilder::fct_def () {
820
 
  // 2: declarator  fct_body
821
 
  // 2: declarator  fct_try_block
822
 
  // 3: declarator  ctor_init  fct_body
823
 
  // 3: declarator  arg_decl_seq  fct_body
824
 
  // 3: decl_spec_seq  declarator  fct_body
825
 
  // 3: decl_spec_seq  declarator  fct_try_block
826
 
  // 4: decl_spec_seq  declarator  ctor_init  fct_body
827
 
  // 4: decl_spec_seq  declarator  arg_decl_seq  fct_body
828
 
  CTree *dss, *hs, *ci, *as, *t = dss = hs = ci = as = (CTree*)0;
829
 
  CTree *d, *b = 0;
830
 
  if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
831
 
    dss = get_node (0);
832
 
  int offset = dss ? 1 : 0;
833
 
  d = get_node (offset);
834
 
  if (nodes () == 1 || (nodes () == 2 && 
835
 
       get_node (1)->NodeName () != CT_CmpdStmt::NodeId () &&
836
 
       get_node (1)->NodeName () != Container::NodeId ())) {
837
 
    b = error ();
838
 
    Push (b);
839
 
  } else if (get_node (1+offset)->NodeName () == CT_CmpdStmt::NodeId ()) {
840
 
    b = get_node (1+offset);
841
 
  } else if (get_node (1+offset)->NodeName () == CT_MembInitList::NodeId () ||
842
 
             get_node (1+offset)->NodeName () == CT_ExprList::NodeId ()) {
843
 
    ci = get_node (1+offset);
844
 
    b = get_node (2+offset);
845
 
  } else if (get_node (1+offset)->NodeName () == CT_ArgDeclSeq::NodeId ()) {
846
 
    as = get_node (1+offset);
847
 
    b = get_node (2+offset);
848
 
  } else {
849
 
    Container *cont = (Container*)get_node (1+offset); 
850
 
    t = cont->Son (0); 
851
 
    if (cont->Son (1)->NodeName () == CT_MembInitList::NodeId ())
852
 
      ci = cont->Son (1);
853
 
    offset = ci ? 1 : 0;
854
 
    b = cont->Son (1+offset);
855
 
    hs = cont->Son (2+offset);
856
 
    delete cont;
857
 
  }                                       
858
 
  return new CT_FctDef (dss, d, t, ci, as, b, hs); 
859
 
}
860
 
 
861
 
CTree *CBuilder::arg_decl_seq () {
862
 
  return list (new CT_ArgDeclSeq (nodes ()));
863
 
}
864
 
 
865
 
CTree *CBuilder::fct_body () {
866
 
  // 1: cmpd_stmt
867
 
  return get_node (0);
868
 
}
869
 
 
870
 
CTree *CBuilder::init () {
871
 
  // 2: =  init_clause 
872
 
  // 3: (  expr_list  )
873
 
  CT_ExprList *result;
874
 
  if (get_node (1)->NodeName () != CT_ExprList::NodeId ()) {
875
 
    result = new CT_ExprList;
876
 
    result->AddSon (get_node (1));
877
 
  } else
878
 
    result = (CT_ExprList*)get_node (1);
879
 
 
880
 
  result->PrefixSon (get_node (0));
881
 
  if (nodes () == 2)  // =  init_clause
882
 
    result->AddProperties (CT_List::INTRO);
883
 
  else {              // (  expr_list  )
884
 
    result->AddSon (get_node (2));
885
 
    result->AddProperties (CT_List::OPEN_CLOSE);
886
 
  }
887
 
  return result;
888
 
}
889
 
 
890
 
CTree *CBuilder::init_clause () {
891
 
  // 1: ass_expr
892
 
  // 2: {  }
893
 
  // 3: {  init_list  }
894
 
  if (nodes () == 1) 
895
 
    return get_node (0);
896
 
 
897
 
  CT_ExprList *result = 0;
898
 
  if (nodes () == 2) {        // "{ }"
899
 
    result = new CT_ExprList;
900
 
    result->AddSon (get_node (0));
901
 
    result->AddSon (get_node (1));
902
 
  } else if (nodes () == 3) { // "{ init_list }"
903
 
    result = (CT_ExprList*)get_node (1);
904
 
    if ((result->Sons () % 2) == 0)
905
 
      result->AddProperties (CT_List::END_SEP);
906
 
    result->PrefixSon (get_node (0));
907
 
    result->AddSon (get_node (2));
908
 
  } 
909
 
  result->AddProperties (CT_List::OPEN_CLOSE);
910
 
  return result;
911
 
}
912
 
 
913
 
CTree *CBuilder::init_list () { 
914
 
  return list (new CT_ExprList); 
915
 
}
916
 
 
917
 
CTree *CBuilder::init_list_item () { 
918
 
  // 1: init_clause
919
 
  // 2: designation  init_clause
920
 
  if (nodes () == 1)
921
 
    return get_node (); 
922
 
  Container *c = (Container*)get_node (0);
923
 
  CTree *result = new CT_BinaryExpr (c->Son (0), c->Son (1), get_node (1)); 
924
 
  delete c;
925
 
  return result;
926
 
}
927
 
 
928
 
CTree *CBuilder::designation () { 
929
 
  // 2+: designator...  =
930
 
  CT_DesignatorSeq *ds = new CT_DesignatorSeq (nodes () - 1);
931
 
  for (int i = 0; i < nodes () - 1; i++)
932
 
    ds->AddSon (get_node (i));
933
 
  Container *result = new Container;
934
 
  result->AddSon (ds);
935
 
  result->AddSon (get_node (nodes () - 1));
936
 
  return result;
937
 
}
938
 
 
939
 
CTree *CBuilder::designator () { 
940
 
  // 2: .  identifier
941
 
  // 3: [  const_expr  ]
942
 
  if (nodes () == 2)
943
 
    return new CT_MembDesignator (get_node (0), get_node (1));
944
 
  else
945
 
    return new CT_IndexDesignator (get_node (0), get_node (1), get_node (2));
946
 
}
947
 
 
948
 
/*****************************************************************************/
949
 
/*                                                                           */
950
 
/*                          A . 8   C l a s s e s                            */
951
 
/*                                                                           */
952
 
/*****************************************************************************/
953
 
 
954
 
CTree *CBuilder::class_spec (CTree *result) {
955
 
  Container *head = (Container*)get_node (0);
956
 
  if (! result) {
957
 
    if (head->Son (0)->token ()->type () == TOK_UNION)
958
 
      result = new CT_UnionDef (head->Son (0), head->Son (1));
959
 
    else 
960
 
      result = new CT_ClassDef (head->Son (0), head->Son (1));
961
 
  } else {
962
 
    CT_MembList *ml = nodes () == 4 ? 
963
 
      (CT_MembList*)get_node (2) : new CT_MembList;
964
 
//    if (nodes () != 4)
965
 
//      Push (ml);
966
 
    ml->PrefixSon (get_node (1));
 
692
    return new CT_ArrayDelimiter (star, quals, stat, expr, pos0);
 
693
  return new CT_ArrayDelimiter (star, stat, quals, expr, pos0);
 
694
}
 
695
 
 
696
CTree *CBuilder::ptr_operator () { 
 
697
  return container (); 
 
698
}
 
699
 
 
700
CTree *CBuilder::cv_qual_seq () { 
 
701
  return list (new CT_DeclSpecSeq); 
 
702
}
 
703
 
 
704
CTree *CBuilder::cv_qual () { 
 
705
  return prim_ds (); 
 
706
}
 
707
 
 
708
CTree *CBuilder::declarator_id () { 
 
709
  return get_node (); 
 
710
}
 
711
 
 
712
CTree *CBuilder::type_id () { 
 
713
  return new CT_NamedType (get_node (0), get_node (1));
 
714
}
 
715
 
 
716
CTree *CBuilder::abst_declarator () {
 
717
  // 1 : direct_abst_declarator
 
718
  // 1+: ptr_operator..
 
719
  // 2+: ptr_operator..  direct_abst_declarator
 
720
  return declarator ();
 
721
}
 
722
 
 
723
CTree *CBuilder::direct_abst_declarator () { 
 
724
  // 1 : direct_abst_declarator1                              => cont
 
725
  // 2+: direct_abst_declarator1  direct_abst_declarator1...  => cont cont...
 
726
  // 3 : ( abst_declarator )                                  => token node token
 
727
  // 3+: ( abst_declarator )  direct_abst_declarator1...      => token node token cont...
 
728
  CTree *result;
 
729
  int braced = (get_node (0)->NodeName () != Container::NodeId ()) ? 3 : 0;
 
730
  if (! braced)
 
731
    result = get_node (nodes () - 1); // PrivateName, pushed by semantic
 
732
  else {
 
733
    // win specific declaration specifier
 
734
    if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
 
735
      braced++;
 
736
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
 
737
    } else
 
738
      result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
 
739
    // braced declarator only
 
740
    if (nodes () == braced)
 
741
      return result;
 
742
  }
 
743
  
 
744
  int num = nodes () - (braced ? 0 : 1);
 
745
  for (int i = 0 + braced; i < num; i++) {
 
746
    Container *d1 = (Container*)get_node (i);
 
747
    if (d1->Son (0)->token ()->type () == TOK_OPEN_SQUARE) {
 
748
      if (d1->Son (1)->NodeName () == CT_ArrayDelimiter::NodeId ()) {
 
749
        result = new CT_ArrayDeclarator (result, d1->Son (0), 
 
750
          d1->Son (1), d1->Son (2));
 
751
      } else if (d1->Son (1)->token ()->type () == TOK_CLOSE_SQUARE) {
 
752
        result = new CT_ArrayDeclarator (result, d1->Son (0),
 
753
          new CT_ArrayDelimiter (0, 0, 0, 0), d1->Son (1));
 
754
      } else if (d1->Son (1)->NodeName () == CT_Token::NodeId () &&
 
755
                 d1->Son (1)->token ()->type () == TOK_MUL) {
 
756
        result = new CT_ArrayDeclarator (result, d1->Son (0),
 
757
          new CT_ArrayDelimiter (d1->Son (1), 0, 0, 0), d1->Son (2));
 
758
      }
967
759
else {
 
760
        result = new CT_ArrayDeclarator (result, d1->Son (0),
 
761
          new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2));
 
762
      }
 
763
    } else {
 
764
      CT_ArgDeclList *args = (CT_ArgDeclList*)d1->Son (1);
 
765
      args->PrefixSon (d1->Son (0));
 
766
      args->AddSon (d1->Son (2));
 
767
      if (d1->Sons () == 4) {
 
768
        if (d1->Son (3)->NodeName () == CT_DeclSpecSeq::NodeId ())
 
769
          result = new CT_FctDeclarator (result, args, d1->Son (3), 0);
 
770
        else
 
771
          result = new CT_FctDeclarator (result, args, 0, d1->Son (3));
 
772
      } else if (d1->Sons () == 5) {
 
773
        result = new CT_FctDeclarator (result, args, d1->Son (3), d1->Son (4));
 
774
      } else
 
775
        result = new CT_FctDeclarator (result, args, 0, 0);
 
776
    }
 
777
    delete d1;
 
778
  }
 
779
  return result;
 
780
 
781
 
 
782
CTree *CBuilder::direct_abst_declarator1 () { 
 
783
  // 2: [  ]
 
784
  // 3: [  *  ]
 
785
  // 3: [  ass_expr  ]
 
786
  // 3: (  param_decl_clause  )
 
787
  return container ();
 
788
 
789
 
 
790
CTree *CBuilder::param_decl_clause () {
 
791
  // 0:                             => 
 
792
  // 1: ...                         => token
 
793
  // 1: param_decl_list             => cont
 
794
  // 2: param_decl_list  ...        => cont token
 
795
  if (nodes () == 0)
 
796
    return new CT_ArgDeclList ();
 
797
    
 
798
  CT_ArgDeclList *result;
 
799
  if (get_node (0)->NodeName () != Container::NodeId ()) {
 
800
    result = new CT_ArgDeclList ();
 
801
    result->AddSon (new CT_ArgDecl (get_node (0)));
 
802
    return result;
 
803
  }
 
804
  
 
805
  Container *al = (Container*)get_node (0);
 
806
  int add_args = (nodes () == 2) ? 1 : 0;
 
807
  result = new CT_ArgDeclList (al->Sons () + add_args);  
 
808
  copy_list (result, al);
 
809
  if (add_args) { 
 
810
    if ((al->Sons () % 2) == 1)
 
811
      result->AddProperties (CT_List::NO_LAST_SEP);
 
812
    result->AddSon (new CT_ArgDecl (get_node (nodes ()-1))); // ...
 
813
  }
 
814
  
 
815
  delete al;
 
816
  return result;
 
817
}
 
818
 
 
819
CTree *CBuilder::param_decl_list () {
 
820
  return container ();  
 
821
}
 
822
 
 
823
CTree *CBuilder::param_decl () {
 
824
  // 1: param_decl1 
 
825
  // 3: param_decl1  param_init
 
826
  CT_ArgDecl *ad = (CT_ArgDecl*)get_node (0);
 
827
  if (nodes () == 2)
 
828
    ad->Initializer (get_node (1));
 
829
  return ad;
 
830
}
 
831
 
 
832
CTree *CBuilder::param_decl1 () {
 
833
  // 2: decl_spec_seq  abst_declarator
 
834
  // 2: decl_spec_seq  declarator
 
835
  // 2: decl_spec_seq  private_name
 
836
  return new CT_ArgDecl (get_node (0), get_node (1));
 
837
}
 
838
 
 
839
CTree *CBuilder::fct_def () {
 
840
  // 2: declarator  fct_body
 
841
  // 2: declarator  fct_try_block
 
842
  // 3: declarator  ctor_init  fct_body
 
843
  // 3: declarator  arg_decl_seq  fct_body
 
844
  // 3: decl_spec_seq  declarator  fct_body
 
845
  // 3: decl_spec_seq  declarator  fct_try_block
 
846
  // 4: decl_spec_seq  declarator  ctor_init  fct_body
 
847
  // 4: decl_spec_seq  declarator  arg_decl_seq  fct_body
 
848
  CTree *dss, *hs, *ci, *as, *t = dss = hs = ci = as = (CTree*)0;
 
849
  CTree *d, *b = 0;
 
850
  if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
 
851
    dss = get_node (0);
 
852
  int offset = dss ? 1 : 0;
 
853
  d = get_node (offset);
 
854
  if (nodes () == 1 || (nodes () == 2 && 
 
855
       get_node (1)->NodeName () != CT_CmpdStmt::NodeId () &&
 
856
       get_node (1)->NodeName () != Container::NodeId ())) {
 
857
    b = error ();
 
858
    Push (b);
 
859
  } else if (get_node (1+offset)->NodeName () == CT_CmpdStmt::NodeId ()) {
 
860
    b = get_node (1+offset);
 
861
  } else if (get_node (1+offset)->NodeName () == CT_MembInitList::NodeId () ||
 
862
             get_node (1+offset)->NodeName () == CT_ExprList::NodeId ()) {
 
863
    ci = get_node (1+offset);
 
864
    b = get_node (2+offset);
 
865
  } else if (get_node (1+offset)->NodeName () == CT_ArgDeclSeq::NodeId ()) {
 
866
    as = get_node (1+offset);
 
867
    b = get_node (2+offset);
 
868
  } else {
 
869
    Container *cont = (Container*)get_node (1+offset); 
 
870
    t = cont->Son (0); 
 
871
    if (cont->Son (1)->NodeName () == CT_MembInitList::NodeId ())
 
872
      ci = cont->Son (1);
 
873
    offset = ci ? 1 : 0;
 
874
    b = cont->Son (1+offset);
 
875
    hs = cont->Son (2+offset);
 
876
    delete cont;
 
877
  }                                       
 
878
  return new CT_FctDef (dss, d, t, ci, as, b, hs); 
 
879
}
 
880
 
 
881
CTree *CBuilder::arg_decl_seq () {
 
882
  return list (new CT_ArgDeclSeq (nodes ()));
 
883
}
 
884
 
 
885
CTree *CBuilder::fct_body () {
 
886
  // 1: cmpd_stmt
 
887
  return get_node (0);
 
888
}
 
889
 
 
890
CTree *CBuilder::init () {
 
891
  // 2: =  init_clause 
 
892
  // 3: (  expr_list  )
 
893
  CT_ExprList *result;
 
894
  if (get_node (1)->NodeName () != CT_ExprList::NodeId ()) {
 
895
    result = new CT_ExprList;
 
896
    result->AddSon (get_node (1));
 
897
  } else
 
898
    result = (CT_ExprList*)get_node (1);
 
899
 
 
900
  result->PrefixSon (get_node (0));
 
901
  if (nodes () == 2)  // =  init_clause
 
902
    result->AddProperties (CT_List::INTRO);
 
903
  else {              // (  expr_list  )
 
904
    result->AddSon (get_node (2));
 
905
    result->AddProperties (CT_List::OPEN_CLOSE);
 
906
  }
 
907
  return result;
 
908
}
 
909
 
 
910
CTree *CBuilder::init_clause () {
 
911
  // 1: ass_expr
 
912
  // 2: {  }
 
913
  // 3: {  init_list  }
 
914
  if (nodes () == 1) 
 
915
    return get_node (0);
 
916
 
 
917
  CT_ExprList *result = 0;
 
918
  if (nodes () == 2) {        // "{ }"
 
919
    result = new CT_ExprList;
 
920
    result->AddSon (get_node (0));
 
921
    result->AddSon (get_node (1));
 
922
  } else if (nodes () == 3) { // "{ init_list }"
 
923
    result = (CT_ExprList*)get_node (1);
 
924
    if ((result->Sons () % 2) == 0)
 
925
      result->AddProperties (CT_List::END_SEP);
 
926
    result->PrefixSon (get_node (0));
 
927
    result->AddSon (get_node (2));
 
928
  } 
 
929
  result->AddProperties (CT_List::OPEN_CLOSE);
 
930
  return result;
 
931
}
 
932
 
 
933
CTree *CBuilder::init_list () { 
 
934
  return list (new CT_ExprList); 
 
935
}
 
936
 
 
937
CTree *CBuilder::init_list_item () { 
 
938
  // 1: init_clause
 
939
  // 2: designation  init_clause
 
940
  if (nodes () == 1)
 
941
    return get_node (); 
 
942
  Container *c = (Container*)get_node (0);
 
943
  CTree *result = new CT_BinaryExpr (c->Son (0), c->Son (1), get_node (1)); 
 
944
  delete c;
 
945
  return result;
 
946
}
 
947
 
 
948
CTree *CBuilder::designation () { 
 
949
  // 2+: designator...  =
 
950
  CT_DesignatorSeq *ds = new CT_DesignatorSeq (nodes () - 1);
 
951
  for (int i = 0; i < nodes () - 1; i++)
 
952
    ds->AddSon (get_node (i));
 
953
  Container *result = new Container;
 
954
  result->AddSon (ds);
 
955
  result->AddSon (get_node (nodes () - 1));
 
956
  return result;
 
957
}
 
958
 
 
959
CTree *CBuilder::designator () { 
 
960
  // 2: .  identifier
 
961
  // 3: [  const_expr  ]
 
962
  if (nodes () == 2)
 
963
    return new CT_MembDesignator (get_node (0), get_node (1));
 
964
  else
 
965
    return new CT_IndexDesignator (get_node (0), get_node (1), get_node (2));
 
966
}
 
967
 
 
968
/*****************************************************************************/
 
969
/*                                                                           */
 
970
/*                          A . 8   C l a s s e s                            */
 
971
/*                                                                           */
 
972
/*****************************************************************************/
 
973
 
 
974
CTree *CBuilder::class_spec (CTree *result) {
 
975
  Container *head = (Container*)get_node (0);
 
976
  if (! result) {
 
977
    if (head->Son (0)->token ()->type () == TOK_UNION)
 
978
      result = new CT_UnionDef (head->Son (0), head->Son (1));
 
979
    else 
 
980
      result = new CT_ClassDef (head->Son (0), head->Son (1));
 
981
  } else {
 
982
    CT_MembList *ml = nodes () == 4 ? 
 
983
      (CT_MembList*)get_node (2) : new CT_MembList;
 
984
//    if (nodes () != 4)
 
985
//      Push (ml);
 
986
    ml->PrefixSon (get_node (1));
968
987
    ml->AddSon (get_node (nodes () - 1));
969
 
    ml->AddProperties (CT_List::OPEN_CLOSE);
970
 
    ((CT_ClassDef*)result)->Members (ml);
971
 
    delete head;
972
 
  }
973
 
  return result;
974
 
}
975
 
 
976
 
CTree *CBuilder::class_spec_err (CTree *result) {
977
 
  delete result;
978
 
  return (CTree*)0;
979
 
}
980
 
 
981
 
CTree *CBuilder::class_head () { 
982
 
  return container (); 
983
 
}
984
 
 
985
 
CTree *CBuilder::class_key () { 
986
 
  return get_node (); 
987
 
}
988
 
 
989
 
CTree *CBuilder::member_spec () { 
990
 
  return list (new CT_MembList); 
991
 
}
992
 
 
993
 
CTree *CBuilder::member_decl () { 
994
 
  // 3: type_spec_seq  member_declarator_list  ;
995
 
  return new CT_ObjDecl (get_node (0), get_node (1), get_node (2));
996
 
}
997
 
 
998
 
CTree *CBuilder::member_declarator_list () { 
999
 
  return list (new CT_DeclaratorList); 
1000
 
}
1001
 
 
1002
 
CTree *CBuilder::member_declarator () { 
1003
 
  // 1: declarator
1004
 
  // 3: declarator  :  const_expr
1005
 
  // 3: private_name  :  const_expr 
1006
 
  if (nodes () == 1)
1007
 
    return new CT_InitDeclarator (get_node (0));
1008
 
  else 
1009
 
    return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2));
1010
 
}
1011
 
 
1012
 
/*****************************************************************************/
1013
 
/*                                                                           */
1014
 
/*                   A . 9   D e r i v e d  c l a s s e s                    */
1015
 
/*                                                                           */
1016
 
/*****************************************************************************/
1017
 
 
1018
 
/*****************************************************************************/
1019
 
/*                                                                           */
1020
 
/*        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            */
1021
 
/*                                                                           */
1022
 
/*****************************************************************************/
1023
 
 
1024
 
/*****************************************************************************/
1025
 
/*                                                                           */
1026
 
/*                     A . 1 1   O v e r l o a d i n g                       */
1027
 
/*                                                                           */
1028
 
/*****************************************************************************/
1029
 
 
1030
 
/*****************************************************************************/
1031
 
/*                                                                           */
1032
 
/*                       A . 1 2   T e m p l a t e s                         */
1033
 
/*                                                                           */
1034
 
/*****************************************************************************/
1035
 
 
1036
 
/*****************************************************************************/
1037
 
/*                                                                           */
1038
 
/*                A . 1 3   E x c e p t i o n  h a n d l i n g               */
1039
 
/*                                                                           */
1040
 
/*****************************************************************************/
 
988
    ml->AddProperties (CT_List::OPEN_CLOSE);
 
989
    ((CT_ClassDef*)result)->Members (ml);
 
990
    delete head;
 
991
  }
 
992
  return result;
 
993
}
 
994
 
 
995
CTree *CBuilder::class_spec_err (CTree *result) {
 
996
  delete result;
 
997
  return (CTree*)0;
 
998
}
 
999
 
 
1000
CTree *CBuilder::class_head () { 
 
1001
  return container (); 
 
1002
}
 
1003
 
 
1004
CTree *CBuilder::class_key () { 
 
1005
  return get_node (); 
 
1006
}
 
1007
 
 
1008
CTree *CBuilder::member_spec () { 
 
1009
  return list (new CT_MembList); 
 
1010
}
 
1011
 
 
1012
CTree *CBuilder::member_decl () { 
 
1013
  // 2: type_spec_seq                          ;
 
1014
  // 3: type_spec_seq  member_declarator_list  ;
 
1015
  if (nodes () == 2)
 
1016
    return new CT_ObjDecl (get_node (0), new CT_DeclaratorList, get_node (1));
 
1017
  return new CT_ObjDecl (get_node (0), get_node (1), get_node (2));
 
1018
}
 
1019
 
 
1020
CTree *CBuilder::member_declarator_list () { 
 
1021
  return list (new CT_DeclaratorList); 
 
1022
}
 
1023
 
 
1024
CTree *CBuilder::member_declarator () { 
 
1025
  // 1: declarator
 
1026
  // 3: declarator  :  const_expr
 
1027
  // 3: private_name  :  const_expr 
 
1028
  if (nodes () == 1)
 
1029
    return new CT_InitDeclarator (get_node (0));
 
1030
  else 
 
1031
    return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2));
 
1032
}
 
1033
 
 
1034
/*****************************************************************************/
 
1035
/*                                                                           */
 
1036
/*                   A . 9   D e r i v e d  c l a s s e s                    */
 
1037
/*                                                                           */
 
1038
/*****************************************************************************/
 
1039
 
 
1040
/*****************************************************************************/
 
1041
/*                                                                           */
 
1042
/*        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            */
 
1043
/*                                                                           */
 
1044
/*****************************************************************************/
 
1045
 
 
1046
/*****************************************************************************/
 
1047
/*                                                                           */
 
1048
/*                     A . 1 1   O v e r l o a d i n g                       */
 
1049
/*                                                                           */
 
1050
/*****************************************************************************/
 
1051
 
 
1052
/*****************************************************************************/
 
1053
/*                                                                           */
 
1054
/*                       A . 1 2   T e m p l a t e s                         */
 
1055
/*                                                                           */
 
1056
/*****************************************************************************/
 
1057
 
 
1058
/*****************************************************************************/
 
1059
/*                                                                           */
 
1060
/*                A . 1 3   E x c e p t i o n  h a n d l i n g               */
 
1061
/*                                                                           */
 
1062
/*****************************************************************************/
1041
1063
 
1042
1064
 
1043
1065
} // namespace Puma