fdad3f6973e2a8f4b0da561b868a8a83ae4aac10
[oweals/gnunet.git] / src / monkey / seaspider / org / gnunet / seaspider / ExpressionExtractorVisitor.java
1 package org.gnunet.seaspider;
2
3 import org.gnunet.seaspider.parser.nodes.ANDExpression;
4 import org.gnunet.seaspider.parser.nodes.AdditiveExpression;
5 import org.gnunet.seaspider.parser.nodes.ArgumentExpressionList;
6 import org.gnunet.seaspider.parser.nodes.AssignmentExpression;
7 import org.gnunet.seaspider.parser.nodes.AssignmentOperator;
8 import org.gnunet.seaspider.parser.nodes.CastExpression;
9 import org.gnunet.seaspider.parser.nodes.CompoundStatement;
10 import org.gnunet.seaspider.parser.nodes.ConditionalExpression;
11 import org.gnunet.seaspider.parser.nodes.ConstantExpression;
12 import org.gnunet.seaspider.parser.nodes.DoWhileStatement;
13 import org.gnunet.seaspider.parser.nodes.EqualityExpression;
14 import org.gnunet.seaspider.parser.nodes.ExclusiveORExpression;
15 import org.gnunet.seaspider.parser.nodes.Expression;
16 import org.gnunet.seaspider.parser.nodes.ExpressionStatement;
17 import org.gnunet.seaspider.parser.nodes.ForStatement;
18 import org.gnunet.seaspider.parser.nodes.FunctionDeclaration;
19 import org.gnunet.seaspider.parser.nodes.IfStatement;
20 import org.gnunet.seaspider.parser.nodes.InclusiveORExpression;
21 import org.gnunet.seaspider.parser.nodes.InitDeclarator;
22 import org.gnunet.seaspider.parser.nodes.InitDeclaratorList;
23 import org.gnunet.seaspider.parser.nodes.Initializer;
24 import org.gnunet.seaspider.parser.nodes.InitializerList;
25 import org.gnunet.seaspider.parser.nodes.JumpStatement;
26 import org.gnunet.seaspider.parser.nodes.LogicalANDExpression;
27 import org.gnunet.seaspider.parser.nodes.LogicalORExpression;
28 import org.gnunet.seaspider.parser.nodes.MultiplicativeExpression;
29 import org.gnunet.seaspider.parser.nodes.Node;
30 import org.gnunet.seaspider.parser.nodes.NodeChoice;
31 import org.gnunet.seaspider.parser.nodes.NodeSequence;
32 import org.gnunet.seaspider.parser.nodes.NodeToken;
33 import org.gnunet.seaspider.parser.nodes.ParameterDeclaration;
34 import org.gnunet.seaspider.parser.nodes.PostfixExpression;
35 import org.gnunet.seaspider.parser.nodes.PrimaryExpression;
36 import org.gnunet.seaspider.parser.nodes.RelationalExpression;
37 import org.gnunet.seaspider.parser.nodes.ShiftExpression;
38 import org.gnunet.seaspider.parser.nodes.StructOrUnionSpecifier;
39 import org.gnunet.seaspider.parser.nodes.SwitchStatement;
40 import org.gnunet.seaspider.parser.nodes.TranslationUnit;
41 import org.gnunet.seaspider.parser.nodes.TypeDeclaration;
42 import org.gnunet.seaspider.parser.nodes.UnaryExpression;
43 import org.gnunet.seaspider.parser.nodes.UnaryOperator;
44 import org.gnunet.seaspider.parser.nodes.VariableDeclaration;
45 import org.gnunet.seaspider.parser.nodes.WhileStatement;
46 import org.gnunet.seaspider.parser.visitors.DepthFirstVisitor;
47 import org.grothoff.LineNumberInfo;
48
49 /**
50  * @author grothoff
51  * 
52  */
53 public class ExpressionExtractorVisitor extends DepthFirstVisitor {
54
55         class ExpressionBuilder {
56                 String expression = "";
57
58                 void push(String token) {
59                         expression = expression + token;
60                 }
61
62                 void commit(int line) {
63                         ExpressionDatabaseHandler.insertIntoExpressionTable(filename,
64                                         expression, line, scope_end_line);
65                 }
66
67         }
68
69         final String filename;
70
71         ExpressionBuilder current_expression;
72
73         int scope_end_line;
74
75         boolean operator;
76
77         boolean skip_mode = true;
78
79         /**
80          * 
81          */
82         public ExpressionExtractorVisitor(String filename) {
83                 this.filename = filename;
84         }
85
86         public void visit(TranslationUnit n) {
87                 LineNumberInfo lin = LineNumberInfo.get(n);
88                 scope_end_line = lin.lineEnd;
89                 n.f0.accept(this);
90                 assert scope_end_line == lin.lineEnd;
91         }
92
93         public void visit(NodeToken n) {
94                 if (skip_mode)
95                         return;
96                 current_expression.push(n.tokenImage);
97         }
98
99         public void visit(StructOrUnionSpecifier n) {
100                 // do nothing -- skip!
101         }
102
103         public void visit(TypeDeclaration n) {
104                 // do nothing -- skip!
105         }
106
107         public void visit(InitDeclaratorList n) {
108                 assert skip_mode == true;
109                 super.visit(n);
110                 assert skip_mode == true;
111         }
112
113         public void visit(Initializer n) {
114                 assert skip_mode == true;
115                 if (n.f0.which == 0) {
116                         boolean old_mode = skip_mode;
117                         skip_mode = false;
118                         ExpressionBuilder old = current_expression;
119                         current_expression = new ExpressionBuilder();
120                         n.f0.accept(this);
121                         LineNumberInfo lin = LineNumberInfo.get(n);
122                         if (old != null) {
123                                 old.push(current_expression.expression);
124                                 old.commit(lin.lineEnd);
125                         } else {
126                                 current_expression.commit(lin.lineEnd);
127                         }                       
128                         current_expression = old;
129                         skip_mode = old_mode;
130                 } else {
131                         super.visit(n);
132                 }
133                 assert skip_mode == true;
134         }
135
136         public void visit(InitializerList n) {
137                 assert skip_mode == true;
138                 super.visit(n);
139                 assert skip_mode == true;
140         }
141
142         public void visit(VariableDeclaration n) {
143                 assert skip_mode == true;
144                 super.visit(n);
145         }
146
147         public void visit(FunctionDeclaration n) {
148                 if (n.f5.which == 0)
149                         return; // no body
150                 int old_scope = scope_end_line;
151                 LineNumberInfo lin = LineNumberInfo.get(n);
152                 scope_end_line = lin.lineEnd;
153                 n.f3.accept(this);
154                 n.f5.accept(this);
155                 assert scope_end_line == lin.lineEnd;
156                 scope_end_line = old_scope;
157         }
158
159         public void visit(ParameterDeclaration n) {
160                 skip_mode = false;
161                 assert current_expression == null;
162                 if (n.f1.present()) {
163                         NodeSequence ns = (NodeSequence) n.f1.node;
164                         Node var = ns.elementAt(0);
165                         current_expression = new ExpressionBuilder();
166                         var.accept(this);
167                         LineNumberInfo lin = LineNumberInfo.get(var);
168                         current_expression.commit(lin.lineEnd);
169                 }
170                 current_expression = null;
171                 skip_mode = true;
172         }
173
174         public void visit(InitDeclarator n) {
175                 skip_mode = false;
176                 assert current_expression == null;
177                 current_expression = new ExpressionBuilder();
178                 n.f0.accept(this);
179                 current_expression = null;
180                 skip_mode = true;
181                 n.f2.accept(this);
182         }
183
184         public void visit(ExpressionStatement n) {
185                 if (!n.f0.present())
186                         return;
187                 assert current_expression == null;
188                 skip_mode = false;
189                 current_expression = new ExpressionBuilder();
190                 n.f0.accept(this);
191                 LineNumberInfo lin = LineNumberInfo.get(n);
192                 current_expression.commit(lin.lineEnd);
193                 current_expression = null;
194                 skip_mode = true;
195         }
196
197         public void visit(CompoundStatement n) {
198                 assert current_expression == null;
199                 assert skip_mode == true;
200                 int old_end = scope_end_line;
201                 scope_end_line = n.f2.endLine;
202                 n.f1.accept(this);
203                 scope_end_line = old_end;
204         }
205
206         public void visit(SwitchStatement n) {
207                 assert current_expression == null;
208                 skip_mode = false;
209                 current_expression = new ExpressionBuilder();
210                 n.f2.accept(this);
211                 current_expression.commit(n.f0.endLine);
212                 skip_mode = true;
213                 current_expression = null;
214                 n.f4.accept(this);
215         }
216
217         public void visit(IfStatement n) {
218                 assert current_expression == null;
219                 skip_mode = false;
220                 current_expression = new ExpressionBuilder();
221                 n.f2.accept(this);
222                 current_expression.commit(n.f0.endLine);
223                 skip_mode = true;
224                 current_expression = null;
225                 n.f4.accept(this);
226                 n.f5.accept(this);
227         }
228
229         public void visit(WhileStatement n) {
230                 assert current_expression == null;
231                 skip_mode = false;
232                 current_expression = new ExpressionBuilder();
233                 n.f2.accept(this);
234                 current_expression.commit(n.f0.endLine);
235                 skip_mode = true;
236                 current_expression = null;
237                 n.f4.accept(this);
238         }
239
240         public void visit(DoWhileStatement n) {
241                 assert current_expression == null;
242                 skip_mode = false;
243                 current_expression = new ExpressionBuilder();
244                 n.f4.accept(this);
245                 current_expression.commit(n.f6.endLine);
246                 skip_mode = true;
247                 current_expression = null;
248                 n.f1.accept(this);
249         }
250
251         public void visit(ForStatement n) {
252                 assert current_expression == null;
253                 skip_mode = false;
254                 int old_scope = scope_end_line;
255                 LineNumberInfo lin = LineNumberInfo.get(n);
256                 scope_end_line = lin.lineEnd;
257                 if (n.f2.present()) {
258                         current_expression = new ExpressionBuilder();
259                         n.f2.accept(this);
260                         current_expression.commit(n.f3.endLine);
261                 }
262                 if (n.f4.present()) {
263                         current_expression = new ExpressionBuilder();
264                         n.f4.accept(this);
265                         current_expression.commit(n.f5.endLine);
266                 }
267                 if (n.f6.present()) {
268                         current_expression = new ExpressionBuilder();
269                         n.f6.accept(this);
270                         current_expression.commit(n.f7.endLine);
271                 }
272                 skip_mode = true;
273                 current_expression = null;
274                 n.f8.accept(this);
275                 scope_end_line = old_scope;
276         }
277
278         public void visit(JumpStatement n) {
279                 if (n.f0.which != 3)
280                         return;
281                 NodeSequence ns = (NodeSequence) n.f0.choice;
282                 assert current_expression == null;
283                 skip_mode = false;
284                 current_expression = new ExpressionBuilder();
285                 ns.elementAt(1).accept(this);
286                 LineNumberInfo lin = LineNumberInfo.get(n);
287                 current_expression.commit(lin.lineEnd);
288                 current_expression = null;
289                 skip_mode = true;
290         }
291
292         public void visit(Expression n) {
293                 ExpressionBuilder old = current_expression;
294                 current_expression = new ExpressionBuilder();
295                 n.f0.accept(this);
296                 for (int i = 0; i < n.f1.size(); i++) {
297                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
298                         current_expression = new ExpressionBuilder();
299                         ns.elementAt(1).accept(this);
300                 }
301                 old.push(current_expression.expression);
302                 current_expression = old;
303         }       
304         
305         public void visit(AssignmentOperator n) {
306                 operator = true;
307                 super.visit(n);
308                 operator = false;
309         }
310         
311         public void visit(AssignmentExpression n)
312         {
313                 if (0 == n.f0.which)
314                 {
315                         NodeSequence ns = (NodeSequence) n.f0.choice;
316                         UnaryExpression u = (UnaryExpression) ns.elementAt(0);
317                         AssignmentOperator ao = (AssignmentOperator) ns.elementAt(1);
318                         AssignmentExpression ae = (AssignmentExpression) ns.elementAt(2);
319                         LineNumberInfo lin = LineNumberInfo.get(n);
320
321                         ExpressionBuilder old = current_expression;
322                         current_expression = new ExpressionBuilder();
323                         u.accept(this);
324                         current_expression.commit(lin.lineEnd);
325                         ao.accept (this);
326                         old.push(current_expression.expression);
327                         current_expression = new ExpressionBuilder();
328                         ae.accept(this);
329                         current_expression.commit(lin.lineEnd);
330                         old.push(current_expression.expression);
331                         current_expression = old;
332                 }
333                 else
334                 {
335                         n.f0.choice.accept (this);
336                 }
337         }
338
339         public void visit(ConditionalExpression n) {
340                 ExpressionBuilder old = current_expression;
341                 current_expression = new ExpressionBuilder();
342                 n.f0.accept(this);
343                 old.push(current_expression.expression);
344                 if (n.f1.present()) {
345                         LineNumberInfo lin = LineNumberInfo.get(n);
346                         NodeSequence ns = (NodeSequence) n.f1.node;
347                         current_expression = new ExpressionBuilder();
348                         ns.elementAt(1).accept(this);
349                         current_expression.commit(lin.lineEnd);
350                         old.push("?");
351                         old.push(current_expression.expression);
352                         current_expression = new ExpressionBuilder();
353                         ns.elementAt(3).accept(this);
354                         current_expression.commit(lin.lineEnd);
355                         old.push(":");
356                         old.push(current_expression.expression);
357                         old.commit(lin.lineEnd);
358                 }
359                 current_expression = old;
360         }
361
362         public void visit(ConstantExpression n) {
363                 /* skip */
364         }
365
366         public void visit(LogicalORExpression n) {
367                 assert skip_mode == false;
368                 ExpressionBuilder old = current_expression;
369                 current_expression = new ExpressionBuilder();
370                 n.f0.accept(this);
371                 if (n.f1.present()) {
372                         LineNumberInfo lin = LineNumberInfo.get(n);
373                         current_expression.commit(lin.lineEnd);
374                         operator = true;
375                         NodeSequence ns = (NodeSequence) n.f1.node;
376                         ns.nodes.get(0).accept(this);
377                         operator = false;
378                         old.push(current_expression.expression);                        
379                         current_expression = new ExpressionBuilder();                   
380                         ns.nodes.get(1).accept(this);
381                         current_expression.commit(lin.lineEnd);
382                 }
383                 old.push(current_expression.expression);
384                 current_expression = old;
385         }
386
387         public void visit(LogicalANDExpression n) {
388                 assert skip_mode == false;
389                 ExpressionBuilder old = current_expression;
390                 current_expression = new ExpressionBuilder();
391                 n.f0.accept(this);
392                 if (n.f1.present()) {
393                         LineNumberInfo lin = LineNumberInfo.get(n);
394                         current_expression.commit(lin.lineEnd);
395                         operator = true;
396                         NodeSequence ns = (NodeSequence) n.f1.node;
397                         ns.nodes.get(0).accept(this);
398                         operator = false;
399                         old.push(current_expression.expression);                        
400                         current_expression = new ExpressionBuilder();                   
401                         ns.nodes.get(1).accept(this);
402                         current_expression.commit(lin.lineEnd);
403                 }
404                 old.push(current_expression.expression);
405                 current_expression = old;
406         }
407
408         public void visit(InclusiveORExpression n) {
409                 assert skip_mode == false;
410                 ExpressionBuilder old = current_expression;
411                 current_expression = new ExpressionBuilder();
412                 n.f0.accept(this);
413                 if (n.f1.present()) {
414                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
415                         current_expression.commit(lin.lineEnd);
416                         operator = true;
417                         NodeSequence ns = (NodeSequence) n.f1.node;
418                         ns.nodes.get(0).accept(this);
419                         operator = false;
420                         ExpressionBuilder tmp = current_expression;
421                         current_expression = new ExpressionBuilder();                           
422                         ns.nodes.get(1).accept(this);
423                         lin = LineNumberInfo.get(ns.nodes.get(1));
424                         current_expression.commit(lin.lineEnd);
425                         tmp.push (current_expression.expression);
426                         current_expression = tmp;
427                 }
428                 old.push(current_expression.expression);
429                 current_expression = old;
430         }
431
432         public void visit(ExclusiveORExpression n) {
433                 assert skip_mode == false;
434                 ExpressionBuilder old = current_expression;
435                 current_expression = new ExpressionBuilder();
436                 n.f0.accept(this);
437                 if (n.f1.present()) {
438                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
439                         current_expression.commit(lin.lineEnd);
440                         operator = true;
441                         NodeSequence ns = (NodeSequence) n.f1.node;
442                         ns.nodes.get(0).accept(this);
443                         operator = false;
444                         ExpressionBuilder tmp = current_expression;
445                         current_expression = new ExpressionBuilder();                           
446                         ns.nodes.get(1).accept(this);
447                         lin = LineNumberInfo.get(ns.nodes.get(1));
448                         current_expression.commit(lin.lineEnd);
449                         tmp.push (current_expression.expression);
450                         current_expression = tmp;
451                 }
452                 old.push(current_expression.expression);
453                 current_expression = old;
454         }
455
456         public void visit(ANDExpression n) {
457                 assert skip_mode == false;
458                 ExpressionBuilder old = current_expression;
459                 current_expression = new ExpressionBuilder();
460                 n.f0.accept(this);
461                 if (n.f1.present()) {
462                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
463                         current_expression.commit(lin.lineEnd);
464                         operator = true;
465                         NodeSequence ns = (NodeSequence) n.f1.node;
466                         ns.nodes.get(0).accept(this);
467                         operator = false;
468                         ExpressionBuilder tmp = current_expression;
469                         current_expression = new ExpressionBuilder();                           
470                         ns.nodes.get(1).accept(this);
471                         lin = LineNumberInfo.get(ns.nodes.get(1));
472                         current_expression.commit(lin.lineEnd);
473                         tmp.push (current_expression.expression);
474                         current_expression = tmp;
475                 }
476                 old.push(current_expression.expression);
477                 current_expression = old;
478         }
479
480         // Safey: this function was fixed to commit the right hand side, the
481         // other similar functions still need to be updated accordingly...
482         public void visit(EqualityExpression n) {
483                 assert skip_mode == false;
484                 ExpressionBuilder old = current_expression;
485                 current_expression = new ExpressionBuilder();
486                 n.f0.accept(this);
487                 if (n.f1.present()) {
488                         LineNumberInfo lin = LineNumberInfo.get(n);
489                         current_expression.commit(lin.lineEnd);
490                         operator = true;
491                         NodeSequence ns = (NodeSequence) n.f1.node;
492                         ns.nodes.get(0).accept(this);
493                         operator = false;
494                         old.push(current_expression.expression);
495                         current_expression = new ExpressionBuilder();
496                         ns.nodes.get(1).accept(this);
497                         current_expression.commit(lin.lineEnd);
498                 }
499                 old.push(current_expression.expression);
500                 current_expression = old;
501         }
502
503         public void visit(RelationalExpression n) {
504                 assert skip_mode == false;
505                 ExpressionBuilder old = current_expression;
506                 current_expression = new ExpressionBuilder();
507                 n.f0.accept(this);
508                 if (n.f1.present()) {
509                         LineNumberInfo lin = LineNumberInfo.get(n);
510                         current_expression.commit(lin.lineEnd);
511                         operator = true;
512                         NodeSequence ns = (NodeSequence) n.f1.node;
513                         ns.nodes.get(0).accept(this);
514                         operator = false;
515                         old.push(current_expression.expression);
516                         current_expression = new ExpressionBuilder();
517                         ns.nodes.get(1).accept(this);
518                         current_expression.commit(lin.lineEnd);
519                 }
520                 old.push(current_expression.expression);
521                 current_expression = old;
522         }
523
524         public void visit(ShiftExpression n) {
525                 assert skip_mode == false;
526                 ExpressionBuilder old = current_expression;
527                 current_expression = new ExpressionBuilder();
528                 n.f0.accept(this);
529                 if (n.f1.present()) {
530                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
531                         current_expression.commit(lin.lineEnd);
532                         operator = true;
533                         NodeSequence ns = (NodeSequence) n.f1.node;
534                         ns.nodes.get(0).accept(this);
535                         operator = false;
536                         ExpressionBuilder tmp = current_expression;
537                         current_expression = new ExpressionBuilder();                           
538                         ns.nodes.get(1).accept(this);
539                         lin = LineNumberInfo.get(ns.nodes.get(1));
540                         current_expression.commit(lin.lineEnd);
541                         tmp.push (current_expression.expression);
542                         current_expression = tmp;
543                 }
544                 old.push(current_expression.expression);
545                 current_expression = old;
546         }
547
548         public void visit(AdditiveExpression n) {
549                 assert skip_mode == false;
550                 ExpressionBuilder old = current_expression;
551                 current_expression = new ExpressionBuilder();
552                 n.f0.accept(this);
553                 if (n.f1.present()) {
554                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
555                         current_expression.commit(lin.lineEnd);
556                         operator = true;
557                         NodeSequence ns = (NodeSequence) n.f1.node;
558                         ns.nodes.get(0).accept(this);
559                         operator = false;
560                         ExpressionBuilder tmp = current_expression;
561                         current_expression = new ExpressionBuilder();                           
562                         ns.nodes.get(1).accept(this);
563                         lin = LineNumberInfo.get(ns.nodes.get(1));
564                         current_expression.commit(lin.lineEnd);
565                         tmp.push (current_expression.expression);
566                         current_expression = tmp;
567                 }
568                 old.push(current_expression.expression);
569                 current_expression = old;
570         }
571
572         public void visit(MultiplicativeExpression n) {
573                 assert skip_mode == false;
574                 ExpressionBuilder old = current_expression;
575                 current_expression = new ExpressionBuilder();
576                 n.f0.accept(this);
577                 if (n.f1.present()) {
578                         LineNumberInfo lin = LineNumberInfo.get(n.f0);
579                         current_expression.commit(lin.lineEnd);
580                         operator = true;
581                         NodeSequence ns = (NodeSequence) n.f1.node;
582                         ns.nodes.get(0).accept(this);
583                         operator = false;
584                         ExpressionBuilder tmp = current_expression;
585                         current_expression = new ExpressionBuilder();                           
586                         ns.nodes.get(1).accept(this);
587                         lin = LineNumberInfo.get(ns.nodes.get(1));
588                         current_expression.commit(lin.lineEnd);
589                         tmp.push (current_expression.expression);
590                         current_expression = tmp;
591                 }
592                 old.push(current_expression.expression);
593                 current_expression = old;
594         }
595
596         public void visit(CastExpression n) {
597                 if (n.f0.which == 1) {
598                         n.f0.accept(this);
599                         return;
600                 }
601                 NodeSequence ns = (NodeSequence) n.f0.choice;
602                 ns.nodes.get(3).accept(this);
603         }
604
605         public void visit(UnaryExpression n) {
606                 if ((n.f0.which == 1) || (n.f0.which == 2)) {
607                         NodeSequence ns = (NodeSequence) n.f0.choice;
608                         ns.nodes.get(1).accept(this);
609                 } else
610                         n.f0.accept(this);
611
612         }
613
614         public void visit(UnaryOperator n) {
615                 operator = true;
616                 n.f0.accept(this);
617                 operator = false;
618         }
619
620         public void visit(PostfixExpression n) {
621                 n.f0.accept(this);
622                 for (int i = 0; i < n.f1.size(); i++) {
623                         NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
624                         switch (nc.which) {
625                         case 0: // []
626                         {
627                                 ExpressionBuilder old = current_expression;
628                                 current_expression = new ExpressionBuilder();
629                                 NodeSequence ns = (NodeSequence) nc.choice;
630                                 ns.elementAt(1).accept(this);
631                                 LineNumberInfo lin = LineNumberInfo.get(n);
632                                 current_expression.commit(lin.lineEnd);
633                                 old.push("[");
634                                 old.push(current_expression.expression);
635                                 old.push("]");
636                                 current_expression = old;
637                         }
638                         case 1: // ()
639                         {
640                                 ExpressionBuilder old = current_expression;
641                                 current_expression = new ExpressionBuilder();
642                                 NodeSequence ns = (NodeSequence) nc.choice;
643                                 ns.elementAt(1).accept(this);
644                                 LineNumberInfo lin = LineNumberInfo.get (ns.elementAt(1));
645                                 if (! current_expression.expression.isEmpty())
646                                         current_expression.commit(lin.lineEnd);
647                                 old.push("(");
648                                 old.push(current_expression.expression);
649                                 old.push(")");
650                                 current_expression = old;
651                         }
652                                 break;
653                         case 2: // .
654                         case 3: // ->
655                         {
656                                 ExpressionBuilder old = current_expression;
657                                 LineNumberInfo lin = LineNumberInfo.get(n);
658                                 old.commit(lin.lineEnd);
659                                 current_expression = new ExpressionBuilder();
660                                 NodeSequence ns = (NodeSequence) nc.choice;
661                                 ns.elementAt(1).accept(this);
662                                 if (nc.which == 2)
663                                         old.push(".");
664                                 else
665                                         old.push("->");
666                                 old.push(current_expression.expression);
667                                 current_expression = old;
668                         }
669                                 break;
670                         case 4: // ++
671                         case 5: // --
672                                 /* skip */
673                                 break;
674                         default:
675                                 throw new Error("Oops!");
676                         }
677                 }
678         }
679
680         public void visit(PrimaryExpression n) {
681                 if (n.f0.which == 2) {
682                         ExpressionBuilder old = current_expression;
683                         current_expression = new ExpressionBuilder();
684                         NodeSequence ns = (NodeSequence) n.f0.choice;
685                         ns.elementAt(1).accept(this);
686                         LineNumberInfo lin1 = LineNumberInfo.get (ns.elementAt(1));
687                         current_expression.commit(lin1.lineEnd);
688                         old.push("(");
689                         old.push(current_expression.expression);
690                         old.push(")");
691                         LineNumberInfo lin = LineNumberInfo.get(n);
692                         old.commit(lin.lineEnd);
693                         current_expression = old;
694                 } else
695                         n.f0.accept(this);
696         }
697
698         public void visit(ArgumentExpressionList n) {
699                 ExpressionBuilder old = current_expression;
700                 current_expression = new ExpressionBuilder();
701                 n.f0.accept(this);
702                 old.push(current_expression.expression);
703                 for (int i = 0; i < n.f1.size(); i++) {
704                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
705                         current_expression = new ExpressionBuilder();
706                         ns.elementAt(1).accept(this);
707                         old.push(",");
708                         old.push(current_expression.expression);
709                 }
710                 current_expression = old;
711         }
712
713 }