1 package org.gnunet.seaspider;
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.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;
52 public class ExpressionExtractorVisitor extends DepthFirstVisitor {
54 class ExpressionBuilder {
55 String expression = "";
57 void push(String token) {
58 expression = expression + token;
61 void commit(int line) {
62 ExpressionDatabaseHandler.insertIntoExpressionTable(filename,
63 expression, line, scope_end_line);
68 final String filename;
70 ExpressionBuilder current_expression;
76 boolean skip_mode = true;
81 public ExpressionExtractorVisitor(String filename) {
82 this.filename = filename;
85 public void visit(TranslationUnit n) {
86 LineNumberInfo lin = LineNumberInfo.get(n);
87 scope_end_line = lin.lineEnd;
89 assert scope_end_line == lin.lineEnd;
92 public void visit(NodeToken n) {
95 current_expression.push(n.tokenImage);
98 public void visit(StructOrUnionSpecifier n) {
99 // do nothing -- skip!
102 public void visit(TypeDeclaration n) {
103 // do nothing -- skip!
106 public void visit(InitDeclaratorList n) {
107 assert skip_mode == true;
109 assert skip_mode == true;
112 public void visit(Initializer n) {
113 assert skip_mode == true;
115 assert skip_mode == true;
118 public void visit(InitializerList n) {
119 assert skip_mode == true;
121 assert skip_mode == true;
124 public void visit(VariableDeclaration n) {
125 assert skip_mode == true;
129 public void visit(FunctionDeclaration n) {
132 int old_scope = scope_end_line;
133 LineNumberInfo lin = LineNumberInfo.get(n);
134 scope_end_line = lin.lineEnd;
137 assert scope_end_line == lin.lineEnd;
138 scope_end_line = old_scope;
141 public void visit(ParameterDeclaration n) {
143 assert current_expression == null;
144 current_expression = new ExpressionBuilder();
146 LineNumberInfo lin = LineNumberInfo.get(n);
147 current_expression.commit(lin.lineEnd);
148 current_expression = null;
152 public void visit(InitDeclarator n) {
154 assert current_expression == null;
155 current_expression = new ExpressionBuilder();
157 current_expression = null;
162 public void visit(ExpressionStatement n) {
165 assert current_expression == null;
167 current_expression = new ExpressionBuilder();
169 LineNumberInfo lin = LineNumberInfo.get(n);
170 current_expression.commit(lin.lineEnd);
171 current_expression = null;
175 public void visit(CompoundStatement n) {
176 assert current_expression == null;
177 assert skip_mode == true;
178 int old_end = scope_end_line;
179 scope_end_line = n.f2.endLine;
181 scope_end_line = old_end;
184 public void visit(SwitchStatement n) {
185 assert current_expression == null;
187 current_expression = new ExpressionBuilder();
189 current_expression.commit(n.f0.endLine);
191 current_expression = null;
195 public void visit(IfStatement n) {
196 assert current_expression == null;
198 current_expression = new ExpressionBuilder();
200 current_expression.commit(n.f0.endLine);
202 current_expression = null;
207 public void visit(WhileStatement n) {
208 assert current_expression == null;
210 current_expression = new ExpressionBuilder();
212 current_expression.commit(n.f0.endLine);
214 current_expression = null;
218 public void visit(DoWhileStatement n) {
219 assert current_expression == null;
221 current_expression = new ExpressionBuilder();
223 current_expression.commit(n.f6.endLine);
225 current_expression = null;
229 public void visit(ForStatement n) {
230 assert current_expression == null;
232 int old_scope = scope_end_line;
233 LineNumberInfo lin = LineNumberInfo.get(n);
234 scope_end_line = lin.lineEnd;
235 if (n.f2.present()) {
236 current_expression = new ExpressionBuilder();
238 current_expression.commit(n.f3.endLine);
240 if (n.f4.present()) {
241 current_expression = new ExpressionBuilder();
243 current_expression.commit(n.f5.endLine);
245 if (n.f6.present()) {
246 current_expression = new ExpressionBuilder();
248 current_expression.commit(n.f7.endLine);
251 current_expression = null;
253 scope_end_line = old_scope;
256 public void visit(JumpStatement n) {
259 NodeSequence ns = (NodeSequence) n.f0.choice;
260 assert current_expression == null;
262 current_expression = new ExpressionBuilder();
263 ns.elementAt(1).accept(this);
264 LineNumberInfo lin = LineNumberInfo.get(n);
265 current_expression.commit(lin.lineEnd);
266 current_expression = null;
270 public void visit(Expression n) {
271 ExpressionBuilder old = current_expression;
272 current_expression = new ExpressionBuilder();
274 for (int i = 0; i < n.f1.size(); i++) {
275 NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
276 current_expression = new ExpressionBuilder();
277 ns.elementAt(1).accept(this);
279 old.push(current_expression.expression);
280 current_expression = old;
283 public void visit(AssignmentExpression n) {
284 boolean old_mode = skip_mode;
286 ExpressionBuilder old = current_expression;
287 current_expression = new ExpressionBuilder();
290 old.push(current_expression.expression);
291 LineNumberInfo lin = LineNumberInfo.get(n);
292 old.commit(lin.lineEnd);
294 current_expression = old;
295 skip_mode = old_mode;
298 public void visit(AssignmentOperator n) {
304 public void visit(ConditionalExpression n) {
305 ExpressionBuilder old = current_expression;
306 current_expression = new ExpressionBuilder();
308 old.push(current_expression.expression);
309 if (n.f1.present()) {
310 NodeSequence ns = (NodeSequence) n.f1.node;
311 current_expression = new ExpressionBuilder();
312 ns.elementAt(1).accept(this);
314 old.push(current_expression.expression);
315 current_expression = new ExpressionBuilder();
316 ns.elementAt(3).accept(this);
318 old.push(current_expression.expression);
319 LineNumberInfo lin = LineNumberInfo.get(n);
320 old.commit(lin.lineEnd);
322 current_expression = old;
325 public void visit(ConstantExpression n) {
329 public void visit(LogicalORExpression n) {
330 assert skip_mode == false;
331 ExpressionBuilder old = current_expression;
332 current_expression = new ExpressionBuilder();
334 if (n.f1.present()) {
336 NodeSequence ns = (NodeSequence) n.f1.node;
337 ns.nodes.get(0).accept(this);
339 ns.nodes.get(1).accept(this);
341 old.push(current_expression.expression);
342 current_expression = old;
345 public void visit(LogicalANDExpression n) {
346 assert skip_mode == false;
347 ExpressionBuilder old = current_expression;
348 current_expression = new ExpressionBuilder();
350 if (n.f1.present()) {
352 NodeSequence ns = (NodeSequence) n.f1.node;
353 ns.nodes.get(0).accept(this);
355 ns.nodes.get(1).accept(this);
357 old.push(current_expression.expression);
358 current_expression = old;
361 public void visit(InclusiveORExpression n) {
362 assert skip_mode == false;
363 ExpressionBuilder old = current_expression;
364 current_expression = new ExpressionBuilder();
366 if (n.f1.present()) {
368 NodeSequence ns = (NodeSequence) n.f1.node;
369 ns.nodes.get(0).accept(this);
371 ns.nodes.get(1).accept(this);
373 old.push(current_expression.expression);
374 current_expression = old;
377 public void visit(ExclusiveORExpression n) {
378 assert skip_mode == false;
379 ExpressionBuilder old = current_expression;
380 current_expression = new ExpressionBuilder();
382 if (n.f1.present()) {
384 NodeSequence ns = (NodeSequence) n.f1.node;
385 ns.nodes.get(0).accept(this);
387 ns.nodes.get(1).accept(this);
389 old.push(current_expression.expression);
390 current_expression = old;
393 public void visit(ANDExpression n) {
394 assert skip_mode == false;
395 ExpressionBuilder old = current_expression;
396 current_expression = new ExpressionBuilder();
398 if (n.f1.present()) {
400 NodeSequence ns = (NodeSequence) n.f1.node;
401 ns.nodes.get(0).accept(this);
403 ns.nodes.get(1).accept(this);
405 old.push(current_expression.expression);
406 current_expression = old;
409 // Safey: this function was fixed to commit the right hand side, the
410 // other similar functions still need to be updated accordingly...
411 public void visit(EqualityExpression n) {
412 assert skip_mode == false;
413 ExpressionBuilder old = current_expression;
414 current_expression = new ExpressionBuilder();
416 if (n.f1.present()) {
417 LineNumberInfo lin = LineNumberInfo.get(n);
418 current_expression.commit(lin.lineEnd);
420 NodeSequence ns = (NodeSequence) n.f1.node;
421 ns.nodes.get(0).accept(this);
423 old.push(current_expression.expression);
424 current_expression = new ExpressionBuilder();
425 ns.nodes.get(1).accept(this);
426 current_expression.commit(lin.lineEnd);
428 old.push(current_expression.expression);
429 current_expression = old;
432 public void visit(RelationalExpression n) {
433 assert skip_mode == false;
434 ExpressionBuilder old = current_expression;
435 current_expression = new ExpressionBuilder();
437 if (n.f1.present()) {
439 NodeSequence ns = (NodeSequence) n.f1.node;
440 ns.nodes.get(0).accept(this);
442 ns.nodes.get(1).accept(this);
444 old.push(current_expression.expression);
445 current_expression = old;
448 public void visit(ShiftExpression n) {
449 assert skip_mode == false;
450 ExpressionBuilder old = current_expression;
451 current_expression = new ExpressionBuilder();
453 if (n.f1.present()) {
455 NodeSequence ns = (NodeSequence) n.f1.node;
456 ns.nodes.get(0).accept(this);
458 ns.nodes.get(1).accept(this);
460 old.push(current_expression.expression);
461 current_expression = old;
464 public void visit(AdditiveExpression n) {
465 assert skip_mode == false;
466 ExpressionBuilder old = current_expression;
467 current_expression = new ExpressionBuilder();
469 if (n.f1.present()) {
471 NodeSequence ns = (NodeSequence) n.f1.node;
472 ns.nodes.get(0).accept(this);
474 ns.nodes.get(1).accept(this);
476 old.push(current_expression.expression);
477 current_expression = old;
480 public void visit(MultiplicativeExpression n) {
481 assert skip_mode == false;
482 ExpressionBuilder old = current_expression;
483 current_expression = new ExpressionBuilder();
485 if (n.f1.present()) {
487 NodeSequence ns = (NodeSequence) n.f1.node;
488 ns.nodes.get(0).accept(this);
490 ns.nodes.get(1).accept(this);
492 old.push(current_expression.expression);
493 current_expression = old;
496 public void visit(CastExpression n) {
497 if (n.f0.which == 1) {
501 NodeSequence ns = (NodeSequence) n.f0.choice;
502 ns.nodes.get(3).accept(this);
505 public void visit(UnaryExpression n) {
506 if ((n.f0.which == 1) || (n.f0.which == 2)) {
507 NodeSequence ns = (NodeSequence) n.f0.choice;
508 ns.nodes.get(1).accept(this);
514 public void visit(UnaryOperator n) {
520 public void visit(PostfixExpression n) {
522 for (int i = 0; i < n.f1.size(); i++) {
523 NodeChoice nc = (NodeChoice) n.f1.elementAt(i);
527 ExpressionBuilder old = current_expression;
528 current_expression = new ExpressionBuilder();
529 NodeSequence ns = (NodeSequence) nc.choice;
530 ns.elementAt(1).accept(this);
531 LineNumberInfo lin = LineNumberInfo.get(n);
532 current_expression.commit(lin.colEnd);
534 old.push(current_expression.expression);
536 current_expression = old;
540 ExpressionBuilder old = current_expression;
541 current_expression = new ExpressionBuilder();
542 NodeSequence ns = (NodeSequence) nc.choice;
543 ns.elementAt(1).accept(this);
545 old.push(current_expression.expression);
547 current_expression = old;
553 ExpressionBuilder old = current_expression;
554 LineNumberInfo lin = LineNumberInfo.get(n);
555 old.commit(lin.lineEnd);
556 current_expression = new ExpressionBuilder();
557 NodeSequence ns = (NodeSequence) nc.choice;
558 ns.elementAt(1).accept(this);
563 old.push(current_expression.expression);
564 current_expression = old;
572 throw new Error("Oops!");
577 public void visit(PrimaryExpression n) {
578 if (n.f0.which == 2) {
579 ExpressionBuilder old = current_expression;
580 current_expression = new ExpressionBuilder();
581 NodeSequence ns = (NodeSequence) n.f0.choice;
582 ns.elementAt(1).accept(this);
584 old.push(current_expression.expression);
586 LineNumberInfo lin = LineNumberInfo.get(n);
587 old.commit(lin.lineEnd);
588 current_expression = old;
593 public void visit(ArgumentExpressionList n) {
594 ExpressionBuilder old = current_expression;
595 current_expression = new ExpressionBuilder();
597 old.push(current_expression.expression);
598 for (int i = 0; i < n.f1.size(); i++) {
599 NodeSequence ns = (NodeSequence) n.f1.elementAt(i);
600 current_expression = new ExpressionBuilder();
601 ns.elementAt(1).accept(this);
603 old.push(current_expression.expression);
605 current_expression = old;