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