16
16
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17
17
// MA 02111-1307 USA
19
#include "Puma/CBuilder.h"
20
#include "Puma/CSyntax.h"
21
#include "Puma/CTokens.h"
19
#include "Puma/CBuilder.h"
20
#include "Puma/CSyntax.h"
21
#include "Puma/CTokens.h"
26
/*****************************************************************************/
28
/* A . 1 K e y w o r d s */
30
/*****************************************************************************/
32
CTree *CBuilder::simple_name () {
33
return new CT_SimpleName (get_node ());
36
/*****************************************************************************/
38
/* A . 2 L e x i c a l c o n v e n t i o n s */
40
/*****************************************************************************/
42
CTree *CBuilder::literal () {
43
if (get_node (0)->NodeName () == CT_String::NodeId () ||
44
get_node (0)->NodeName () == CT_WideString::NodeId ())
48
const char *txt = get_node (0)->token ()->text ();
49
switch (get_node (0)->token ()->type ()) {
52
result = new CT_Integer ((CT_Token*)get_node (0)); break;
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));
59
result = new CT_Float ((CT_Token*)get_node (0)); break;
61
result = new CT_Bool ((CT_Token*)get_node (0)); break;
68
CTree *CBuilder::cmpd_str () {
70
for (int i = 0; (i < nodes ()) && ! wide; i++)
71
if (*(get_node (i)->token ()->text ().c_str()) == 'L')
74
return (wide) ? list (new CT_WideString (nodes ())) :
75
list (new CT_String (nodes ()));
78
CTree *CBuilder::str_literal () {
82
/*****************************************************************************/
84
/* A . 3 B a s i c c o n c e p t s */
86
/*****************************************************************************/
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);
96
/*****************************************************************************/
98
/* A . 4 E x p r e s s i o n s */
100
/*****************************************************************************/
102
CTree *CBuilder::prim_expr () {
103
// 1: literal => node
104
// 1: id_expr => node
105
// 3: ( expr ) => token node token
107
return new CT_BracedExpr (get_node (0), get_node (1), get_node (2));
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);
123
CTree *CBuilder::postfix_expr () {
126
// 1+: prim_expr postfix_expr1...
127
// 1+: cmpd_literal postfix_expr1...
128
CTree *result = get_node (0);
130
for (int n = 1; n < num; n++) {
131
Container *c = (Container*)get_node (n);
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;
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);
163
CTree *CBuilder::postfix_expr1 () {
167
CTree *CBuilder::expr_list () {
168
return list (new CT_ExprList);
171
CTree *CBuilder::unary_expr () {
175
// 2: any_unary_op cast_expr
176
// 2: sizeof unary_expr
177
// 2: sizeof unary_expr1
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));
193
return new CT_SizeofExpr (get_node (0), get_node (1));
195
return new CT_UnaryExpr (get_node (0), get_node (1));
198
CTree *CBuilder::unary_expr1 () {
203
CTree *CBuilder::cast_expr () {
205
// 2+: cast_expr1... unary_expr
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);
216
CTree *CBuilder::cast_expr1 () {
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));
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 (); }
241
CTree *CBuilder::cond_expr () {
242
CTree *result = get_node (0);
244
result = new CT_IfThenExpr (result, get_node (1), get_node (2),
245
get_node (3), get_node (4));
249
CTree *CBuilder::ass_expr () {
251
// 2+: ass_expr1... cond_expr
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);
262
CTree *CBuilder::ass_expr1 () {
266
CTree *CBuilder::const_expr () {
270
/*****************************************************************************/
272
/* A . 5 S t a t e m e n t s */
274
/*****************************************************************************/
276
CTree *CBuilder::stmt () {
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
285
if (get_node (0)->NodeName () == CT_SimpleName::NodeId ()) {
286
return new CT_LabelStmt (get_node (0), get_node (1), get_node (2));
288
return new CT_DefaultStmt (get_node (0), get_node (1), get_node (2));
290
return new CT_CaseStmt (get_node (0), get_node (1), get_node (2),
294
CTree *CBuilder::expr_stmt () {
298
return new CT_ExprStmt ((CTree*)0, get_node (0));
300
return new CT_ExprStmt (get_node (0), get_node (1));
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));
309
Container *container = (Container*)get_node (1);
310
for (int i = 0; i < container->Sons (); i++)
311
result->AddSon (container->Son (i));
313
result->AddSon (get_node (2));
315
result->AddSon (get_node (1));
319
CTree *CBuilder::stmt_seq () {
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));
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));
338
CTree *CBuilder::sub_stmt () {
342
CTree *CBuilder::condition (CTree *) {
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
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),
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));
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));
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));
381
CTree *CBuilder::for_init_stmt () {
387
CTree *CBuilder::jump_stmt () {
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));
402
return new CT_ReturnStmt (token, (CTree*)0, get_node (1));
404
return new CT_ReturnStmt (token, get_node (1), get_node (2));
409
/*****************************************************************************/
411
/* A . 6 D e c l a r a t i o n s */
413
/*****************************************************************************/
415
CTree *CBuilder::decl_seq () {
419
CTree *CBuilder::decl () {
423
CTree *CBuilder::block_decl () {
427
CTree *CBuilder::simple_decl () {
430
if (get_node ()->NodeName () == CT_DeclSpecSeq::NodeId ())
431
dss = (CT_DeclSpecSeq*)get_node (offset++);
433
dss = new CT_DeclSpecSeq;
436
CT_DeclaratorList *dl;
437
if (offset + 1 < nodes ())
438
dl = (CT_DeclaratorList*)get_node (offset++);
440
dl = new CT_DeclaratorList;
443
return new CT_ObjDecl (dss, dl, get_node (offset));
446
CTree *CBuilder::decl_spec () {
450
CTree *CBuilder::decl_spec_seq () {
451
return list (new CT_DeclSpecSeq);
454
CTree *CBuilder::decl_spec_seq1 () {
458
// helper function for primitive declaration specifiers
459
CTree *CBuilder::prim_ds () {
460
return new CT_PrimDeclSpec ((CT_Token*)get_node ());
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 (); }
467
CTree *CBuilder::type_spec () {
471
CTree *CBuilder::simple_type_spec () {
472
return (get_node ()->NodeName () == CT_Token::NodeId ()) ?
473
prim_ds () : get_node ();
476
CTree *CBuilder::type_name () {
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));
489
return new CT_EnumSpec (get_node (0), get_node (1));
492
CTree *CBuilder::enum_spec (CTree *result) {
493
// 5: ENUM identifier { enumerator_list }
494
// 5: ENUM private_name { enumerator_list }
496
result = new CT_EnumDef (get_node (0), get_node (1));
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);
508
CTree *CBuilder::enum_spec_err (CTree *es) {
513
CTree *CBuilder::enumerator_list () {
514
return list (new CT_EnumeratorList);
517
CTree *CBuilder::enumerator_def () {
519
// 3: enumerator = const_expr
520
CT_Enumerator *e = (CT_Enumerator*)get_node (0);
522
CT_ExprList *el = new CT_ExprList;
524
el->AddSon (get_node (1));
525
el->AddSon (get_node (2));
526
el->AddProperties (CT_List::INTRO);
532
CTree *CBuilder::enumerator () {
533
return new CT_Enumerator (get_node ());
536
/*****************************************************************************/
538
/* A . 7 D e c l a r a t o r s */
540
/*****************************************************************************/
542
CTree *CBuilder::init_declarator_list () {
543
return list (new CT_DeclaratorList);
546
CTree *CBuilder::init_declarator (CTree* id) {
548
return new CT_InitDeclarator (get_node (0));
550
((CT_InitDeclarator*)id)->Initializer (get_node (1));
554
CTree *CBuilder::declarator () {
555
// 1 : direct_declarator
556
// 2+: ptr_operator.. direct_declarator
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
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);
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...
579
int braced = (get_node (0)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0;
581
result = get_node (0);
583
// win specific declaration specifier
584
if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
586
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
588
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
589
// braced declarator only
590
if (nodes () == braced+1)
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),
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);
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));
611
result = new CT_FctDeclarator (result, args, 0, 0);
618
CTree *CBuilder::direct_declarator1 () {
619
// 3: [ array_delim ]
620
// 3: ( param_decl_clause )
621
// 3: ( identifier_list )
625
CTree *CBuilder::identifier_list () {
626
return list (new CT_ArgNameList);
629
CTree *CBuilder::array_delim () {
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
640
CTree *star, *stat, *quals, *expr = star = stat = quals = (CTree*)0;
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)
649
} else if (nodes () == 2) {
650
if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
654
quals = get_node (0);
655
if (get_node (1)->NodeName () == CT_Token::NodeId () &&
656
get_node (1)->token ()->type () == TOK_MUL)
661
} else if (nodes () == 3) {
662
if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
26
/*****************************************************************************/
28
/* A . 1 K e y w o r d s */
30
/*****************************************************************************/
32
CTree *CBuilder::simple_name () {
33
return new CT_SimpleName (get_node ());
36
/*****************************************************************************/
38
/* A . 2 L e x i c a l c o n v e n t i o n s */
40
/*****************************************************************************/
42
CTree *CBuilder::literal () {
43
if (get_node (0)->NodeName () == CT_String::NodeId () ||
44
get_node (0)->NodeName () == CT_WideString::NodeId ())
48
const char *txt = get_node (0)->token ()->text ();
49
switch (get_node (0)->token ()->type ()) {
52
result = new CT_Integer ((CT_Token*)get_node (0)); break;
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));
59
result = new CT_Float ((CT_Token*)get_node (0)); break;
61
result = new CT_Bool ((CT_Token*)get_node (0)); break;
68
CTree *CBuilder::cmpd_str () {
70
for (int i = 0; (i < nodes ()) && ! wide; i++)
71
if (*(get_node (i)->token ()->text ()) == 'L')
74
return (wide) ? list (new CT_WideString (nodes ())) :
75
list (new CT_String (nodes ()));
78
CTree *CBuilder::str_literal () {
82
/*****************************************************************************/
84
/* A . 3 B a s i c c o n c e p t s */
86
/*****************************************************************************/
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);
96
/*****************************************************************************/
98
/* A . 4 E x p r e s s i o n s */
100
/*****************************************************************************/
102
CTree *CBuilder::prim_expr () {
103
// 1: literal => node
104
// 1: id_expr => node
105
// 3: ( expr ) => token node token
107
return new CT_BracedExpr (get_node (0), get_node (1), get_node (2));
112
CTree *CBuilder::cmpd_literal () {
113
// 5 : ( type_id ) { init_list }
114
// 6 : ( type_id ) { init_list }
118
el = new CT_ExprList ();
120
el = (CT_ExprList*)get_node (4);
121
if ((el->Sons () % 2) == 0)
122
el->AddProperties (CT_List::END_SEP);
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);
130
CTree *CBuilder::postfix_expr () {
133
// 1+: prim_expr postfix_expr1...
134
// 1+: cmpd_literal postfix_expr1...
135
CTree *result = get_node (0);
137
for (int n = 1; n < num; n++) {
138
Container *c = (Container*)get_node (n);
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;
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);
170
CTree *CBuilder::postfix_expr1 () {
174
CTree *CBuilder::expr_list () {
175
return list (new CT_ExprList);
178
CTree *CBuilder::unary_expr () {
182
// 2: any_unary_op cast_expr
183
// 2: sizeof unary_expr
184
// 2: sizeof unary_expr1
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));
200
return new CT_SizeofExpr (get_node (0), get_node (1));
202
return new CT_UnaryExpr (get_node (0), get_node (1));
205
CTree *CBuilder::unary_expr1 () {
210
CTree *CBuilder::cast_expr () {
216
CTree *CBuilder::cast_expr1 () {
217
// 2+: cast_expr2... unary_expr
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);
228
CTree *CBuilder::cast_expr2 () {
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));
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 (); }
253
CTree *CBuilder::cond_expr () {
254
CTree *result = get_node (0);
256
result = new CT_IfThenExpr (result, get_node (1), get_node (2),
257
get_node (3), get_node (4));
261
CTree *CBuilder::ass_expr () {
263
// 2+: ass_expr1... cond_expr
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);
274
CTree *CBuilder::ass_expr1 () {
278
CTree *CBuilder::const_expr () {
282
/*****************************************************************************/
284
/* A . 5 S t a t e m e n t s */
286
/*****************************************************************************/
288
CTree *CBuilder::stmt () {
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
297
if (get_node (0)->NodeName () == CT_SimpleName::NodeId ()) {
298
return new CT_LabelStmt (get_node (0), get_node (1), get_node (2));
300
return new CT_DefaultStmt (get_node (0), get_node (1), get_node (2));
302
return new CT_CaseStmt (get_node (0), get_node (1), get_node (2),
306
CTree *CBuilder::expr_stmt () {
310
return new CT_ExprStmt ((CTree*)0, get_node (0));
312
return new CT_ExprStmt (get_node (0), get_node (1));
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));
321
Container *container = (Container*)get_node (1);
322
for (int i = 0; i < container->Sons (); i++)
323
result->AddSon (container->Son (i));
325
result->AddSon (get_node (2));
327
result->AddSon (get_node (1));
331
CTree *CBuilder::stmt_seq () {
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));
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));
350
CTree *CBuilder::sub_stmt () {
354
CTree *CBuilder::condition (CTree *) {
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
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),
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));
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));
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));
393
CTree *CBuilder::for_init_stmt () {
399
CTree *CBuilder::jump_stmt () {
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));
414
return new CT_ReturnStmt (token, (CTree*)0, get_node (1));
416
return new CT_ReturnStmt (token, get_node (1), get_node (2));
421
/*****************************************************************************/
423
/* A . 6 D e c l a r a t i o n s */
425
/*****************************************************************************/
427
CTree *CBuilder::decl_seq () {
431
CTree *CBuilder::decl () {
435
CTree *CBuilder::block_decl () {
439
CTree *CBuilder::simple_decl () {
442
if (get_node ()->NodeName () == CT_DeclSpecSeq::NodeId ())
443
dss = (CT_DeclSpecSeq*)get_node (offset++);
445
dss = new CT_DeclSpecSeq;
448
CT_DeclaratorList *dl;
449
if (offset + 1 < nodes ())
450
dl = (CT_DeclaratorList*)get_node (offset++);
452
dl = new CT_DeclaratorList;
455
return new CT_ObjDecl (dss, dl, get_node (offset));
458
CTree *CBuilder::decl_spec () {
462
CTree *CBuilder::decl_spec_seq () {
463
return list (new CT_DeclSpecSeq);
466
CTree *CBuilder::decl_spec_seq1 () {
470
// helper function for primitive declaration specifiers
471
CTree *CBuilder::prim_ds () {
472
return new CT_PrimDeclSpec ((CT_Token*)get_node ());
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 (); }
479
CTree *CBuilder::type_spec () {
483
CTree *CBuilder::simple_type_spec () {
484
return (get_node ()->NodeName () == CT_Token::NodeId ()) ?
485
prim_ds () : get_node ();
488
CTree *CBuilder::type_name () {
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));
501
return new CT_EnumSpec (get_node (0), get_node (1));
504
CTree *CBuilder::enum_spec (CTree *result) {
505
// 5: ENUM identifier { enumerator_list }
506
// 5: ENUM private_name { enumerator_list }
508
result = new CT_EnumDef (get_node (0), get_node (1));
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);
520
CTree *CBuilder::enum_spec_err (CTree *es) {
525
CTree *CBuilder::enumerator_list () {
526
return list (new CT_EnumeratorList);
529
CTree *CBuilder::enumerator_def () {
531
// 3: enumerator = const_expr
532
CT_Enumerator *e = (CT_Enumerator*)get_node (0);
534
CT_ExprList *el = new CT_ExprList;
536
el->AddSon (get_node (1));
537
el->AddSon (get_node (2));
538
el->AddProperties (CT_List::INTRO);
544
CTree *CBuilder::enumerator () {
545
return new CT_Enumerator (get_node ());
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));
555
/*****************************************************************************/
557
/* A . 7 D e c l a r a t o r s */
559
/*****************************************************************************/
561
CTree *CBuilder::init_declarator_list () {
562
return list (new CT_DeclaratorList);
565
CTree *CBuilder::init_declarator (CTree* 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));
573
CTree *CBuilder::declarator () {
574
// 1 : direct_declarator
575
// 2+: ptr_operator.. direct_declarator
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
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);
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...
598
int braced = (get_node (0)->token ()->type () == TOK_OPEN_ROUND) ? 2 : 0;
600
result = get_node (0);
602
// win specific declaration specifier
603
if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
605
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
607
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
608
// braced declarator only
609
if (nodes () == braced+1)
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),
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);
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));
630
result = new CT_FctDeclarator (result, args, 0, 0);
637
CTree *CBuilder::direct_declarator1 () {
638
// 3: [ array_delim ]
639
// 3: ( param_decl_clause )
640
// 3: ( identifier_list )
644
CTree *CBuilder::identifier_list () {
645
return list (new CT_ArgNameList);
648
CTree *CBuilder::array_delim () {
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
659
CTree *star, *stat, *quals, *expr = star = stat = quals = (CTree*)0;
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)
668
} else if (nodes () == 2) {
669
if (get_node (0)->NodeName () == CT_Token::NodeId ()) {
673
quals = get_node (0);
674
if (get_node (1)->NodeName () == CT_Token::NodeId () &&
675
get_node (1)->token ()->type () == TOK_MUL)
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);
666
quals = get_node (0); pos0 = true;
683
quals = get_node (1);
685
quals = get_node (0); pos0 = true;
672
return new CT_ArrayDelimiter (star, quals, stat, expr, pos0);
673
return new CT_ArrayDelimiter (star, stat, quals, expr, pos0);
676
CTree *CBuilder::ptr_operator () {
680
CTree *CBuilder::cv_qual_seq () {
681
return list (new CT_DeclSpecSeq);
684
CTree *CBuilder::cv_qual () {
688
CTree *CBuilder::declarator_id () {
692
CTree *CBuilder::type_id () {
693
return new CT_NamedType (get_node (0), get_node (1));
696
CTree *CBuilder::abst_declarator () {
697
// 1 : direct_abst_declarator
698
// 1+: ptr_operator..
699
// 2+: ptr_operator.. direct_abst_declarator
700
return declarator ();
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...
709
int braced = (get_node (0)->NodeName () != Container::NodeId ()) ? 3 : 0;
711
result = get_node (nodes () - 1); // PrivateName, pushed by semantic
713
// win specific declaration specifier
714
if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
716
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
718
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
719
// braced declarator only
720
if (nodes () == braced)
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));
740
result = new CT_ArrayDeclarator (result, d1->Son (0),
741
new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2));
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);
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));
755
result = new CT_FctDeclarator (result, args, 0, 0);
762
CTree *CBuilder::direct_abst_declarator1 () {
766
// 3: ( param_decl_clause )
770
CTree *CBuilder::param_decl_clause () {
773
// 1: param_decl_list => cont
774
// 2: param_decl_list ... => cont token
776
return new CT_ArgDeclList ();
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)));
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);
790
if ((al->Sons () % 2) == 1)
791
result->AddProperties (CT_List::NO_LAST_SEP);
792
result->AddSon (new CT_ArgDecl (get_node (nodes ()-1))); // ...
799
CTree *CBuilder::param_decl_list () {
803
CTree *CBuilder::param_decl () {
805
// 3: param_decl1 param_init
806
CT_ArgDecl *ad = (CT_ArgDecl*)get_node (0);
808
ad->Initializer (get_node (1));
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));
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;
830
if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
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 ())) {
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);
849
Container *cont = (Container*)get_node (1+offset);
851
if (cont->Son (1)->NodeName () == CT_MembInitList::NodeId ())
854
b = cont->Son (1+offset);
855
hs = cont->Son (2+offset);
858
return new CT_FctDef (dss, d, t, ci, as, b, hs);
861
CTree *CBuilder::arg_decl_seq () {
862
return list (new CT_ArgDeclSeq (nodes ()));
865
CTree *CBuilder::fct_body () {
870
CTree *CBuilder::init () {
874
if (get_node (1)->NodeName () != CT_ExprList::NodeId ()) {
875
result = new CT_ExprList;
876
result->AddSon (get_node (1));
878
result = (CT_ExprList*)get_node (1);
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);
890
CTree *CBuilder::init_clause () {
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));
909
result->AddProperties (CT_List::OPEN_CLOSE);
913
CTree *CBuilder::init_list () {
914
return list (new CT_ExprList);
917
CTree *CBuilder::init_list_item () {
919
// 2: designation init_clause
922
Container *c = (Container*)get_node (0);
923
CTree *result = new CT_BinaryExpr (c->Son (0), c->Son (1), get_node (1));
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;
935
result->AddSon (get_node (nodes () - 1));
939
CTree *CBuilder::designator () {
943
return new CT_MembDesignator (get_node (0), get_node (1));
945
return new CT_IndexDesignator (get_node (0), get_node (1), get_node (2));
948
/*****************************************************************************/
950
/* A . 8 C l a s s e s */
952
/*****************************************************************************/
954
CTree *CBuilder::class_spec (CTree *result) {
955
Container *head = (Container*)get_node (0);
957
if (head->Son (0)->token ()->type () == TOK_UNION)
958
result = new CT_UnionDef (head->Son (0), head->Son (1));
960
result = new CT_ClassDef (head->Son (0), head->Son (1));
962
CT_MembList *ml = nodes () == 4 ?
963
(CT_MembList*)get_node (2) : new CT_MembList;
964
// if (nodes () != 4)
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);
696
CTree *CBuilder::ptr_operator () {
700
CTree *CBuilder::cv_qual_seq () {
701
return list (new CT_DeclSpecSeq);
704
CTree *CBuilder::cv_qual () {
708
CTree *CBuilder::declarator_id () {
712
CTree *CBuilder::type_id () {
713
return new CT_NamedType (get_node (0), get_node (1));
716
CTree *CBuilder::abst_declarator () {
717
// 1 : direct_abst_declarator
718
// 1+: ptr_operator..
719
// 2+: ptr_operator.. direct_abst_declarator
720
return declarator ();
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...
729
int braced = (get_node (0)->NodeName () != Container::NodeId ()) ? 3 : 0;
731
result = get_node (nodes () - 1); // PrivateName, pushed by semantic
733
// win specific declaration specifier
734
if (get_node (2)->token ()->type () != TOK_CLOSE_ROUND) {
736
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2), get_node (3));
738
result = new CT_BracedDeclarator (get_node (0), get_node (1), get_node (2));
739
// braced declarator only
740
if (nodes () == braced)
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));
760
result = new CT_ArrayDeclarator (result, d1->Son (0),
761
new CT_ArrayDelimiter (0, 0, 0, d1->Son (1)), d1->Son (2));
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);
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));
775
result = new CT_FctDeclarator (result, args, 0, 0);
782
CTree *CBuilder::direct_abst_declarator1 () {
786
// 3: ( param_decl_clause )
790
CTree *CBuilder::param_decl_clause () {
793
// 1: param_decl_list => cont
794
// 2: param_decl_list ... => cont token
796
return new CT_ArgDeclList ();
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)));
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);
810
if ((al->Sons () % 2) == 1)
811
result->AddProperties (CT_List::NO_LAST_SEP);
812
result->AddSon (new CT_ArgDecl (get_node (nodes ()-1))); // ...
819
CTree *CBuilder::param_decl_list () {
823
CTree *CBuilder::param_decl () {
825
// 3: param_decl1 param_init
826
CT_ArgDecl *ad = (CT_ArgDecl*)get_node (0);
828
ad->Initializer (get_node (1));
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));
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;
850
if (get_node (0)->NodeName () == CT_DeclSpecSeq::NodeId ())
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 ())) {
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);
869
Container *cont = (Container*)get_node (1+offset);
871
if (cont->Son (1)->NodeName () == CT_MembInitList::NodeId ())
874
b = cont->Son (1+offset);
875
hs = cont->Son (2+offset);
878
return new CT_FctDef (dss, d, t, ci, as, b, hs);
881
CTree *CBuilder::arg_decl_seq () {
882
return list (new CT_ArgDeclSeq (nodes ()));
885
CTree *CBuilder::fct_body () {
890
CTree *CBuilder::init () {
894
if (get_node (1)->NodeName () != CT_ExprList::NodeId ()) {
895
result = new CT_ExprList;
896
result->AddSon (get_node (1));
898
result = (CT_ExprList*)get_node (1);
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);
910
CTree *CBuilder::init_clause () {
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));
929
result->AddProperties (CT_List::OPEN_CLOSE);
933
CTree *CBuilder::init_list () {
934
return list (new CT_ExprList);
937
CTree *CBuilder::init_list_item () {
939
// 2: designation init_clause
942
Container *c = (Container*)get_node (0);
943
CTree *result = new CT_BinaryExpr (c->Son (0), c->Son (1), get_node (1));
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;
955
result->AddSon (get_node (nodes () - 1));
959
CTree *CBuilder::designator () {
963
return new CT_MembDesignator (get_node (0), get_node (1));
965
return new CT_IndexDesignator (get_node (0), get_node (1), get_node (2));
968
/*****************************************************************************/
970
/* A . 8 C l a s s e s */
972
/*****************************************************************************/
974
CTree *CBuilder::class_spec (CTree *result) {
975
Container *head = (Container*)get_node (0);
977
if (head->Son (0)->token ()->type () == TOK_UNION)
978
result = new CT_UnionDef (head->Son (0), head->Son (1));
980
result = new CT_ClassDef (head->Son (0), head->Son (1));
982
CT_MembList *ml = nodes () == 4 ?
983
(CT_MembList*)get_node (2) : new CT_MembList;
984
// if (nodes () != 4)
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);
976
CTree *CBuilder::class_spec_err (CTree *result) {
981
CTree *CBuilder::class_head () {
985
CTree *CBuilder::class_key () {
989
CTree *CBuilder::member_spec () {
990
return list (new CT_MembList);
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));
998
CTree *CBuilder::member_declarator_list () {
999
return list (new CT_DeclaratorList);
1002
CTree *CBuilder::member_declarator () {
1004
// 3: declarator : const_expr
1005
// 3: private_name : const_expr
1007
return new CT_InitDeclarator (get_node (0));
1009
return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2));
1012
/*****************************************************************************/
1014
/* A . 9 D e r i v e d c l a s s e s */
1016
/*****************************************************************************/
1018
/*****************************************************************************/
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 */
1022
/*****************************************************************************/
1024
/*****************************************************************************/
1026
/* A . 1 1 O v e r l o a d i n g */
1028
/*****************************************************************************/
1030
/*****************************************************************************/
1032
/* A . 1 2 T e m p l a t e s */
1034
/*****************************************************************************/
1036
/*****************************************************************************/
1038
/* A . 1 3 E x c e p t i o n h a n d l i n g */
1040
/*****************************************************************************/
988
ml->AddProperties (CT_List::OPEN_CLOSE);
989
((CT_ClassDef*)result)->Members (ml);
995
CTree *CBuilder::class_spec_err (CTree *result) {
1000
CTree *CBuilder::class_head () {
1001
return container ();
1004
CTree *CBuilder::class_key () {
1008
CTree *CBuilder::member_spec () {
1009
return list (new CT_MembList);
1012
CTree *CBuilder::member_decl () {
1013
// 2: type_spec_seq ;
1014
// 3: type_spec_seq member_declarator_list ;
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));
1020
CTree *CBuilder::member_declarator_list () {
1021
return list (new CT_DeclaratorList);
1024
CTree *CBuilder::member_declarator () {
1026
// 3: declarator : const_expr
1027
// 3: private_name : const_expr
1029
return new CT_InitDeclarator (get_node (0));
1031
return new CT_BitFieldDeclarator (get_node (0), get_node (1), get_node (2));
1034
/*****************************************************************************/
1036
/* A . 9 D e r i v e d c l a s s e s */
1038
/*****************************************************************************/
1040
/*****************************************************************************/
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 */
1044
/*****************************************************************************/
1046
/*****************************************************************************/
1048
/* A . 1 1 O v e r l o a d i n g */
1050
/*****************************************************************************/
1052
/*****************************************************************************/
1054
/* A . 1 2 T e m p l a t e s */
1056
/*****************************************************************************/
1058
/*****************************************************************************/
1060
/* A . 1 3 E x c e p t i o n h a n d l i n g */
1062
/*****************************************************************************/
1043
1065
} // namespace Puma