1 package edu.uci.eecs.specCompiler.specExtraction;
3 import java.io.BufferedReader;
5 import java.io.FileNotFoundException;
6 import java.io.FileReader;
7 import java.io.IOException;
8 import java.io.LineNumberReader;
9 import java.util.ArrayList;
11 import edu.uci.eecs.specCompiler.grammerParser.ParseException;
12 import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
13 import edu.uci.eecs.specCompiler.grammerParser.TokenMgrError;
17 * This class represents the specification extractor of the specification. The
18 * main function of this class is to read C/C++11 source files and extract the
19 * corresponding specification out, and remember its location, including the
20 * file name and the line number, to help the code generation process.
26 public class SpecExtractor {
27 private ArrayList<SpecConstruct> _constructs;
28 private int _beginLineNum, _endLineNum;
29 private String _beginLine;
31 public SpecExtractor() {
32 _constructs = new ArrayList<SpecConstruct>();
37 * Given a list of files, it scans each file and add found SpecConstrcut to
38 * the _constructs list.
42 * @throws SpecNotMatchException
44 public void extract(File[] files) throws SpecNotMatchException {
45 for (int i = 0; i < files.length; i++)
49 public void extract(File file) throws SpecNotMatchException {
50 StringBuilder specText = new StringBuilder();
52 LineNumberReader reader = new LineNumberReader(new FileReader(file));
53 String prevLine = "", curLine, trimedLine, funcDecl;
54 SpecConstruct specConstruct;
55 boolean foundHead = false;
56 while ((curLine = reader.readLine()) != null) {
57 if (prevLine.endsWith("\\"))
59 trimedLine = trimSpace(curLine);
61 if (trimedLine.startsWith("/**")) {
62 _beginLineNum = reader.getLineNumber();
65 specText.append("\n");
66 specText.append(curLine);
67 if (trimedLine.endsWith("*/")) {
68 _endLineNum = reader.getLineNumber();
70 if (isComment(specText.toString()))
72 Construct inst = SpecParser.parseSpec(specText
74 if (inst instanceof InterfaceConstruct
75 || inst instanceof InterfaceDefineConstruct) {
76 funcDecl = readFunctionDecl(reader);
77 specConstruct = new SpecConstruct(
78 specText.toString(), file,
79 _beginLineNum, _endLineNum, inst,
82 specConstruct = new SpecConstruct(
83 specText.toString(), file,
84 _beginLineNum, _endLineNum, inst);
86 _constructs.add(specConstruct);
87 specText = new StringBuilder();
88 // System.out.println(specConstruct);
92 specText.append("\n");
93 specText.append(curLine);
94 if (trimedLine.endsWith("*/")) {
95 _endLineNum = reader.getLineNumber();
97 if (isComment(specText.toString())) {
98 specText = new StringBuilder();
101 Construct inst = SpecParser.parseSpec(specText
103 if (inst instanceof InterfaceConstruct
104 || inst instanceof InterfaceDefineConstruct) {
105 funcDecl = readFunctionDecl(reader);
106 specConstruct = new SpecConstruct(
107 specText.toString(), file, _beginLineNum,
108 _endLineNum, inst, funcDecl);
110 specConstruct = new SpecConstruct(
111 specText.toString(), file, _beginLineNum,
114 _constructs.add(specConstruct);
115 specText = new StringBuilder();
116 // System.out.println(specConstruct);
120 // At the end we can only find the head "/**" but no tail found
122 String msg = "In file \"" + file.getAbsolutePath()
123 + "\", line: " + _beginLineNum + "\n" + _beginLine
124 + "\n" + "Can't find matching spec.";
125 throw new SpecNotMatchException(msg);
127 } catch (FileNotFoundException e) {
129 } catch (IOException e) {
131 } catch (ParseException e) {
132 printSpecInfo(file, specText.toString());
134 } catch (TokenMgrError e) {
135 printSpecInfo(file, specText.toString());
140 private void printSpecInfo(File file, String text) {
141 System.out.println("Error in spec!");
142 System.out.println("File: " + file.getAbsolutePath());
143 System.out.println("Begin: " + _beginLineNum + " End: " + _endLineNum);
144 System.out.println(text);
147 private boolean isComment(String specText) {
148 if (specText.indexOf("@Begin") != -1)
153 private String readFunctionDecl(LineNumberReader reader) throws IOException {
154 String res = "", curLine;
155 while ((curLine = reader.readLine()) != null) {
156 int braceIdx = curLine.indexOf(')');
157 if (braceIdx == -1) {
158 res = res + " " + curLine;
160 res = res + curLine.substring(0, braceIdx + 1);
161 res = trimSpace(res);
168 private String trimSpace(String line) {
171 for (i = 0; i < line.length(); i++) {
173 if (ch != ' ' && ch != '\t')
176 for (j = line.length() - 1; j >= 0; j--) {
178 if (ch != ' ' && ch != '\t')
184 return line.substring(i, j + 1);
187 public ArrayList<SpecConstruct> getConstructs() {
188 return this._constructs;
191 public static void main(String[] argvs) {
192 SpecExtractor extractor = new SpecExtractor();
193 File file = new File("./grammer/spec1.txt");
195 extractor.extract(file);
196 } catch (SpecNotMatchException e) {