mardi 19 mai 2015

NoSuchElementException from Scanner I think there is something wrong with my Path?

Hello I'm checking out ANTL. I tried to make a Parser for calculations (at this point just additions work like 1+2+3 or similar). It turned out that my Scanner throws a NoSuchElementException if he wants to Read from my HelloWorld file. As far as I evaluated the Code everything works fine except for the Scanner. But I could be terribly wrong with this.

I also tried to read a simple character with:

new Scanner(in).read();

but it returned -1.

So I'm not sure if this is a Problem with my Scanner or if this is a Problem with my temp Path or maybe I'm doing something other stupid.

By the way I'm using a Mac OSX with Yosemite if it helps.

The source Code is also here on Github.

So here is my Code from the Test Case:

@RunWith(DataProviderRunner.class)
public class CompilerTest {

    private Path tempDir;

    @Before
    public void createTempDir() throws IOException {
        tempDir = Files.createTempDirectory("compilerTest");
    }

    @After
    public void deleteTempDir() {
        deleteRecursive(tempDir.toFile());
    }

    private void deleteRecursive(File file) {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                deleteRecursive(child);
            }
        }
        if (!file.delete()) {
            throw new Error("Could not delete file <" + file.getName() + ">");
        }
    }

    @DataProvider
    public static Object[][] provide_code_expectedText() {
        //@formatter:off
        return new Object[][] { 
                { "1+2", "3" }, 
                { "20+22", "42" }, 
                { "1+2+3", "6" }
               };
        //@formatter:on
    }

    @Test
    @UseDataProvider("provide_code_expectedText")
    public void test(String code, String expectedText) throws IOException,
            Exception {
        // execution
        String actualOutput = compileAndRun(code);

        // evaluation
        assertEquals(expectedText, actualOutput);
    }

    private String compileAndRun(String code) throws IOException, Exception {
        code = Main.compile(new ANTLRInputStream(code));
        ClassFile classFile = new ClassFile();
        classFile.readJasmin(new StringReader(code), "", false);
        Path outputPath = tempDir.resolve(classFile.getClassName() + ".class");
        classFile.write(Files.newOutputStream(outputPath));
        return runJavaClass(tempDir, classFile.getClassName());
    }

    private String runJavaClass(Path dir, String className) throws IOException {
        System.out.println(dir.toString());
        Process process = Runtime.getRuntime().exec(new String[] { "javac", "-cp", dir.toString(), className });
        try (InputStream in = process.getInputStream()) {
            // TODO here is something wrong
            return new Scanner(in).useDelimiter("\\A").next();
        }
    }

}

And the code from the Main:

public class Main {

    public static void main(String[] args) throws Exception {
        ANTLRInputStream input = new ANTLRFileStream("resources/code.demo");
        System.out.println(compile(input)); 
    }

    public static String compile(ANTLRInputStream input) {
        DemoLexer lexer = new DemoLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        DemoParser parser = new DemoParser(tokens);

        ParseTree tree = parser.addition();
        return createJasminFile(new MyVisitor().visit(tree));
    }

    private static String createJasminFile(String instructions) {
        return ".class public HelloWorld\n"
                + ".super java/lang/Object\n"
                + "\n"
                + ".method public static main([Ljava/lang/String;)V\n"
                + "   .limit stack 100\n"
                + "   .limit locals 100\n"
                + "\n"
                + "   getstatic java/lang/System/out Ljava/io/PrintStream;\n"
                + instructions + "\n"
                + "   invokevirtual java/io/PrintStream/println(I)V\n"
                + "return\n"
                + "\n"
                + ".end method";
    }

}

Aucun commentaire:

Enregistrer un commentaire