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