Ejemplo n.º 1
0
  private PdeRecognizer createParser(final String program) {
    // create a lexer with the stream reader, and tell it to handle
    // hidden tokens (eg whitespace, comments) since we want to pass these
    // through so that the line numbers when the compiler reports errors
    // match those that will be highlighted in the PDE IDE
    //
    PdeLexer lexer = new PdeLexer(new StringReader(program));
    lexer.setTokenObjectClass("antlr.CommonHiddenStreamToken");

    // create the filter for hidden tokens and specify which tokens to
    // hide and which to copy to the hidden text
    //
    filter = new TokenStreamCopyingHiddenTokenFilter(lexer);
    filter.hide(PdePartialTokenTypes.SL_COMMENT);
    filter.hide(PdePartialTokenTypes.ML_COMMENT);
    filter.hide(PdePartialTokenTypes.WS);
    filter.copy(PdePartialTokenTypes.SEMI);
    filter.copy(PdePartialTokenTypes.LPAREN);
    filter.copy(PdePartialTokenTypes.RPAREN);
    filter.copy(PdePartialTokenTypes.LCURLY);
    filter.copy(PdePartialTokenTypes.RCURLY);
    filter.copy(PdePartialTokenTypes.COMMA);
    filter.copy(PdePartialTokenTypes.RBRACK);
    filter.copy(PdePartialTokenTypes.LBRACK);
    filter.copy(PdePartialTokenTypes.COLON);
    filter.copy(PdePartialTokenTypes.TRIPLE_DOT);

    // Because the meanings of < and > are overloaded to support
    // type arguments and type parameters, we have to treat them
    // as copyable to hidden text (or else the following syntax,
    // such as (); and what not gets lost under certain circumstances)
    // -- jdf
    filter.copy(PdePartialTokenTypes.LT);
    filter.copy(PdePartialTokenTypes.GT);
    filter.copy(PdePartialTokenTypes.SR);
    filter.copy(PdePartialTokenTypes.BSR);

    // create a parser and set what sort of AST should be generated
    //
    final PdeRecognizer parser = new PdeRecognizer(this, filter);

    // use our extended AST class
    //
    parser.setASTNodeClass("antlr.ExtendedCommonASTWithHiddenTokens");
    return parser;
  }
Ejemplo n.º 2
0
  /**
   * preprocesses a pde file and writes out a java file
   *
   * @return the class name of the exported Java
   */
  private String write(final String program, final PrintWriter stream)
      throws SketchException, RecognitionException, TokenStreamException {

    // Match on the uncommented version, otherwise code inside comments used
    // http://code.google.com/p/processing/issues/detail?id=1404
    String uncomment = scrubComments(program);
    PdeRecognizer parser = createParser(program);
    if (PUBLIC_CLASS.matcher(uncomment).find()) {
      try {
        final PrintStream saved = System.err;
        try {
          // throw away stderr for this tentative parse
          System.setErr(new PrintStream(new ByteArrayOutputStream()));
          parser.javaProgram();
        } finally {
          System.setErr(saved);
        }
        setMode(Mode.JAVA);
      } catch (Exception e) {
        // I can't figure out any other way of resetting the parser.
        parser = createParser(program);
        parser.pdeProgram();
      }
    } else if (FUNCTION_DECL.matcher(uncomment).find()) {
      setMode(Mode.ACTIVE);
      parser.activeProgram();
    } else {
      parser.pdeProgram();
    }

    // set up the AST for traversal by PdeEmitter
    //
    ASTFactory factory = new ASTFactory();
    AST parserAST = parser.getAST();
    AST rootNode = factory.create(ROOT_ID, "AST ROOT");
    rootNode.setFirstChild(parserAST);

    makeSimpleMethodsPublic(rootNode);

    // unclear if this actually works, but it's worth a shot
    //
    // ((CommonAST)parserAST).setVerboseStringConversion(
    //  true, parser.getTokenNames());
    // (made to use the static version because of jikes 1.22 warning)
    BaseAST.setVerboseStringConversion(true, parser.getTokenNames());

    final String className;
    if (mode == Mode.JAVA) {
      // if this is an advanced program, the classname is already defined.
      className = getFirstClassName(parserAST);
    } else {
      className = this.name;
    }

    // if 'null' was passed in for the name, but this isn't
    // a 'java' mode class, then there's a problem, so punt.
    //
    if (className == null) return null;

    // debug
    if (false) {
      final StringWriter buf = new StringWriter();
      final PrintWriter bufout = new PrintWriter(buf);
      writeDeclaration(bufout, className);
      new PdeEmitter(this, bufout).print(rootNode);
      writeFooter(bufout, className);
      debugAST(rootNode, true);
      System.err.println(buf.toString());
    }

    writeDeclaration(stream, className);
    new PdeEmitter(this, stream).print(rootNode);
    writeFooter(stream, className);

    // if desired, serialize the parse tree to an XML file.  can
    // be viewed usefully with Mozilla or IE
    if (Preferences.getBoolean("preproc.output_parse_tree")) {
      writeParseTree("parseTree.xml", parserAST);
    }

    return className;
  }