59afc51cecd993664f58cd3b666f9b06110d01f0
[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                         operator = true;
484                         NodeSequence ns = (NodeSequence) n.f1.node;
485                         ns.nodes.get(0).accept(this);
486                         operator = false;
487                         ns.nodes.get(1).accept(this);
488                 }
489                 old.push(current_expression.expression);
490                 current_expression = old;
491         }
492
493         public void visit(ShiftExpression n) {
494                 assert skip_mode == false;
495                 ExpressionBuilder old = current_expression;
496                 current_expression = new ExpressionBuilder();
497                 n.f0.accept(this);
498                 if (n.f1.present()) {
499                         operator = true;
500                         NodeSequence ns = (NodeSequence) n.f1.node;
501                         ns.nodes.get(0).accept(this);
502                         operator = false;
503                         ns.nodes.get(1).accept(this);
504                 }
505                 old.push(current_expression.expression);
506                 current_expression = old;
507         }
508
509         public void visit(AdditiveExpression n) {
510                 assert skip_mode == false;
511                 ExpressionBuilder old = current_expression;
512                 current_expression = new ExpressionBuilder();
513                 n.f0.accept(this);
514                 if (n.f1.present()) {
515                         operator = true;
516                         NodeSequence ns = (NodeSequence) n.f1.node;
517                         ns.nodes.get(0).accept(this);
518                         operator = false;
519                         ns.nodes.get(1).accept(this);
520                 }
521                 old.push(current_expression.expression);
522                 current_expression = old;
523         }
524
525         public void visit(MultiplicativeExpression n) {
526                 assert skip_mode == false;
527                 ExpressionBuilder old = current_expression;
528                 current_expression = new ExpressionBuilder();
529                 n.f0.accept(this);
530                 if (n.f1.present()) {
531                         operator = true;
532                         NodeSequence ns = (NodeSequence) n.f1.node;
533                         ns.nodes.get(0).accept(this);
534                         operator = false;
535                         ns.nodes.get(1).accept(this);
536                 }
537                 old.push(current_expression.expression);
538                 current_expression = old;
539         }
540
541         public void visit(CastExpression n) {
542                 if (n.f0.which == 1) {
543                         n.f0.accept(this);
544                         return;
545                 }
546                 NodeSequence ns = (NodeSequence) n.f0.choice;
547                 ns.nodes.get(3).accept(this);
548         }
549
550         public void visit(UnaryExpression n) {
551                 if ((n.f0.which == 1) || (n.f0.which == 2)) {
552                         NodeSequence ns = (NodeSequence) n.f0.choice;
553                         ns.nodes.get(1).accept(this);
554                 } else
555                         n.f0.accept(this);
556
557         }
558
559         public void visit(UnaryOperator n) {
560                 operator = true;
561                 n.f0.accept(this);
562                 operator = false;
563         }
564
565         public void visit(PostfixExpression n) {
566                 n.f0.accept(this);
567                 for (int i = 0; i < n.f1.size(); i++) {
568                         NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
569                         switch (nc.which) {
570                         case 0: // []
571                         {
572                                 ExpressionBuilder old = current_expression;
573                                 current_expression = new ExpressionBuilder();
574                                 NodeSequence ns = (NodeSequence) nc.choice;
575                                 ns.elementAt(1).accept(this);
576                                 LineNumberInfo lin = LineNumberInfo.get(n);
577                                 current_expression.commit(lin.colEnd);
578                                 old.push("[");
579                                 old.push(current_expression.expression);
580                                 old.push("]");
581                                 current_expression = old;
582                         }
583                         case 1: // ()
584                         {
585                                 ExpressionBuilder old = current_expression;
586                                 current_expression = new ExpressionBuilder();
587                                 NodeSequence ns = (NodeSequence) nc.choice;
588                                 ns.elementAt(1).accept(this);
589                                 old.push("(");
590                                 old.push(current_expression.expression);
591                                 old.push(")");
592                                 current_expression = old;
593                         }
594                                 break;
595                         case 2: // .
596                         case 3: // ->
597                         {
598                                 ExpressionBuilder old = current_expression;
599                                 LineNumberInfo lin = LineNumberInfo.get(n);
600                                 old.commit(lin.lineEnd);
601                                 current_expression = new ExpressionBuilder();
602                                 NodeSequence ns = (NodeSequence) nc.choice;
603                                 ns.elementAt(1).accept(this);
604                                 if (nc.which == 2)
605                                         old.push(".");
606                                 else
607                                         old.push("->");
608                                 old.push(current_expression.expression);
609                                 current_expression = old;
610                         }
611                                 break;
612                         case 4: // ++
613                         case 5: // --
614                                 /* skip */
615                                 break;
616                         default:
617                                 throw new Error("Oops!");
618                         }
619                 }
620         }
621
622         public void visit(PrimaryExpression n) {
623                 if (n.f0.which == 2) {
624                         ExpressionBuilder old = current_expression;
625                         current_expression = new ExpressionBuilder();
626                         NodeSequence ns = (NodeSequence) n.f0.choice;
627                         ns.elementAt(1).accept(this);
628                         old.push("(");
629                         old.push(current_expression.expression);
630                         old.push(")");
631                         LineNumberInfo lin = LineNumberInfo.get(n);
632                         old.commit(lin.lineEnd);
633                         current_expression = old;
634                 } else
635                         n.f0.accept(this);
636         }
637
638         public void visit(ArgumentExpressionList n) {
639                 ExpressionBuilder old = current_expression;
640                 current_expression = new ExpressionBuilder();
641                 n.f0.accept(this);
642                 old.push(current_expression.expression);
643                 for (int i = 0; i < n.f1.size(); i++) {
644                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
645                         current_expression = new ExpressionBuilder();
646                         ns.elementAt(1).accept(this);
647                         old.push(",");
648                         old.push(current_expression.expression);
649                 }
650                 current_expression = old;
651         }
652
653 }