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 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 _constructs.add(specConstruct);
85 specText = new StringBuilder();
86 // System.out.println(specConstruct);
90 specText.append("\n");
91 specText.append(curLine);
92 if (trimedLine.endsWith("*/")) {
93 _endLineNum = reader.getLineNumber();
95 if (isComment(specText.toString())) {
96 specText = new StringBuilder();
99 Construct inst = SpecParser.parseSpec(specText
101 if (inst instanceof InterfaceConstruct) {
102 funcDecl = readFunctionDecl(reader);
103 specConstruct = new SpecConstruct(
104 specText.toString(), file,
105 _beginLineNum, _endLineNum, inst, funcDecl);
107 specConstruct = new SpecConstruct(
108 specText.toString(), file,
109 _beginLineNum, _endLineNum, inst);
111 _constructs.add(specConstruct);
112 specText = new StringBuilder();
113 // System.out.println(specConstruct);
117 // At the end we can only find the head "/**" but no tail found
119 String msg = "In file \"" + file.getAbsolutePath()
120 + "\", line: " + _beginLineNum + "\n" + _beginLine
121 + "\n" + "Can't find matching spec.";
122 throw new SpecNotMatchException(msg);
124 } catch (FileNotFoundException e) {
126 } catch (IOException e) {
128 } catch (ParseException e) {
129 printSpecInfo(file, specText.toString());
131 } catch (TokenMgrError e) {
132 printSpecInfo(file, specText.toString());
137 private void printSpecInfo(File file, String text) {
138 System.out.println("Error in spec!");
139 System.out.println("File: " + file.getAbsolutePath());
140 System.out.println("Begin: "
141 + _beginLineNum + " End: " + _endLineNum);
142 System.out.println(text);
145 private boolean isComment(String specText) {
146 if (specText.indexOf("@Begin") != -1)
151 private String readFunctionDecl(LineNumberReader reader) throws IOException {
152 String res = "", curLine;
153 while ((curLine = reader.readLine()) != null) {
154 int braceIdx = curLine.indexOf(')');
155 if (braceIdx == -1) {
156 res = res + " " + curLine;
158 res = res + curLine.substring(0, braceIdx + 1);
159 res = trimSpace(res);
166 private String trimSpace(String line) {
169 for (i = 0; i < line.length(); i++) {
171 if (ch != ' ' && ch != '\t')
174 for (j = line.length() - 1; j >= 0; j--) {
176 if (ch != ' ' && ch != '\t')
182 return line.substring(i, j + 1);
185 public ArrayList<SpecConstruct> getConstructs() {
186 return this._constructs;
189 public static void main(String[] argvs) {
190 SpecExtractor extractor = new SpecExtractor();
191 File file = new File("./grammer/spec1.txt");
193 extractor.extract(file);
194 } catch (SpecNotMatchException e) {