001package jtb.cparser.customvisitor;
002
003import jtb.cparser.syntaxtree.*;
004import jtb.cparser.visitor.*;
005import java.util.*;
006import java.io.*;
007
008
009@SuppressWarnings({"rawtypes", "unchecked"})
010public class ConditionPrinter extends DepthFirstVisitor {
011
012    private final Printer printer;
013    private final Converter converter = new Converter();
014    private ArrayList<String> actualStrings;
015    private ArrayList<String> stringArrays;
016    private HashMap<String,ArrayList<String>> actualStringsByFunction;
017    private HashMap<String,ArrayList<String>> stringArraysByFunction;
018    private ArrayList<String> localVariables;
019
020
021    public ConditionPrinter(String fileName) throws IOException {
022        printer = new Printer(fileName);
023    }
024
025    public void close() throws IOException {
026        printer.close();
027    }
028
029    public void setActualStrings(HashMap<String,ArrayList<String>> l) {
030        this.actualStringsByFunction = l;
031    }
032
033    public void setStringArrays(HashMap<String,ArrayList<String>> l) {
034        this.stringArraysByFunction = l;
035    }
036
037
038    // f0 -> [ DeclarationSpecifiers() ]
039    // f1 -> Declarator()
040    // f2 -> [ DeclarationList() ]
041    // f3 -> CompoundStatement()
042
043    @Override
044    public void visit(FunctionDefinition n) {
045        String functionName = n.f1.f1.f0.choice.toString();
046        this.actualStrings = actualStringsByFunction.get(functionName);
047        this.stringArrays = stringArraysByFunction.get(functionName);
048        converter.actualStrings = this.actualStrings;
049        converter.stringArrays = this.stringArrays;
050        printer.println();
051        printer.println();
052        printer.print("PPT_NAME std." + functionName);
053        printer.println();
054        DeclarationList l = (DeclarationList) n.f3.f1.node;
055        localVariables = new ArrayList<String>();
056        localVariables.addAll(actualStringsByFunction.keySet());
057        if (l!=null) {
058            identifyLocalVariables(l.f0.nodes);
059        }
060        super.visit(n);
061    }
062
063
064    private void identifyLocalVariables(Vector v) {
065        for (int i = 0; i < v.size(); i++) {
066            Declaration d = (Declaration) v.elementAt(i);
067            NodeSequence temp = (NodeSequence)d.f0.f0.choice;
068            if (temp.nodes.get(0) instanceof TypeSpecifier) {
069                Node n = ((TypeSpecifier)(temp.nodes.get(0))).f0.choice;
070                if (n instanceof TypedefName) {
071                    TypedefName type = (TypedefName) n;
072                    Vector<Object> decls = new Vector<Object>();
073                    InitDeclaratorList list = (InitDeclaratorList) d.f1.node;
074                    decls.add(list.f0); // get the first in "boolean first, second,third;"
075                    // get the second, third, in "boolean first, second, third"
076                    Vector<Node> tempVec = list.f1.nodes;
077                    for (int k = 0; k < tempVec.size(); k++) {
078                        decls.addAll(((NodeSequence)tempVec.get(k)).nodes);
079                    }
080
081                    for (int j = 0; j < decls.size(); j++) {
082                        InitDeclarator curr=null;;
083                        // filter out the "," node tokens
084                        if (decls.elementAt(j) instanceof InitDeclarator) {
085                            curr = (InitDeclarator) decls.elementAt(j);
086                        }
087                        // if it is a node token, nothing will be printed
088                        if (curr != null) {
089                            localVariables.add((curr.f0.f1.f0.choice).toString().trim());
090                        }
091                    }
092
093                }
094                else {
095                    Vector<Object> decls = new Vector<Object>();
096                    InitDeclaratorList list = (InitDeclaratorList) d.f1.node;
097                    decls.add(list.f0); // get the first in "boolean first, second,third;"
098                    // get the second, third, in "boolean first, second, third"
099                    Vector tempVec = list.f1.nodes;
100                    for (int k = 0; k < tempVec.size(); k++) {
101                        decls.addAll(((NodeSequence)tempVec.get(k)).nodes);
102                    }
103                    for (int j = 0; j < decls.size(); j++) {
104                        InitDeclarator curr=null;;
105                        // filter out the "," node tokens
106                        if (decls.elementAt(j) instanceof InitDeclarator) {
107                            curr = (InitDeclarator) decls.elementAt(j);
108                        }
109                        // if it is a node token, nothing will be printed
110                        if (curr != null) {
111                            localVariables.add(curr.f0.f1.f0.choice.toString().trim());
112                        }
113                    }
114                }
115            }
116        }
117    }
118
119
120
121    @Override
122    public void visit(IterationStatement n) {
123        NodeSequence seq = (NodeSequence)n.f0.choice;
124        String loop = seq.nodes.get(0).toString();
125        if (loop.equals("while")) {
126            printExpression((Expression)seq.nodes.get(2));
127
128        }
129        else if (loop.equals("do")) {
130            printExpression((Expression)seq.nodes.get(4));
131        }
132        else if (loop.equals("for")) {
133            printExpression((Expression)((NodeOptional)seq.nodes.get(4)).node );
134        }
135        n.f0.accept(this);
136    }
137
138    public void printExpression(Expression n) {
139        printer.setFilter(localVariables);
140        n.accept(converter);
141        n.accept(printer);
142        printer.commit();
143    }
144
145
146    private boolean isString(String s) {
147        return actualStrings.contains(s.trim());
148    }
149
150    // f0 -> ( <IF> "(" Expression() ")" Statement() [ <ELSE> Statement() ] | <SWITCH> "(" Expression() ")" Statement() )
151    @Override
152    public void visit(SelectionStatement n) {
153        NodeSequence seq = (NodeSequence) n.f0.choice;
154        if (seq.nodes.get(0).toString().equals("if")) {
155            printExpression(((Expression)seq.nodes.get(2)));
156        }
157        n.f0.accept(this);
158    }
159
160
161    // the following methods check that the nodes not not null before visiting them
162    // because the AST is modified by the Converter to have null pointers
163
164    @Override
165    public void visit(LogicalANDExpression n) {
166        if (n.f0 !=null) {
167            n.f0.accept(this);
168        }
169        n.f1.accept(this);
170    }
171
172    @Override
173    public void visit(LogicalORExpression n) {
174        if (n.f0 !=null) {
175            n.f0.accept(this);
176        }
177        n.f1.accept(this);
178    }
179
180    @Override
181    public void visit(EqualityExpression n) {
182        if (n.f0 != null) {
183            n.f0.accept(this);
184        }
185        n.f1.accept(this);
186    }
187
188    @Override
189    public void visit(RelationalExpression n) {
190        if (n.f0 != null) {
191            n.f0.accept(this);
192        }
193        n.f1.accept(this);
194    }
195}