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, InterfaceConstruct> CPLabel2InterfaceConstruct;
33 public final HashMap<String, Integer> interface2Num;
34 public final HashMap<Integer, String> num2Interface;
35 public final HashMap<String, Integer> hbLabel2Num;
36 public final HashMap<Integer, String> num2HBLabel;
37 public final HashMap<String, Integer> commitPointLabel2Num;
38 public final HashMap<Integer, String> num2CommitPointLabel;
40 private HashMap<String, String> options;
41 private HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbConditions;
42 private ArrayList<EntryPointConstruct> entryPointConstructs;
43 private ClassBeginConstruct classBeginConstruct;
44 private ClassEndConstruct classEndConstruct;
45 private GlobalConstruct globalConstruct;
47 private String templateStr;
48 private String templateFullStr;
49 private String className;
51 private int _interfaceNum;
52 private int _hbLabelNum;
53 private int _commitPointNum;
55 public SemanticsChecker(SpecExtractor extractor) {
56 this.srcFilesInfo = extractor.srcFilesInfo;
57 this.constructs = extractor.getConstructs();
58 this.CPLabel2Construct = new HashMap<String, Construct>();
59 this.potentialCPLabel2Construct = new HashMap<String, PotentialCPDefineConstruct>();
60 this.interfaceName2Construct = new HashMap<String, InterfaceConstruct>();
61 this.interfaceName2DefineConstruct = new HashMap<String, InterfaceDefineConstruct>();
62 this.CPLabel2InterfaceConstruct = new HashMap<String, InterfaceConstruct>();
63 this.entryPointConstructs = new ArrayList<EntryPointConstruct>();
64 this.classBeginConstruct = null;
65 this.classEndConstruct = null;
67 this.interface2Num = new HashMap<String, Integer>();
68 this.num2Interface = new HashMap<Integer, String>();
69 this.hbLabel2Num = new HashMap<String, Integer>();
70 this.num2HBLabel = new HashMap<Integer, String>();
71 // Immediately init the true HB-condition to be 0
72 hbLabel2Num.put("", 0);
73 num2HBLabel.put(0, "");
75 this.commitPointLabel2Num = new HashMap<String, Integer>();
76 this.num2CommitPointLabel = new HashMap<Integer, String>();
83 templateFullStr = null;
87 public ClassBeginConstruct getClassBeginConstruct() {
88 return this.classBeginConstruct;
91 public ClassEndConstruct getClassEndConstruct() {
92 return this.classEndConstruct;
95 public String getTemplateFullStr() {
96 return this.templateFullStr;
99 public String getTemplateStr() {
100 return this.templateStr;
103 public String getClassName() {
104 return this.className;
107 public GlobalConstruct getGlobalConstruct() {
108 return this.globalConstruct;
111 public HashMap<ConditionalInterface, HashSet<ConditionalInterface>> getHBConditions() {
112 return this.hbConditions;
116 * Check if the conditional interface is in the HB checking list
118 * @param condInterface
121 public boolean containsConditionalInterface(
122 ConditionalInterface condInterface) {
123 if (hbConditions.containsKey(condInterface))
125 for (ConditionalInterface key : hbConditions.keySet()) {
126 if (hbConditions.get(key).contains(condInterface))
132 public String getOption(String key) {
133 return options.get(key);
136 private void checkHBLabelConsistency(ConditionalInterface inst)
137 throws SemanticsCheckerException {
138 String interfaceName = inst.interfaceName, label = inst.hbConditionLabel;
139 if (!interfaceName2Construct.containsKey(interfaceName)) {
140 throw new SemanticsCheckerException(
141 "In global construct, no interface \"" + interfaceName
143 } else if (!label.equals("")) {
144 InterfaceConstruct iConstruct = (InterfaceConstruct) interfaceName2Construct
146 if (!iConstruct.hbConditions.containsKey(label)) {
147 throw new SemanticsCheckerException("Interface "
148 + interfaceName + " doesn't contain HB_codition: "
152 // Number the HB-condition label
153 hbLabel2Num.put(label, _hbLabelNum++);
154 num2HBLabel.put(_hbLabelNum, label);
158 private void checkLabelDuplication(Construct construct, String label)
159 throws SemanticsCheckerException {
160 if (potentialCPLabel2Construct.containsKey(label)
161 || CPLabel2Construct.containsKey(label))
162 throw new SemanticsCheckerException("In construct: " + construct
163 + "\"" + label + "\" has duplication.");
166 private void checkOptions() throws SemanticsCheckerException {
167 // FIXME: We don't have any check here
170 private void postCheck() throws SemanticsCheckerException {
171 // C++ data structure with Class must provide the beginning and ending
172 // of its declaration
173 if (getOption("Class") != null) {
174 if (classBeginConstruct == null || classEndConstruct == null) {
175 throw new SemanticsCheckerException(
176 "Class must provide the boundary explicitly!");
179 // It must provide the entry point
180 if (entryPointConstructs.size() == 0) {
181 throw new SemanticsCheckerException(
182 "The program must have at least one entry point!");
185 // Check if interface define construct labels are correct
186 for (String name : interfaceName2DefineConstruct.keySet()) {
187 if (!interfaceName2Construct.containsKey(name)) {
188 throw new SemanticsCheckerException("Label \"" + name
189 + "\" does not have interface declaration!");
194 public void check() throws SemanticsCheckerException {
195 boolean hasGlobalConstruct = false;
196 // First grab the information from the interface
197 for (int i = 0; i < constructs.size(); i++) {
198 Construct inst = constructs.get(i);
199 if (inst instanceof InterfaceConstruct) {
200 InterfaceConstruct iConstruct = (InterfaceConstruct) inst;
201 if (interfaceName2Construct.containsKey(iConstruct.name)) {
202 throw new SemanticsCheckerException("Interface name: "
203 + iConstruct.name + " duplicates!");
205 // Number the interface label
206 interface2Num.put(iConstruct.name, _interfaceNum++);
207 num2Interface.put(_interfaceNum, iConstruct.name);
209 interfaceName2Construct.put(iConstruct.name,
210 (InterfaceConstruct) constructs.get(i));
212 for (int j = 0; j < iConstruct.commitPointSet.size(); j++) {
213 String label = iConstruct.commitPointSet.get(j);
214 // if (!CPLabel2InterfaceConstruct.containsKey(label)) {
215 // CPLabel2InterfaceConstruct.put(label,
216 // new ArrayList<InterfaceConstruct>());
218 // CPLabel2InterfaceConstruct.get(label).add(iConstruct);
219 if (!CPLabel2InterfaceConstruct.containsKey(label)) {
220 CPLabel2InterfaceConstruct.put(label, iConstruct);
222 throw new SemanticsCheckerException(
223 "Commit point has multiple interfaces!");
231 for (int i = 0; i < constructs.size(); i++) {
232 Construct construct = constructs.get(i);
233 if (construct instanceof GlobalConstruct) {
234 GlobalConstruct theConstruct = (GlobalConstruct) construct;
235 globalConstruct = theConstruct;
236 if (!hasGlobalConstruct)
237 hasGlobalConstruct = true;
239 throw new SemanticsCheckerException(
240 "More than one global construct!");
242 // Record the options and check them
243 options = theConstruct.options;
245 // Record the HB conditions and check it
246 hbConditions = theConstruct.hbRelations;
247 for (ConditionalInterface left : hbConditions.keySet()) {
248 HashSet<ConditionalInterface> set = hbConditions.get(left);
249 checkHBLabelConsistency(left);
251 for (ConditionalInterface right : set) {
252 checkHBLabelConsistency(right);
255 } else if (construct instanceof PotentialCPDefineConstruct) {
256 PotentialCPDefineConstruct theConstruct = (PotentialCPDefineConstruct) construct;
257 label = theConstruct.label;
258 checkLabelDuplication(construct, label);
259 // Number the commit point potential commit point label
260 commitPointLabel2Num.put(label, _commitPointNum++);
261 num2CommitPointLabel.put(_commitPointNum, label);
263 potentialCPLabel2Construct.put(label,
264 (PotentialCPDefineConstruct) construct);
265 } else if (construct instanceof CPDefineCheckConstruct) {
266 CPDefineCheckConstruct theConstruct = (CPDefineCheckConstruct) construct;
267 label = theConstruct.label;
268 checkLabelDuplication(construct, label);
269 // Number the commit point define check label
270 commitPointLabel2Num.put(label, _commitPointNum++);
271 num2CommitPointLabel.put(_commitPointNum, label);
273 CPLabel2Construct.put(label, construct);
274 } else if (construct instanceof CPDefineConstruct) {
275 CPDefineConstruct theConstruct = (CPDefineConstruct) construct;
276 label = theConstruct.label;
277 checkLabelDuplication(construct, label);
278 // Number the commit point define label
279 commitPointLabel2Num.put(label, _commitPointNum++);
280 num2CommitPointLabel.put(_commitPointNum, label);
282 CPLabel2Construct.put(label, construct);
283 } else if (construct instanceof EntryPointConstruct) {
284 entryPointConstructs.add((EntryPointConstruct) construct);
285 } else if (construct instanceof InterfaceDefineConstruct) {
286 InterfaceDefineConstruct theConstruct = (InterfaceDefineConstruct) construct;
287 String name = theConstruct.name;
288 if (interfaceName2DefineConstruct.containsKey(name)) {
289 throw new SemanticsCheckerException(
290 "Interface define label duplicates!");
292 interfaceName2DefineConstruct.put(name, theConstruct);
293 } else if (construct instanceof ClassBeginConstruct) {
294 classBeginConstruct = (ClassBeginConstruct) construct;
295 ArrayList<String> content = srcFilesInfo
296 .get(classBeginConstruct.file).content;
297 String firstLine = content
298 .get(classBeginConstruct.beginLineNum + 1), secondLine;
299 if (firstLine.startsWith("template")) {
301 .get(classBeginConstruct.beginLineNum + 1);
302 templateFullStr = firstLine;
303 templateStr = ParserUtils.getTemplateStr(firstLine);
304 className = ParserUtils.getClassName(secondLine);
306 className = ParserUtils.getClassName(firstLine);
309 } else if (construct instanceof ClassEndConstruct) {
310 classEndConstruct = (ClassEndConstruct) construct;
311 className = getOption("CLASS");
316 public String toString() {
317 StringBuilder sb = new StringBuilder();
319 sb.append("Interface name 2 Construct:\n");
320 for (String interfaceName : interfaceName2Construct.keySet()) {
321 sb.append(interfaceName + "\t"
322 + interfaceName2Construct.get(interfaceName) + "\n");
325 sb.append("Interface name 2 define construct:\n");
326 for (String interfaceName : interfaceName2DefineConstruct.keySet()) {
327 sb.append(interfaceName + "\t"
328 + interfaceName2DefineConstruct.get(interfaceName) + "\n");
331 sb.append("Potential commit point label 2 Construct:\n");
332 for (String label : potentialCPLabel2Construct.keySet()) {
333 sb.append(label + "\t" + potentialCPLabel2Construct.get(label)
337 sb.append("Commit point label 2 Construct:\n");
338 for (String label : CPLabel2Construct.keySet()) {
339 sb.append(label + "\t" + CPLabel2Construct.get(label) + "\n");
341 return sb.toString();