06643fdbd04b93ef6529269d22416b8ff53ef03a
[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                         operator = true;
415                         NodeSequence ns = (NodeSequence) n.f1.node;
416                         ns.nodes.get(0).accept(this);
417                         operator = false;
418                         ns.nodes.get(1).accept(this);
419                 }
420                 old.push(current_expression.expression);
421                 current_expression = old;
422         }
423
424         public void visit(ExclusiveORExpression n) {
425                 assert skip_mode == false;
426                 ExpressionBuilder old = current_expression;
427                 current_expression = new ExpressionBuilder();
428                 n.f0.accept(this);
429                 if (n.f1.present()) {
430                         operator = true;
431                         NodeSequence ns = (NodeSequence) n.f1.node;
432                         ns.nodes.get(0).accept(this);
433                         operator = false;
434                         ns.nodes.get(1).accept(this);
435                 }
436                 old.push(current_expression.expression);
437                 current_expression = old;
438         }
439
440         public void visit(ANDExpression n) {
441                 assert skip_mode == false;
442                 ExpressionBuilder old = current_expression;
443                 current_expression = new ExpressionBuilder();
444                 n.f0.accept(this);
445                 if (n.f1.present()) {
446                         operator = true;
447                         NodeSequence ns = (NodeSequence) n.f1.node;
448                         ns.nodes.get(0).accept(this);
449                         operator = false;
450                         ns.nodes.get(1).accept(this);
451                 }
452                 old.push(current_expression.expression);
453                 current_expression = old;
454         }
455
456         // Safey: this function was fixed to commit the right hand side, the
457         // other similar functions still need to be updated accordingly...
458         public void visit(EqualityExpression n) {
459                 assert skip_mode == false;
460                 ExpressionBuilder old = current_expression;
461                 current_expression = new ExpressionBuilder();
462                 n.f0.accept(this);
463                 if (n.f1.present()) {
464                         LineNumberInfo lin = LineNumberInfo.get(n);
465                         current_expression.commit(lin.lineEnd);
466                         operator = true;
467                         NodeSequence ns = (NodeSequence) n.f1.node;
468                         ns.nodes.get(0).accept(this);
469                         operator = false;
470                         old.push(current_expression.expression);
471                         current_expression = new ExpressionBuilder();
472                         ns.nodes.get(1).accept(this);
473                         current_expression.commit(lin.lineEnd);
474                 }
475                 old.push(current_expression.expression);
476                 current_expression = old;
477         }
478
479         public void visit(RelationalExpression n) {
480                 assert skip_mode == false;
481                 ExpressionBuilder old = current_expression;
482                 current_expression = new ExpressionBuilder();
483                 n.f0.accept(this);
484                 if (n.f1.present()) {
485                         LineNumberInfo lin = LineNumberInfo.get(n);
486                         current_expression.commit(lin.lineEnd);
487                         operator = true;
488                         NodeSequence ns = (NodeSequence) n.f1.node;
489                         ns.nodes.get(0).accept(this);
490                         operator = false;
491                         old.push(current_expression.expression);
492                         current_expression = new ExpressionBuilder();
493                         ns.nodes.get(1).accept(this);
494                         current_expression.commit(lin.lineEnd);
495                 }
496                 old.push(current_expression.expression);
497                 current_expression = old;
498         }
499
500         public void visit(ShiftExpression n) {
501                 assert skip_mode == false;
502                 ExpressionBuilder old = current_expression;
503                 current_expression = new ExpressionBuilder();
504                 n.f0.accept(this);
505                 if (n.f1.present()) {
506                         operator = true;
507                         NodeSequence ns = (NodeSequence) n.f1.node;
508                         ns.nodes.get(0).accept(this);
509                         operator = false;
510                         ns.nodes.get(1).accept(this);
511                 }
512                 old.push(current_expression.expression);
513                 current_expression = old;
514         }
515
516         public void visit(AdditiveExpression n) {
517                 assert skip_mode == false;
518                 ExpressionBuilder old = current_expression;
519                 current_expression = new ExpressionBuilder();
520                 n.f0.accept(this);
521                 if (n.f1.present()) {
522                         operator = true;
523                         NodeSequence ns = (NodeSequence) n.f1.node;
524                         ns.nodes.get(0).accept(this);
525                         operator = false;
526                         ns.nodes.get(1).accept(this);
527                 }
528                 old.push(current_expression.expression);
529                 current_expression = old;
530         }
531
532         public void visit(MultiplicativeExpression n) {
533                 assert skip_mode == false;
534                 ExpressionBuilder old = current_expression;
535                 current_expression = new ExpressionBuilder();
536                 n.f0.accept(this);
537                 if (n.f1.present()) {
538                         operator = true;
539                         NodeSequence ns = (NodeSequence) n.f1.node;
540                         ns.nodes.get(0).accept(this);
541                         operator = false;
542                         ns.nodes.get(1).accept(this);
543                 }
544                 old.push(current_expression.expression);
545                 current_expression = old;
546         }
547
548         public void visit(CastExpression n) {
549                 if (n.f0.which == 1) {
550                         n.f0.accept(this);
551                         return;
552                 }
553                 NodeSequence ns = (NodeSequence) n.f0.choice;
554                 ns.nodes.get(3).accept(this);
555         }
556
557         public void visit(UnaryExpression n) {
558                 if ((n.f0.which == 1) || (n.f0.which == 2)) {
559                         NodeSequence ns = (NodeSequence) n.f0.choice;
560                         ns.nodes.get(1).accept(this);
561                 } else
562                         n.f0.accept(this);
563
564         }
565
566         public void visit(UnaryOperator n) {
567                 operator = true;
568                 n.f0.accept(this);
569                 operator = false;
570         }
571
572         public void visit(PostfixExpression n) {
573                 n.f0.accept(this);
574                 for (int i = 0; i < n.f1.size(); i++) {
575                         NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
576                         switch (nc.which) {
577                         case 0: // []
578                         {
579                                 ExpressionBuilder old = current_expression;
580                                 current_expression = new ExpressionBuilder();
581                                 NodeSequence ns = (NodeSequence) nc.choice;
582                                 ns.elementAt(1).accept(this);
583                                 LineNumberInfo lin = LineNumberInfo.get(n);
584                                 current_expression.commit(lin.lineEnd);
585                                 old.push("[");
586                                 old.push(current_expression.expression);
587                                 old.push("]");
588                                 current_expression = old;
589                         }
590                         case 1: // ()
591                         {
592                                 ExpressionBuilder old = current_expression;
593                                 current_expression = new ExpressionBuilder();
594                                 NodeSequence ns = (NodeSequence) nc.choice;
595                                 ns.elementAt(1).accept(this);
596                                 LineNumberInfo lin = LineNumberInfo.get (ns.elementAt(1));
597                                 current_expression.commit(lin.lineEnd);
598                                 old.push("(");
599                                 old.push(current_expression.expression);
600                                 old.push(")");
601                                 current_expression = old;
602                         }
603                                 break;
604                         case 2: // .
605                         case 3: // ->
606                         {
607                                 ExpressionBuilder old = current_expression;
608                                 LineNumberInfo lin = LineNumberInfo.get(n);
609                                 old.commit(lin.lineEnd);
610                                 current_expression = new ExpressionBuilder();
611                                 NodeSequence ns = (NodeSequence) nc.choice;
612                                 ns.elementAt(1).accept(this);
613                                 if (nc.which == 2)
614                                         old.push(".");
615                                 else
616                                         old.push("->");
617                                 old.push(current_expression.expression);
618                                 current_expression = old;
619                         }
620                                 break;
621                         case 4: // ++
622                         case 5: // --
623                                 /* skip */
624                                 break;
625                         default:
626                                 throw new Error("Oops!");
627                         }
628                 }
629         }
630
631         public void visit(PrimaryExpression n) {
632                 if (n.f0.which == 2) {
633                         ExpressionBuilder old = current_expression;
634                         current_expression = new ExpressionBuilder();
635                         NodeSequence ns = (NodeSequence) n.f0.choice;
636                         ns.elementAt(1).accept(this);
637                         old.push("(");
638                         old.push(current_expression.expression);
639                         old.push(")");
640                         LineNumberInfo lin = LineNumberInfo.get(n);
641                         old.commit(lin.lineEnd);
642                         current_expression = old;
643                 } else
644                         n.f0.accept(this);
645         }
646
647         public void visit(ArgumentExpressionList n) {
648                 ExpressionBuilder old = current_expression;
649                 current_expression = new ExpressionBuilder();
650                 n.f0.accept(this);
651                 old.push(current_expression.expression);
652                 for (int i = 0; i < n.f1.size(); i++) {
653                         NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
654                         current_expression = new ExpressionBuilder();
655                         ns.elementAt(1).accept(this);
656                         old.push(",");
657                         old.push(current_expression.expression);
658                 }
659                 current_expression = old;
660         }
661
662 }