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