fix
[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                         if (old != null) {
122                                 old.push(current_expression.expression);
123                                 LineNumberInfo lin = LineNumberInfo.get(n);
124                                 old.commit(lin.lineEnd);
125                         }
126                         current_expression = old;
127                         skip_mode = old_mode;
128                 } else {
129                         super.visit(n);
130                 }
131                 assert skip_mode == true;
132         }
133
134         public void visit(InitializerList n) {
135                 assert skip_mode == true;
136                 super.visit(n);
137                 assert skip_mode == true;
138         }
139
140         public void visit(VariableDeclaration n) {
141                 assert skip_mode == true;
142                 super.visit(n);
143         }
144
145         public void visit(FunctionDeclaration n) {
146                 if (n.f5.which == 0)
147                         return; // no body
148                 int old_scope = scope_end_line;
149                 LineNumberInfo lin = LineNumberInfo.get(n);
150                 scope_end_line = lin.lineEnd;
151                 n.f3.accept(this);
152                 n.f5.accept(this);
153                 assert scope_end_line == lin.lineEnd;
154                 scope_end_line = old_scope;
155         }
156
157         public void visit(ParameterDeclaration n) {
158                 skip_mode = false;
159                 assert current_expression == null;
160                 if (n.f1.present()) {
161                         NodeSequence ns = (NodeSequence) n.f1.node;
162                         Node var = ns.elementAt(0);
163                         current_expression = new ExpressionBuilder();
164                         var.accept(this);
165                         LineNumberInfo lin = LineNumberInfo.get(var);
166                         current_expression.commit(lin.lineEnd);
167                 }
168                 current_expression = null;
169                 skip_mode = true;
170         }
171
172         public void visit(InitDeclarator n) {
173                 skip_mode = false;
174                 assert current_expression == null;
175                 current_expression = new ExpressionBuilder();
176                 n.f0.accept(this);
177                 current_expression = null;
178                 skip_mode = true;
179                 n.f2.accept(this);
180         }
181
182         public void visit(ExpressionStatement n) {
183                 if (!n.f0.present())
184                         return;
185                 assert current_expression == null;
186                 skip_mode = false;
187                 current_expression = new ExpressionBuilder();
188                 n.f0.accept(this);
189                 LineNumberInfo lin = LineNumberInfo.get(n);
190                 current_expression.commit(lin.lineEnd);
191                 current_expression = null;
192                 skip_mode = true;
193         }
194
195         public void visit(CompoundStatement n) {
196                 assert current_expression == null;
197                 assert skip_mode == true;
198                 int old_end = scope_end_line;
199                 scope_end_line = n.f2.endLine;
200                 n.f1.accept(this);
201                 scope_end_line = old_end;
202         }
203
204         public void visit(SwitchStatement n) {
205                 assert current_expression == null;
206                 skip_mode = false;
207                 current_expression = new ExpressionBuilder();
208                 n.f2.accept(this);
209                 current_expression.commit(n.f0.endLine);
210                 skip_mode = true;
211                 current_expression = null;
212                 n.f4.accept(this);
213         }
214
215         public void visit(IfStatement n) {
216                 assert current_expression == null;
217                 skip_mode = false;
218                 current_expression = new ExpressionBuilder();
219                 n.f2.accept(this);
220                 current_expression.commit(n.f0.endLine);
221                 skip_mode = true;
222                 current_expression = null;
223                 n.f4.accept(this);
224                 n.f5.accept(this);
225         }
226
227         public void visit(WhileStatement n) {
228                 assert current_expression == null;
229                 skip_mode = false;
230                 current_expression = new ExpressionBuilder();
231                 n.f2.accept(this);
232                 current_expression.commit(n.f0.endLine);
233                 skip_mode = true;
234                 current_expression = null;
235                 n.f4.accept(this);
236         }
237
238         public void visit(DoWhileStatement n) {
239                 assert current_expression == null;
240                 skip_mode = false;
241                 current_expression = new ExpressionBuilder();
242                 n.f4.accept(this);
243                 current_expression.commit(n.f6.endLine);
244                 skip_mode = true;
245                 current_expression = null;
246                 n.f1.accept(this);
247         }
248
249         public void visit(ForStatement n) {
250                 assert current_expression == null;
251                 skip_mode = false;
252                 int old_scope = scope_end_line;
253                 LineNumberInfo lin = LineNumberInfo.get(n);
254                 scope_end_line = lin.lineEnd;
255                 if (n.f2.present()) {
256                         current_expression = new ExpressionBuilder();
257                         n.f2.accept(this);
258                         current_expression.commit(n.f3.endLine);
259                 }
260                 if (n.f4.present()) {
261                         current_expression = new ExpressionBuilder();
262                         n.f4.accept(this);
263                         current_expression.commit(n.f5.endLine);
264                 }
265                 if (n.f6.present()) {
266                         current_expression = new ExpressionBuilder();
267                         n.f6.accept(this);
268                         current_expression.commit(n.f7.endLine);
269                 }
270                 skip_mode = true;
271                 current_expression = null;
272                 n.f8.accept(this);
273                 scope_end_line = old_scope;
274         }
275
276         public void visit(JumpStatement n) {
277                 if (n.f0.which != 3)
278                         return;
279                 NodeSequence ns = (NodeSequence) n.f0.choice;
280                 assert current_expression == null;
281                 skip_mode = false;
282                 current_expression = new ExpressionBuilder();
283                 ns.elementAt(1).accept(this);
284                 LineNumberInfo lin = LineNumberInfo.get(n);
285                 current_expression.commit(lin.lineEnd);
286                 current_expression = null;
287                 skip_mode = true;
288         }
289
290         public void visit(Expression n) {
291                 ExpressionBuilder old = current_expression;
292                 current_expression = new ExpressionBuilder();
293                 n.f0.accept(this);
294                 for (int i = 0; i < n.f1.size(); i++) {
295                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
296                         current_expression = new ExpressionBuilder();
297                         ns.elementAt(1).accept(this);
298                 }
299                 old.push(current_expression.expression);
300                 current_expression = old;
301         }       
302         
303         public void visit(AssignmentOperator n) {
304                 operator = true;
305                 super.visit(n);
306                 operator = false;
307         }
308         
309         public void visit(AssignmentExpression n)
310         {
311                 if (0 == n.f0.which)
312                 {
313                         NodeSequence ns = (NodeSequence) n.f0.choice;
314                         UnaryExpression u = (UnaryExpression) ns.elementAt(0);
315                         AssignmentOperator ao = (AssignmentOperator) ns.elementAt(1);
316                         AssignmentExpression ae = (AssignmentExpression) ns.elementAt(2);
317                         LineNumberInfo lin = LineNumberInfo.get(n);
318
319                         ExpressionBuilder old = current_expression;
320                         current_expression = new ExpressionBuilder();
321                         u.accept(this);
322                         current_expression.commit(lin.lineEnd);
323                         ao.accept (this);
324                         old.push(current_expression.expression);
325                         current_expression = new ExpressionBuilder();
326                         ae.accept(this);
327                         current_expression.commit(lin.lineEnd);
328                         old.push(current_expression.expression);
329                         current_expression = old;
330                 }
331                 else
332                 {
333                         n.f0.choice.accept (this);
334                 }
335         }
336
337         public void visit(ConditionalExpression n) {
338                 ExpressionBuilder old = current_expression;
339                 current_expression = new ExpressionBuilder();
340                 n.f0.accept(this);
341                 old.push(current_expression.expression);
342                 if (n.f1.present()) {
343                         LineNumberInfo lin = LineNumberInfo.get(n);
344                         NodeSequence ns = (NodeSequence) n.f1.node;
345                         current_expression = new ExpressionBuilder();
346                         ns.elementAt(1).accept(this);
347                         current_expression.commit(lin.lineEnd);
348                         old.push("?");
349                         old.push(current_expression.expression);
350                         current_expression = new ExpressionBuilder();
351                         ns.elementAt(3).accept(this);
352                         current_expression.commit(lin.lineEnd);
353                         old.push(":");
354                         old.push(current_expression.expression);
355                         old.commit(lin.lineEnd);
356                 }
357                 current_expression = old;
358         }
359
360         public void visit(ConstantExpression n) {
361                 /* skip */
362         }
363
364         public void visit(LogicalORExpression n) {
365                 assert skip_mode == false;
366                 ExpressionBuilder old = current_expression;
367                 current_expression = new ExpressionBuilder();
368                 n.f0.accept(this);
369                 if (n.f1.present()) {
370                         LineNumberInfo lin = LineNumberInfo.get(n);
371                         current_expression.commit(lin.lineEnd);
372                         operator = true;
373                         NodeSequence ns = (NodeSequence) n.f1.node;
374                         ns.nodes.get(0).accept(this);
375                         operator = false;
376                         old.push(current_expression.expression);                        
377                         current_expression = new ExpressionBuilder();                   
378                         ns.nodes.get(1).accept(this);
379                         current_expression.commit(lin.lineEnd);
380                 }
381                 old.push(current_expression.expression);
382                 current_expression = old;
383         }
384
385         public void visit(LogicalANDExpression n) {
386                 assert skip_mode == false;
387                 ExpressionBuilder old = current_expression;
388                 current_expression = new ExpressionBuilder();
389                 n.f0.accept(this);
390                 if (n.f1.present()) {
391                         LineNumberInfo lin = LineNumberInfo.get(n);
392                         current_expression.commit(lin.lineEnd);
393                         operator = true;
394                         NodeSequence ns = (NodeSequence) n.f1.node;
395                         ns.nodes.get(0).accept(this);
396                         operator = false;
397                         old.push(current_expression.expression);                        
398                         current_expression = new ExpressionBuilder();                   
399                         ns.nodes.get(1).accept(this);
400                         current_expression.commit(lin.lineEnd);
401                 }
402                 old.push(current_expression.expression);
403                 current_expression = old;
404         }
405
406         public void visit(InclusiveORExpression n) {
407                 assert skip_mode == false;
408                 ExpressionBuilder old = current_expression;
409                 current_expression = new ExpressionBuilder();
410                 n.f0.accept(this);
411                 if (n.f1.present()) {
412                         operator = true;
413                         NodeSequence ns = (NodeSequence) n.f1.node;
414                         ns.nodes.get(0).accept(this);
415                         operator = false;
416                         ns.nodes.get(1).accept(this);
417                 }
418                 old.push(current_expression.expression);
419                 current_expression = old;
420         }
421
422         public void visit(ExclusiveORExpression n) {
423                 assert skip_mode == false;
424                 ExpressionBuilder old = current_expression;
425                 current_expression = new ExpressionBuilder();
426                 n.f0.accept(this);
427                 if (n.f1.present()) {
428                         operator = true;
429                         NodeSequence ns = (NodeSequence) n.f1.node;
430                         ns.nodes.get(0).accept(this);
431                         operator = false;
432                         ns.nodes.get(1).accept(this);
433                 }
434                 old.push(current_expression.expression);
435                 current_expression = old;
436         }
437
438         public void visit(ANDExpression n) {
439                 assert skip_mode == false;
440                 ExpressionBuilder old = current_expression;
441                 current_expression = new ExpressionBuilder();
442                 n.f0.accept(this);
443                 if (n.f1.present()) {
444                         operator = true;
445                         NodeSequence ns = (NodeSequence) n.f1.node;
446                         ns.nodes.get(0).accept(this);
447                         operator = false;
448                         ns.nodes.get(1).accept(this);
449                 }
450                 old.push(current_expression.expression);
451                 current_expression = old;
452         }
453
454         // Safey: this function was fixed to commit the right hand side, the
455         // other similar functions still need to be updated accordingly...
456         public void visit(EqualityExpression 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);
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                         old.push(current_expression.expression);
469                         current_expression = new ExpressionBuilder();
470                         ns.nodes.get(1).accept(this);
471                         current_expression.commit(lin.lineEnd);
472                 }
473                 old.push(current_expression.expression);
474                 current_expression = old;
475         }
476
477         public void visit(RelationalExpression n) {
478                 assert skip_mode == false;
479                 ExpressionBuilder old = current_expression;
480                 current_expression = new ExpressionBuilder();
481                 n.f0.accept(this);
482                 if (n.f1.present()) {
483                         LineNumberInfo lin = LineNumberInfo.get(n);
484                         current_expression.commit(lin.lineEnd);
485                         operator = true;
486                         NodeSequence ns = (NodeSequence) n.f1.node;
487                         ns.nodes.get(0).accept(this);
488                         operator = false;
489                         old.push(current_expression.expression);
490                         current_expression = new ExpressionBuilder();
491                         ns.nodes.get(1).accept(this);
492                         current_expression.commit(lin.lineEnd);
493                 }
494                 old.push(current_expression.expression);
495                 current_expression = old;
496         }
497
498         public void visit(ShiftExpression n) {
499                 assert skip_mode == false;
500                 ExpressionBuilder old = current_expression;
501                 current_expression = new ExpressionBuilder();
502                 n.f0.accept(this);
503                 if (n.f1.present()) {
504                         operator = true;
505                         NodeSequence ns = (NodeSequence) n.f1.node;
506                         ns.nodes.get(0).accept(this);
507                         operator = false;
508                         ns.nodes.get(1).accept(this);
509                 }
510                 old.push(current_expression.expression);
511                 current_expression = old;
512         }
513
514         public void visit(AdditiveExpression n) {
515                 assert skip_mode == false;
516                 ExpressionBuilder old = current_expression;
517                 current_expression = new ExpressionBuilder();
518                 n.f0.accept(this);
519                 if (n.f1.present()) {
520                         operator = true;
521                         NodeSequence ns = (NodeSequence) n.f1.node;
522                         ns.nodes.get(0).accept(this);
523                         operator = false;
524                         ns.nodes.get(1).accept(this);
525                 }
526                 old.push(current_expression.expression);
527                 current_expression = old;
528         }
529
530         public void visit(MultiplicativeExpression n) {
531                 assert skip_mode == false;
532                 ExpressionBuilder old = current_expression;
533                 current_expression = new ExpressionBuilder();
534                 n.f0.accept(this);
535                 if (n.f1.present()) {
536                         operator = true;
537                         NodeSequence ns = (NodeSequence) n.f1.node;
538                         ns.nodes.get(0).accept(this);
539                         operator = false;
540                         ns.nodes.get(1).accept(this);
541                 }
542                 old.push(current_expression.expression);
543                 current_expression = old;
544         }
545
546         public void visit(CastExpression n) {
547                 if (n.f0.which == 1) {
548                         n.f0.accept(this);
549                         return;
550                 }
551                 NodeSequence ns = (NodeSequence) n.f0.choice;
552                 ns.nodes.get(3).accept(this);
553         }
554
555         public void visit(UnaryExpression n) {
556                 if ((n.f0.which == 1) || (n.f0.which == 2)) {
557                         NodeSequence ns = (NodeSequence) n.f0.choice;
558                         ns.nodes.get(1).accept(this);
559                 } else
560                         n.f0.accept(this);
561
562         }
563
564         public void visit(UnaryOperator n) {
565                 operator = true;
566                 n.f0.accept(this);
567                 operator = false;
568         }
569
570         public void visit(PostfixExpression n) {
571                 n.f0.accept(this);
572                 for (int i = 0; i < n.f1.size(); i++) {
573                         NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
574                         switch (nc.which) {
575                         case 0: // []
576                         {
577                                 ExpressionBuilder old = current_expression;
578                                 current_expression = new ExpressionBuilder();
579                                 NodeSequence ns = (NodeSequence) nc.choice;
580                                 ns.elementAt(1).accept(this);
581                                 LineNumberInfo lin = LineNumberInfo.get(n);
582                                 current_expression.commit(lin.colEnd);
583                                 old.push("[");
584                                 old.push(current_expression.expression);
585                                 old.push("]");
586                                 current_expression = old;
587                         }
588                         case 1: // ()
589                         {
590                                 ExpressionBuilder old = current_expression;
591                                 current_expression = new ExpressionBuilder();
592                                 NodeSequence ns = (NodeSequence) nc.choice;
593                                 ns.elementAt(1).accept(this);
594                                 old.push("(");
595                                 old.push(current_expression.expression);
596                                 old.push(")");
597                                 current_expression = old;
598                         }
599                                 break;
600                         case 2: // .
601                         case 3: // ->
602                         {
603                                 ExpressionBuilder old = current_expression;
604                                 LineNumberInfo lin = LineNumberInfo.get(n);
605                                 old.commit(lin.lineEnd);
606                                 current_expression = new ExpressionBuilder();
607                                 NodeSequence ns = (NodeSequence) nc.choice;
608                                 ns.elementAt(1).accept(this);
609                                 if (nc.which == 2)
610                                         old.push(".");
611                                 else
612                                         old.push("->");
613                                 old.push(current_expression.expression);
614                                 current_expression = old;
615                         }
616                                 break;
617                         case 4: // ++
618                         case 5: // --
619                                 /* skip */
620                                 break;
621                         default:
622                                 throw new Error("Oops!");
623                         }
624                 }
625         }
626
627         public void visit(PrimaryExpression n) {
628                 if (n.f0.which == 2) {
629                         ExpressionBuilder old = current_expression;
630                         current_expression = new ExpressionBuilder();
631                         NodeSequence ns = (NodeSequence) n.f0.choice;
632                         ns.elementAt(1).accept(this);
633                         old.push("(");
634                         old.push(current_expression.expression);
635                         old.push(")");
636                         LineNumberInfo lin = LineNumberInfo.get(n);
637                         old.commit(lin.lineEnd);
638                         current_expression = old;
639                 } else
640                         n.f0.accept(this);
641         }
642
643         public void visit(ArgumentExpressionList n) {
644                 ExpressionBuilder old = current_expression;
645                 current_expression = new ExpressionBuilder();
646                 n.f0.accept(this);
647                 old.push(current_expression.expression);
648                 for (int i = 0; i < n.f1.size(); i++) {
649                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
650                         current_expression = new ExpressionBuilder();
651                         ns.elementAt(1).accept(this);
652                         old.push(",");
653                         old.push(current_expression.expression);
654                 }
655                 current_expression = old;
656         }
657
658 }