예제 #1
0
  /**
   * Create an AST from a program (using ANTLR lexer & parser) Returns null if error Use
   * 'alreadyIncluded' to keep track of from 'include' statements
   */
  public static ParseTree createAst(File file, boolean debug, Set<String> alreadyIncluded) {
    alreadyIncluded.add(Gpr.getCanonicalFileName(file));
    String fileName = file.toString();
    String filePath = fileName;

    BigDataScriptLexer lexer = null;
    BigDataScriptParser parser = null;

    try {
      filePath = file.getCanonicalPath();

      // Input stream
      if (!Gpr.canRead(filePath)) {
        CompilerMessages.get().addError("Can't read file '" + filePath + "'");
        return null;
      }

      // Create a CharStream that reads from standard input
      ANTLRFileStream input = new ANTLRFileStream(fileName);

      // ---
      // Lexer: Create a lexer that feeds off of input CharStream
      // ---
      lexer =
          new BigDataScriptLexer(input) {
            @Override
            public void recover(LexerNoViableAltException e) {
              throw new RuntimeException(e); // Bail out
            }
          };

      // ---
      // Parser
      // ---
      CommonTokenStream tokens = new CommonTokenStream(lexer);
      parser = new BigDataScriptParser(tokens);

      // Parser error handling
      parser.setErrorHandler(
          new CompileErrorStrategy()); // Bail out with exception if errors in parser
      parser.addErrorListener(new CompilerErrorListener()); // Catch some other error messages that
      // 'CompileErrorStrategy' fails to catch

      // Begin parsing at main rule
      ParseTree tree = parser.programUnit();

      // Error loading file?
      if (tree == null) {
        System.err.println("Can't parse file '" + filePath + "'");
        return null;
      }

      // Show main nodes
      if (debug) {
        Timer.showStdErr("AST:");
        for (int childNum = 0; childNum < tree.getChildCount(); childNum++) {
          Tree child = tree.getChild(childNum);
          System.err.println(
              "\t\tChild " + childNum + ":\t" + child + "\tTree:'" + child.toStringTree() + "'");
        }
      }

      // Included files
      boolean resolveIncludePending = true;
      while (resolveIncludePending)
        resolveIncludePending = resolveIncludes(tree, debug, alreadyIncluded);

      return tree;
    } catch (Exception e) {
      String msg = e.getMessage();
      CompilerMessages.get()
          .addError(
              "Could not compile "
                  + filePath //
                  + (msg != null ? " :" + e.getMessage() : "") //
              );
      return null;
    }
  }