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;
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 funcDecl = readFunctionDecl(reader);
76 specConstruct = new SpecConstruct(
77 specText.toString(), file,
78 _beginLineNum, _endLineNum, inst, funcDecl);
80 specConstruct = new SpecConstruct(
81 specText.toString(), file,
82 _beginLineNum, _endLineNum, inst);
84 specText = new StringBuilder();
85 System.out.println(specConstruct);
89 specText.append("\n");
90 specText.append(curLine);
91 if (trimedLine.endsWith("*/")) {
92 _endLineNum = reader.getLineNumber();
94 if (isComment(specText.toString())) {
95 specText = new StringBuilder();
98 Construct inst = SpecParser.parseSpec(specText
100 if (inst instanceof InterfaceConstruct) {
101 funcDecl = readFunctionDecl(reader);
102 specConstruct = new SpecConstruct(
103 specText.toString(), file,
104 _beginLineNum, _endLineNum, inst, funcDecl);
106 specConstruct = new SpecConstruct(
107 specText.toString(), file,
108 _beginLineNum, _endLineNum, inst);
110 System.out.println(specConstruct);
111 specText = new StringBuilder();
115 // At the end we can only find the head "/**" but no tail found
117 String msg = "In file \"" + file.getAbsolutePath()
118 + "\", line: " + _beginLineNum + "\n" + _beginLine
119 + "\n" + "Can't find matching spec.";
120 throw new SpecNotMatchException(msg);
122 } catch (FileNotFoundException e) {
124 } catch (IOException e) {
126 } catch (ParseException e) {
127 printSpecInfo(file, specText.toString());
129 } catch (TokenMgrError e) {
130 printSpecInfo(file, specText.toString());
135 private void printSpecInfo(File file, String text) {
136 System.out.println("Error in spec!");
137 System.out.println("File: " + file.getAbsolutePath());
138 System.out.println("Begin: "
139 + _beginLineNum + " End: " + _endLineNum);
140 System.out.println(text);
143 private boolean isComment(String specText) {
144 if (specText.indexOf("@Begin") != -1)
149 private String readFunctionDecl(LineNumberReader reader) throws IOException {
150 String res = "", curLine;
151 while ((curLine = reader.readLine()) != null) {
152 int braceIdx = curLine.indexOf(')');
153 if (braceIdx == -1) {
154 res = res + " " + curLine;
156 res = res + curLine.substring(0, braceIdx + 1);
157 res = trimSpace(res);
164 private String trimSpace(String line) {
167 for (i = 0; i < line.length(); i++) {
169 if (ch != ' ' && ch != '\t')
172 for (j = line.length() - 1; j >= 0; j--) {
174 if (ch != ' ' && ch != '\t')
180 return line.substring(i, j + 1);
183 public ArrayList<SpecConstruct> getConstructs() {
184 return this._constructs;
187 public static void main(String[] argvs) {
188 SpecExtractor extractor = new SpecExtractor();
189 File file = new File("./grammer/spec1.txt");
191 extractor.extract(file);
192 } catch (SpecNotMatchException e) {