parser checked
[cdsspec-compiler.git] / src / edu / uci / eecs / specCompiler / specExtraction / SpecExtractor.java
index ddd25bc1273a3d1dc558463b257a77e2bb14de84..ac6de02b405f06a4db25b1a184009eb6d150c0a9 100644 (file)
@@ -8,6 +8,10 @@ import java.io.IOException;
 import java.io.LineNumberReader;
 import java.util.ArrayList;
 
 import java.io.LineNumberReader;
 import java.util.ArrayList;
 
+import edu.uci.eecs.specCompiler.grammerParser.ParseException;
+import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
+import edu.uci.eecs.specCompiler.grammerParser.TokenMgrError;
+
 /**
  * <p>
  * This class represents the specification extractor of the specification. The
 /**
  * <p>
  * This class represents the specification extractor of the specification. The
@@ -15,89 +19,174 @@ import java.util.ArrayList;
  * corresponding specification out, and remember its location, including the
  * file name and the line number, to help the code generation process.
  * </p>
  * corresponding specification out, and remember its location, including the
  * file name and the line number, to help the code generation process.
  * </p>
+ * 
  * @author peizhaoo
  * @author peizhaoo
- *
+ * 
  */
 public class SpecExtractor {
        private ArrayList<SpecConstruct> _constructs;
  */
 public class SpecExtractor {
        private ArrayList<SpecConstruct> _constructs;
-       private StringBuilder _extractedSpecText;
-       
-       private enum State {
-               Neutral, HeadParsed, BeginParsed, EndParsed
-       }
-       
-       private State _curState;
-       
-       private StringBuilder _potentialConstruct;
-       private int _startLine, _endLine;
-       
+       private int _beginLineNum, _endLineNum;
+       private String _beginLine;
+
        SpecExtractor() {
                _constructs = new ArrayList<SpecConstruct>();
        SpecExtractor() {
                _constructs = new ArrayList<SpecConstruct>();
-               _extractedSpecText = new StringBuilder();
-               _curState = State.Neutral;
-               _potentialConstruct = new StringBuilder();
        }
        }
-       
+
        /**
         * <p>
        /**
         * <p>
-        * Given a list of files, it scans each file and add found SpecConstrcut
-        * to the _constructs list.
+        * Given a list of files, it scans each file and add found SpecConstrcut to
+        * the _constructs list.
         * </p>
         * </p>
+        * 
         * @param files
         * @param files
+        * @throws SpecNotMatchException
         */
         */
-       private void extract(File[] files) {
+       public void extract(File[] files) throws SpecNotMatchException {
                for (int i = 0; i < files.length; i++)
                        extract(files[i]);
        }
                for (int i = 0; i < files.length; i++)
                        extract(files[i]);
        }
-       
-       private void extract(File file) {
+
+       public void extract(File file) throws SpecNotMatchException {
+               StringBuilder specText = new StringBuilder();
                try {
                        LineNumberReader reader = new LineNumberReader(new FileReader(file));
                try {
                        LineNumberReader reader = new LineNumberReader(new FileReader(file));
-                       String prevLine = "", curLine;
-                       ArrayList<String> text;
+                       String prevLine = "", curLine, trimedLine, funcDecl;
+                       SpecConstruct specConstruct;
+                       boolean foundHead = false;
                        while ((curLine = reader.readLine()) != null) {
                        while ((curLine = reader.readLine()) != null) {
-                               
+                               if (prevLine.endsWith("\\"))
+                                       continue;
+                               trimedLine = trimSpace(curLine);
+                               if (!foundHead) {
+                                       if (trimedLine.startsWith("/**")) {
+                                               _beginLineNum = reader.getLineNumber();
+                                               _beginLine = curLine;
+                                               foundHead = true;
+                                               specText.append("\n");
+                                               specText.append(curLine);
+                                               if (trimedLine.endsWith("*/")) {
+                                                       _endLineNum = reader.getLineNumber();
+                                                       foundHead = false;
+                                                       if (isComment(specText.toString()))
+                                                               continue;
+                                                       Construct inst = SpecParser.parseSpec(specText
+                                                                       .toString());
+                                                       if (inst instanceof InterfaceConstruct) {
+                                                               funcDecl = readFunctionDecl(reader);
+                                                               specConstruct = new SpecConstruct(
+                                                                               specText.toString(), file,
+                                                                               _beginLineNum, _endLineNum, inst, funcDecl);
+                                                       } else {
+                                                               specConstruct = new SpecConstruct(
+                                                                               specText.toString(), file,
+                                                                               _beginLineNum, _endLineNum, inst);
+                                                       }
+                                                       specText = new StringBuilder();
+                                                       System.out.println(specConstruct);
+                                               }
+                                       }
+                               } else {
+                                       specText.append("\n");
+                                       specText.append(curLine);
+                                       if (trimedLine.endsWith("*/")) {
+                                               _endLineNum = reader.getLineNumber();
+                                               foundHead = false;
+                                               if (isComment(specText.toString())) {
+                                                       specText = new StringBuilder();
+                                                       continue;
+                                               }
+                                               Construct inst = SpecParser.parseSpec(specText
+                                                               .toString());
+                                               if (inst instanceof InterfaceConstruct) {
+                                                       funcDecl = readFunctionDecl(reader);
+                                                       specConstruct = new SpecConstruct(
+                                                                       specText.toString(), file,
+                                                                       _beginLineNum, _endLineNum, inst, funcDecl);
+                                               } else {
+                                                       specConstruct = new SpecConstruct(
+                                                                       specText.toString(), file,
+                                                                       _beginLineNum, _endLineNum, inst);
+                                               }
+                                               System.out.println(specConstruct);
+                                               specText = new StringBuilder();
+                                       }
+                               }
+                       }
+                       // At the end we can only find the head "/**" but no tail found
+                       if (foundHead) {
+                               String msg = "In file \"" + file.getAbsolutePath()
+                                               + "\", line: " + _beginLineNum + "\n" + _beginLine
+                                               + "\n" + "Can't find matching spec.";
+                               throw new SpecNotMatchException(msg);
                        }
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
                        }
                } catch (FileNotFoundException e) {
                        e.printStackTrace();
                } catch (IOException e) {
                        e.printStackTrace();
+               } catch (ParseException e) {
+                       printSpecInfo(file, specText.toString());
+                       e.printStackTrace();
+               } catch (TokenMgrError e) {
+                       printSpecInfo(file, specText.toString());
+                       e.printStackTrace();
                }
        }
        
                }
        }
        
-       private void parseHead(String prevLine, String line) {
-               assert (_curState == State.Neutral);
-               
-               // "\" is the C/C++ line break. If the previous line ends with "\",
-               // it may be part of a string literal.
-               if (prevLine.endsWith("\\"))
-                       return;
-               String newLine = trimBeginningSpace(line);
-//             if (newLine.startsWith("/**") && 
-//                             (newLine.length() == 3 || 
-       }
-       
-       private void parseBegin(String line) {
-               
+       private void printSpecInfo(File file, String text) {
+               System.out.println("Error in spec!");
+               System.out.println("File: " + file.getAbsolutePath());
+               System.out.println("Begin: "
+                               + _beginLineNum + "  End: " + _endLineNum);
+               System.out.println(text);
        }
        
        }
        
-       private void parseEnd(String line) {
-               
+       private boolean isComment(String specText) {
+               if (specText.indexOf("@Begin") != -1)
+                       return false;
+               return true;
        }
        }
-       
-       private void parseTail(String line) {
-               
+
+       private String readFunctionDecl(LineNumberReader reader) throws IOException {
+               String res = "", curLine;
+               while ((curLine = reader.readLine()) != null) {
+                       int braceIdx = curLine.indexOf(')');
+                       if (braceIdx == -1) {
+                               res = res + " " + curLine;
+                       } else {
+                               res = res + curLine.substring(0, braceIdx + 1);
+                               res = trimSpace(res);
+                               break;
+                       }
+               }
+               return res;
        }
        }
-       
-       private String trimBeginningSpace(String line) {
-               int i;
+
+       private String trimSpace(String line) {
+               int i, j;
+               char ch;
                for (i = 0; i < line.length(); i++) {
                for (i = 0; i < line.length(); i++) {
-                       char ch = line.charAt(i);
-                       if (ch == ' ' || ch == '\t')
-                               i++;
-                       else
+                       ch = line.charAt(i);
+                       if (ch != ' ' && ch != '\t')
                                break;
                }
                                break;
                }
-               return line.substring(i);
+               for (j = line.length() - 1; j >= 0; j--) {
+                       ch = line.charAt(j);
+                       if (ch != ' ' && ch != '\t')
+                               break;
+               }
+               if (i > j)
+                       return "";
+               else
+                       return line.substring(i, j + 1);
+       }
+
+       public static void main(String[] argvs) {
+               SpecExtractor extractor = new SpecExtractor();
+               File file = new File("./grammer/spec1.txt");
+               try {
+                       extractor.extract(file);
+               } catch (SpecNotMatchException e) {
+                       e.printStackTrace();
+               }
        }
 }
        }
 }