1
// This file is part of PUMA.
2
// Copyright (C) 1999-2003 The PUMA developer team.
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.
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.
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,
19
#include "Puma/CCBuilder.h"
20
#include "Puma/CCSyntax.h"
21
#include "Puma/CTokens.h"
26
/*****************************************************************************/
28
/* A . 1 K e y w o r d s */
30
/*****************************************************************************/
32
CTree *CCBuilder::namespace_name () {
33
// 1: original_ns_name
38
/*****************************************************************************/
40
/* A . 4 E x p r e s s i o n s */
42
/*****************************************************************************/
44
CTree *CCBuilder::prim_expr () {
48
// 3: ( expr ) => token node token
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 ();
57
CTree *CCBuilder::id_expr () {
61
CTree *CCBuilder::unqual_id () {
68
return new CT_DestructorName (get_node (0), get_node (1));
73
CTree *CCBuilder::qual_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
82
int root = 0, num = nodes ();
83
if (get_node (0)->NodeName () != Container::NodeId ()) {
86
result = new CT_RootQualName (2);
87
result->AddSon (get_node (0));
88
result->AddSon (get_node (1));
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));
99
result = new CT_RootQualName (nns->Sons ()+2);
100
result->AddSon (get_node (0));
102
result = new CT_QualName (nns->Sons ()+1);
103
copy_list (result, nns);
109
CTree *CCBuilder::nested_name_spec () {
110
Container *c, *nns = (Container*)get_node ();
114
for (int i = 1; i < nodes (); i++) {
115
c = (Container*)get_node (i);
117
sn = (CT_SimpleName*)c->Son (sons-2);
119
sn->PrefixSon (c->Son (0));
121
nns->AddSon (c->Son (sons-1));
127
CTree *CCBuilder::nested_name_spec1 () {
131
CTree *CCBuilder::class_or_ns_name () {
137
CTree *CCBuilder::postfix_expr (CTree *postfix) {
139
// 1+: postfix_expr2 postfix_expr1..
140
CTree *result = postfix;
142
result = get_node (0);
144
Container *c = (Container*)get_node (nodes ()-1);
149
// 2: . pseudo_dtor_name
150
// 2: -> pseudo_dtor_name
152
// 3: . template_key id_expr
153
// 3: -> template_key id_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'
165
sn->PrefixSon (c->Son (1));
166
if (token == TOK_DOT)
167
result = new CT_MembRefExpr (result, c->Son (0), sn);
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);
183
CTree *CCBuilder::postfix_expr2 () {
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 )
207
CTree *result = get_node (0);
208
int num = nodes (), offset = 0;
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));
217
el = new CT_ExprList;
218
el->PrefixSon (get_node (num-2));
220
el->AddSon (get_node (num-1));
221
el->AddProperties (CT_List::OPEN_CLOSE);
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));
228
int root = (get_node (1)->NodeName () == Container::NodeId ()) ? 0 : 1;
229
Container *nns = (Container*)get_node (root+1);
231
qn = new CT_RootQualName (nns->Sons ()+2);
232
qn->AddSon (get_node (1));
234
qn = new CT_QualName (nns->Sons ()+1);
237
return new CT_ConstructExpr (new CT_ClassSpec (get_node (0), qn), el);
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));
245
// construct expressions and "new style" casts
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);
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);
278
CTree *CCBuilder::pseudo_dtor_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
290
CTree *dtor = new CT_DestructorName (get_node (num-2), get_node (num-1));
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);
299
result = new CT_RootQualName (nns->Sons () + (num > 4 ? 4 : 2));
300
result->AddSon (get_node (0));
302
result = new CT_QualName (nns->Sons () + (num > 4 ? 3 : 1));
303
copy_list (result, nns);
307
result = new CT_RootQualName (num > 3 ? 4 : 2);
308
result->AddSon (get_node (0));
310
result = new CT_QualName (3);
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));
318
result->AddSon (get_node (num-3));
320
result->AddSon (dtor);
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));
344
CT_RootQualName *rqn = new CT_RootQualName (2);
345
rqn->AddSon (get_node (0));
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;
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);
360
CTree *CCBuilder::new_placement () {
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);
369
CTree *CCBuilder::direct_new_declarator () {
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));
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));
386
CTree *CCBuilder::direct_new_declarator1 () {
391
CTree *CCBuilder::new_init () {
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);
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;
410
result = new CT_OperatorName (0, get_node (root), get_node (root+1),
413
result = new CT_OperatorName (get_node (root));
415
CT_RootQualName *rqn = new CT_RootQualName;
416
rqn->AddSon (get_node ());
417
rqn->AddSon (result);
420
return new CT_DeleteExpr (result, get_node (num-1));
423
CTree *CCBuilder::pm_expr () {
424
return lr_bin_expr ();
427
/*****************************************************************************/
429
/* A . 5 S t a t e m e n t s */
431
/*****************************************************************************/
433
CTree *CCBuilder::condition (CTree *cond) {
435
// 2: type_spec_seq declarator
440
return new CT_Condition (get_node (0), get_node (1));
441
// 4: type_spec_seq declarator = ass_expr
447
CT_ExprList *el = new CT_ExprList;
449
el->AddSon (get_node (2));
450
el->AddSon (get_node (3));
451
el->AddProperties (CT_List::INTRO);
452
((CT_Condition*)cond)->Initializer (el);
457
CTree *CCBuilder::decl_stmt () {
459
return new CT_DeclStmt (get_node ());
462
/*****************************************************************************/
464
/* A . 6 D e c l a r a t i o n s */
466
/*****************************************************************************/
468
CTree *CCBuilder::decl () {
471
// 1: explicit_specialization
473
// 1: explicit_instantiation
476
// 3: EXTERN str_literal decl
480
return new CT_LinkageSpec (get_node (0), get_node (1), 0, get_node (2), 0);
483
CTree *CCBuilder::simple_type_spec () {
486
// 2: nested_name_spec 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
493
if (get_node ()->NodeName () == CT_Token::NodeId ())
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));
504
int root = (get_node ()->NodeName () == Container::NodeId ()) ? 0 : 1;
506
if (num == 2 && root) {
507
result = new CT_RootQualName (2);
508
result->AddSon (get_node (0));
510
Container *nns = (Container*)get_node (root);
512
result = new CT_RootQualName (nns->Sons ()+2);
513
result->AddSon (get_node (0));
515
result = new CT_QualName (nns->Sons ()+1);
516
copy_list (result, nns);
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
540
CT_SimpleName *name = (CT_SimpleName*)get_node (num-1);
542
// name prefixed by `template'
543
if (get_node (num-2)->token ()->type () == TOK_TEMPLATE)
544
name->PrefixSon (get_node (num-2));
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));
551
Container *nns = (Container*)get_node (root+1);
553
qn = new CT_RootQualName (nns->Sons ()+2);
554
qn->AddSon (get_node (1));
556
qn = new CT_QualName (nns->Sons ()+1);
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);
568
return new CT_EnumSpec (get_node (0), name);
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));
577
CTree *CCBuilder::linkage_spec () {
578
// 3: EXTERN str_literal decl
579
// 4: EXTERN str_literal { }
580
// 5: EXTERN str_literal { decl_seq }
582
return new CT_LinkageSpec (get_node (0), get_node (1),
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);
592
return new CT_LinkageSpec (get_node (0), get_node (1),
593
get_node (2), dl, get_node (4));
597
/*****************************************************************************/
599
/* A . 6 . 1 N a m e s p a c e s */
601
/*****************************************************************************/
603
CTree *CCBuilder::namespace_def () {
609
CTree *CCBuilder::named_ns_def () {
610
// 1: original_ns_def
611
// 1: extension_ns_def
615
CTree *CCBuilder::orig_namespace_def (CTree *nsd) {
616
// 5: NAMESPACE identifier { namespace_body }
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);
626
return new CT_NamespaceDef (get_node (0), get_node (1));
629
CTree *CCBuilder::namespace_body () {
634
Container *decls = (Container*)get_node ();
635
ml = new CT_MembList (decls->Sons ());
636
copy_list (ml, decls);
639
ml = new CT_MembList (1);
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));
649
CTree *CCBuilder::qual_ns_spec () {
651
// 2: nested_name_spec namespace_name
652
// 2: colon_colon namespace_name
653
// 3: colon_colon nested_name_spec namespace_name
660
if (get_node (0)->NodeName () != Container::NodeId ()) {
663
result = new CT_RootQualName (2);
664
result->AddSon (get_node (0));
665
result->AddSon (get_node (1));
670
Container *nns = (Container*)get_node (root);
672
result = new CT_RootQualName (nns->Sons ()+2);
673
result->AddSon (get_node (0));
675
result = new CT_QualName (nns->Sons ()+1);
676
copy_list (result, nns);
677
result->AddSon (get_node (1+root));
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 ;
689
int root = 0, num = nodes ();
690
if (get_node (1)->token ()->type () == TOK_TYPENAME)
692
if (get_node (root+1)->NodeName () != Container::NodeId ())
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));
699
Container *nns = (Container*)get_node (num-3);
701
qn = new CT_RootQualName (nns->Sons ()+2);
702
qn->AddSon (get_node (num-4));
704
qn = new CT_QualName (nns->Sons ()+1);
706
qn->AddSon (get_node (num-2));
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));
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 ;
719
int root = 0, num = nodes ();
720
if (get_node (2)->NodeName () != Container::NodeId ())
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));
729
Container *nns = (Container*)get_node (num-3);
731
n = new CT_RootQualName (nns->Sons ()+2);
732
((CT_QualName*)n)->AddSon (get_node (2));
734
n = new CT_QualName (nns->Sons ()+1);
735
copy_list ((CT_QualName*)n, nns);
736
((CT_QualName*)n)->AddSon (get_node (num-2));
738
return new CT_UsingDirective (get_node (0), get_node (1), n, get_node (num-1));
741
/*****************************************************************************/
743
/* A . 7 D e c l a r a t o r s */
745
/*****************************************************************************/
747
CTree *CCBuilder::declarator () {
748
// 1 : direct_declarator
749
// 2+: ptr_operator.. direct_declarator
751
CTree *result = get_node (num-1);
752
for (int i = num-1; i > 0; i--) {
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 ();
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);
769
int root = (type == TOK_COLON_COLON) ? 1 : 0;
770
Container *nns = (Container*)p->Son (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);
778
if (nns->Sons () == 2)
779
qn = (CT_QualName*)nns->Son (0);
781
for (int i = 0; i < nns->Sons ()-1; i++)
782
qn->AddSon (nns->Son (i));
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);
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
806
int root = (get_node (0)->NodeName () == CT_Token::NodeId ()) ? 1 : 0;
807
if ((num-root) == 2) {
808
Container *nns = (Container*)get_node (root);
810
result = new CT_RootQualName (nns->Sons ()+2);
811
result->AddSon (get_node (0));
813
result = new CT_QualName (nns->Sons ()+1);
814
copy_list (result, nns);
817
result = new CT_RootQualName (2);
818
result->AddSon (get_node (0));
820
result->AddSon (get_node (num-1));
824
CTree *CCBuilder::param_init () {
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);
833
/*****************************************************************************/
835
/* A . 8 C l a s s e s */
837
/*****************************************************************************/
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
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);
858
qn->AddSon (get_node (2));
861
if (get_node (0)->token ()->type () == TOK_UNION)
862
result = new CT_UnionDef (get_node (0), result, 0);
864
result = new CT_ClassDef (get_node (0), result, 0);
865
// base_clause parsed successfully
868
if (get_node (num-1)->NodeName () == CT_BaseSpecList::NodeId ())
869
((CT_ClassDef*)result)->BaseClasses (get_node (num-1));
874
CTree *CCBuilder::class_spec () {
876
// 4: class_head { member_spec }
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);
888
CTree *CCBuilder::member_decl () {
896
return new CT_AccessSpec (get_node (0), get_node (1));
899
CTree *CCBuilder::member_decl1 () {
901
// 2: decl_spec_seq ;
902
// 2: member_declarator_list ;
903
// 3: decl_spec_seq member_declarator_list ;
906
return new CT_ObjDecl (new CT_DeclSpecSeq, new CT_DeclaratorList, get_node (0));
908
if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
909
return new CT_ObjDecl (get_node (0), new CT_DeclaratorList, get_node (1));
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));
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 ;
922
int root = (get_node ()->NodeName () != Container::NodeId ()) ? 1 : 0;
923
Container *nns = (Container*)get_node (root);
926
qn = new CT_RootQualName (nns->Sons ()+2);
927
qn->AddSon (get_node (0));
929
qn = new CT_QualName (nns->Sons ()+1);
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));
937
return new CT_AccessDecl (qn, get_node (num-1));
940
CTree *CCBuilder::member_declarator () {
942
// 2: declarator pure_spec
943
// 2: declarator const_init
944
// 3: identifier : const_expr
945
// 3: private_name : const_expr
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));
952
return new CT_InitDeclarator (get_node (0), (num == 2) ? get_node (1) : 0);
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);
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);
971
/*****************************************************************************/
973
/* A . 9 D e r i v e d c l a s s e s */
975
/*****************************************************************************/
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));
984
CTree *CCBuilder::base_spec_list () {
985
return list (new CT_BaseSpecList);
988
CTree *CCBuilder::base_spec () {
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);
1013
if ((i = 0, get_node (i)->token ()->type () == TOK_VIRTUAL) ||
1014
(i = 1, get_node (i)->token ()->type () == TOK_VIRTUAL))
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))
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));
1031
qn = new CT_QualName (nns->Sons ()+1);
1032
copy_list (qn, nns);
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));
1043
return new CT_BaseSpec (v, a, n);
1046
CTree *CCBuilder::access_spec () {
1050
/*****************************************************************************/
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 */
1054
/*****************************************************************************/
1056
CTree *CCBuilder::conv_fct_id () {
1057
// 2: OPERATOR conv_type_id
1058
return new CT_ConversionName (get_node (0), get_node (1));
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));
1068
CTree *CCBuilder::mem_init_list () {
1069
return list (new CT_MembInitList);
1072
CTree *CCBuilder::mem_init () {
1073
// 3: mem_init_id ( )
1074
// 4: mem_init_id ( expr_list )
1076
CT_ExprList *el = (num == 4) ? (CT_ExprList*)get_node (2) : new CT_ExprList;
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);
1085
CTree *CCBuilder::mem_init_id () {
1088
// 2: nested_name_spec class_name
1090
// 3: :: nested_name_spec class_name
1094
CT_QualName *result;
1095
if (get_node (num-2)->NodeName () == Container::NodeId ()) {
1096
Container *nns = (Container*)get_node (num-2);
1098
result = new CT_RootQualName (nns->Sons ()+2);
1099
result->AddSon (get_node (0));
1101
result = new CT_QualName (nns->Sons ()+1);
1102
copy_list (result, nns);
1105
result = new CT_RootQualName (2);
1106
result->AddSon (get_node (0));
1108
result->AddSon (get_node (num-1));
1112
/*****************************************************************************/
1114
/* A . 1 1 O v e r l o a d i n g */
1116
/*****************************************************************************/
1118
CTree *CCBuilder::oper_fct_id () {
1119
// 2: OPERATOR any_operator
1121
// 2: OPERATOR DELETE
1124
// 4: OPERATOR NEW [ ]
1125
// 4: OPERATOR DELETE [ ]
1128
return new CT_OperatorName (get_node (0), get_node (1), 0, 0);
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),
1136
/*****************************************************************************/
1138
/* A . 1 2 T e m p l a t e s */
1140
/*****************************************************************************/
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));
1154
CTree *CCBuilder::template_param_list () {
1155
// 1 : template_param
1156
// 3+: template_param , template_param ..
1157
return list (new CT_TemplateParamList);
1160
CTree *CCBuilder::template_param () {
1162
// 1: non_type_param
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));
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);
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
1198
result = new CT_NonTypeParamDecl (get_node (0), get_node (1));
1199
else if (nodes () == 3)
1200
((CT_NonTypeParamDecl*)result)->Initializer (get_node (2));
1204
CTree *CCBuilder::template_id () {
1205
// 3: template_name < >
1206
// 4: template_name < template_arg_list >
1207
CT_TemplateArgList *tal;
1209
tal = new CT_TemplateArgList;
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);
1217
CTree *CCBuilder::template_arg_list () {
1219
// 3+: template_arg , template_arg ..
1220
return list (new CT_TemplateArgList);
1223
CTree *CCBuilder::template_arg () {
1230
CTree *CCBuilder::explicit_instantiation () {
1232
// 3: EXTERN TEMPLATE decl => GCC EXTENSION!!!
1233
CT_TemplateParamList *tpl = new CT_TemplateParamList;
1234
tpl->AddSon (get_node (nodes ()-2));
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));
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));
1250
/*****************************************************************************/
1252
/* A . 1 3 E x c e p t i o n h a n d l i n g */
1254
/*****************************************************************************/
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));
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 ();
1267
CTree *CCBuilder::handler_seq () {
1269
return list (new CT_HandlerSeq);
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));
1281
CTree *CCBuilder::exception_decl () {
1284
// 2: type_spec_seq abst_declarator
1285
// 2: type_spec_seq declarator
1287
return new CT_ArgDecl (get_node (0), get_node (1));
1288
return new CT_ArgDecl (get_node (0));
1291
CTree *CCBuilder::throw_expr () {
1293
// 2: THROW ass_expr
1295
return new CT_ThrowExpr (get_node (0));
1296
return new CT_ThrowExpr (get_node (0), get_node (1));
1299
CTree *CCBuilder::exception_spec () {
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;
1307
adl->AddSon (get_node (2));
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);
1315
CTree *CCBuilder::type_id_list () {
1317
// 3+: type_id , type_id ..
1318
return list (new CT_ArgDeclList (3));