1 package edu.uci.eecs.specCompiler.codeGenerator;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.HashSet;
8 import edu.uci.eecs.specCompiler.grammerParser.ParseException;
9 import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
10 import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
11 import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
12 import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
13 import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
14 import edu.uci.eecs.specCompiler.specExtraction.Construct;
15 import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
16 import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
17 import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
18 import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
19 import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
20 import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
21 import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
22 import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
24 public class SemanticsChecker {
25 public final HashMap<File, SourceFileInfo> srcFilesInfo;
26 public final ArrayList<Construct> constructs;
27 public final HashMap<String, Construct> CPLabel2Construct;
28 public final HashMap<String, PotentialCPDefineConstruct> potentialCPLabel2Construct;
29 public final HashMap<String, InterfaceConstruct> interfaceName2Construct;
30 public final HashMap<String, InterfaceDefineConstruct> interfaceName2DefineConstruct;
31 public final HashMap<String, ArrayList<InterfaceConstruct>> CPLabel2InterfaceConstruct;
33 public final HashMap<String, Integer> interface2Num;
34 public final HashMap<String, Integer> hbLabel2Num;
35 public final HashMap<String, Integer> commitPointLabel2Num;
37 private HashMap<String, String> options;
38 private HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbConditions;
39 private ArrayList<EntryPointConstruct> entryPointConstructs;
40 private ClassBeginConstruct classBeginConstruct;
41 private ClassEndConstruct classEndConstruct;
42 private GlobalConstruct globalConstruct;
44 private String templateStr;
45 private String templateFullStr;
46 private String className;
48 private int _interfaceNum;
49 private int _hbLabelNum;
50 private int _commitPointNum;
52 public SemanticsChecker(SpecExtractor extractor) {
53 this.srcFilesInfo = extractor.srcFilesInfo;
54 this.constructs = extractor.getConstructs();
55 this.CPLabel2Construct = new HashMap<String, Construct>();
56 this.potentialCPLabel2Construct = new HashMap<String, PotentialCPDefineConstruct>();
57 this.interfaceName2Construct = new HashMap<String, InterfaceConstruct>();
58 this.interfaceName2DefineConstruct = new HashMap<String, InterfaceDefineConstruct>();
59 this.CPLabel2InterfaceConstruct = new HashMap<String, ArrayList<InterfaceConstruct>>();
60 this.entryPointConstructs = new ArrayList<EntryPointConstruct>();
61 this.classBeginConstruct = null;
62 this.classEndConstruct = null;
64 this.interface2Num = new HashMap<String, Integer>();
65 this.hbLabel2Num = new HashMap<String, Integer>();
66 // Immediately init the true HB-condition to be 0
67 hbLabel2Num.put("", 0);
69 this.commitPointLabel2Num = new HashMap<String, Integer>();
76 templateFullStr = null;
80 public ClassBeginConstruct getClassBeginConstruct() {
81 return this.classBeginConstruct;
84 public ClassEndConstruct getClassEndConstruct() {
85 return this.classEndConstruct;
88 public String getTemplateFullStr() {
89 return this.templateFullStr;
92 public String getTemplateStr() {
93 return this.templateStr;
96 public String getClassName() {
97 return this.className;
100 public GlobalConstruct getGlobalConstruct() {
101 return this.globalConstruct;
104 public HashMap<ConditionalInterface, HashSet<ConditionalInterface>> getHBConditions() {
105 return this.hbConditions;
109 * Check if the conditional interface is in the HB checking list
110 * @param condInterface
113 public boolean containsConditionalInterface(ConditionalInterface condInterface) {
114 if (hbConditions.containsKey(condInterface))
116 for (ConditionalInterface key : hbConditions.keySet()) {
117 if (hbConditions.get(key).contains(condInterface))
123 public String getOption(String key) {
124 return options.get(key);
127 private void checkHBLabelConsistency(ConditionalInterface inst)
128 throws SemanticsCheckerException {
129 String interfaceName = inst.interfaceName, label = inst.hbConditionLabel;
130 if (!interfaceName2Construct.containsKey(interfaceName)) {
131 throw new SemanticsCheckerException(
132 "In global construct, no interface \"" + interfaceName
134 } else if (!label.equals("")) {
135 InterfaceConstruct iConstruct = (InterfaceConstruct) interfaceName2Construct
137 if (!iConstruct.hbConditions.containsKey(label)) {
138 throw new SemanticsCheckerException("Interface "
139 + interfaceName + " doesn't contain HB_codition: "
143 // Number the HB-condition label
144 hbLabel2Num.put(label, _hbLabelNum++);
148 private void checkLabelDuplication(Construct construct, String label)
149 throws SemanticsCheckerException {
150 if (potentialCPLabel2Construct.containsKey(label)
151 || CPLabel2Construct.containsKey(label))
152 throw new SemanticsCheckerException("In construct: " + construct
153 + "\"" + label + "\" has duplication.");
156 private void checkOptions() throws SemanticsCheckerException {
157 // FIXME: We don't have any check here
160 private void postCheck() throws SemanticsCheckerException {
161 // C++ data structure with Class must provide the beginning and ending
162 // of its declaration
163 if (getOption("Class") != null) {
164 if (classBeginConstruct == null || classEndConstruct == null) {
165 throw new SemanticsCheckerException(
166 "Class must provide the boundary explicitly!");
169 // It must provide the entry point
170 if (entryPointConstructs.size() == 0) {
171 throw new SemanticsCheckerException(
172 "The program must have at least one entry point!");
175 // Check if interface define construct labels are correct
176 for (String name : interfaceName2DefineConstruct.keySet()) {
177 if (!interfaceName2Construct.containsKey(name)) {
178 throw new SemanticsCheckerException("Label \"" + name
179 + "\" does not have interface declaration!");
184 public void check() throws SemanticsCheckerException {
185 boolean hasGlobalConstruct = false;
186 // First grab the information from the interface
187 for (int i = 0; i < constructs.size(); i++) {
188 Construct inst = constructs.get(i);
189 if (inst instanceof InterfaceConstruct) {
190 InterfaceConstruct iConstruct = (InterfaceConstruct) inst;
191 if (interfaceName2Construct.containsKey(iConstruct.name)) {
192 throw new SemanticsCheckerException("Interface name: "
193 + iConstruct.name + " duplicates!");
195 // Number the interface label
196 interface2Num.put(iConstruct.name, _interfaceNum++);
198 interfaceName2Construct.put(iConstruct.name,
199 (InterfaceConstruct) constructs.get(i));
201 for (int j = 0; j < iConstruct.commitPointSet.size(); j++) {
202 String label = iConstruct.commitPointSet.get(j);
203 if (!CPLabel2InterfaceConstruct.containsKey(label)) {
204 CPLabel2InterfaceConstruct.put(label,
205 new ArrayList<InterfaceConstruct>());
207 CPLabel2InterfaceConstruct.get(label).add(iConstruct);
213 for (int i = 0; i < constructs.size(); i++) {
214 Construct construct = constructs.get(i);
215 if (construct instanceof GlobalConstruct) {
216 GlobalConstruct theConstruct = (GlobalConstruct) construct;
217 globalConstruct = theConstruct;
218 if (!hasGlobalConstruct)
219 hasGlobalConstruct = true;
221 throw new SemanticsCheckerException(
222 "More than one global construct!");
224 // Record the options and check them
225 options = theConstruct.options;
227 // Record the HB conditions and check it
228 hbConditions = theConstruct.hbRelations;
229 for (ConditionalInterface left : hbConditions.keySet()) {
230 HashSet<ConditionalInterface> set = hbConditions.get(left);
231 checkHBLabelConsistency(left);
233 for (ConditionalInterface right : set) {
234 checkHBLabelConsistency(right);
237 } else if (construct instanceof PotentialCPDefineConstruct) {
238 PotentialCPDefineConstruct theConstruct = (PotentialCPDefineConstruct) construct;
239 label = theConstruct.label;
240 checkLabelDuplication(construct, label);
241 // Number the commit_point label
242 commitPointLabel2Num.put(label, _commitPointNum++);
244 potentialCPLabel2Construct.put(label,
245 (PotentialCPDefineConstruct) construct);
246 } else if (construct instanceof CPDefineCheckConstruct) {
247 CPDefineCheckConstruct theConstruct = (CPDefineCheckConstruct) construct;
248 label = theConstruct.label;
249 checkLabelDuplication(construct, label);
250 // Number the commit_point label
251 commitPointLabel2Num.put(label, _commitPointNum++);
253 CPLabel2Construct.put(label, construct);
254 } else if (construct instanceof CPDefineConstruct) {
255 CPDefineConstruct theConstruct = (CPDefineConstruct) construct;
256 label = theConstruct.label;
257 checkLabelDuplication(construct, label);
258 // Number the commit_point label
259 commitPointLabel2Num.put(label, _commitPointNum++);
261 CPLabel2Construct.put(label, construct);
262 } else if (construct instanceof EntryPointConstruct) {
263 entryPointConstructs.add((EntryPointConstruct) construct);
264 } else if (construct instanceof InterfaceDefineConstruct) {
265 InterfaceDefineConstruct theConstruct = (InterfaceDefineConstruct) construct;
266 String name = theConstruct.name;
267 if (interfaceName2DefineConstruct.containsKey(name)) {
268 throw new SemanticsCheckerException(
269 "Interface define label duplicates!");
271 interfaceName2DefineConstruct.put(name, theConstruct);
272 } else if (construct instanceof ClassBeginConstruct) {
273 classBeginConstruct = (ClassBeginConstruct) construct;
274 ArrayList<String> content = srcFilesInfo.get(classBeginConstruct.file).content;
275 String firstLine = content.get(classBeginConstruct.beginLineNum), secondLine;
276 if (firstLine.startsWith("template")) {
277 secondLine = content.get(classBeginConstruct.beginLineNum + 1);
278 templateFullStr = firstLine;
279 templateStr = ParserUtils.getTemplateStr(firstLine);
280 className = ParserUtils.getClassName(secondLine);
282 className = ParserUtils.getClassName(firstLine);
285 } else if (construct instanceof ClassEndConstruct) {
286 classEndConstruct = (ClassEndConstruct) construct;
287 className = getOption("CLASS");
292 public String toString() {
293 StringBuilder sb = new StringBuilder();
295 sb.append("Interface name 2 Construct:\n");
296 for (String interfaceName : interfaceName2Construct.keySet()) {
297 sb.append(interfaceName + "\t"
298 + interfaceName2Construct.get(interfaceName) + "\n");
301 sb.append("Interface name 2 define construct:\n");
302 for (String interfaceName : interfaceName2DefineConstruct.keySet()) {
303 sb.append(interfaceName + "\t"
304 + interfaceName2DefineConstruct.get(interfaceName) + "\n");
307 sb.append("Potential commit point label 2 Construct:\n");
308 for (String label : potentialCPLabel2Construct.keySet()) {
309 sb.append(label + "\t" + potentialCPLabel2Construct.get(label)
313 sb.append("Commit point label 2 Construct:\n");
314 for (String label : CPLabel2Construct.keySet()) {
315 sb.append(label + "\t" + CPLabel2Construct.get(label) + "\n");
317 return sb.toString();