2

我想从java程序编译以下C代码(故意留下语法错误):

/* Hello World program */

#include<stdio.h>

main()
{
    printf("Hello World")

}

我希望我的 java 程序编译 C 文件并在控制台中给出诊断。示例:第 4 行;预期和第 5 行无效语法...

我已经安装了 CodeBlock MinGW 编译器,并且能够编译代码并打印出错误。

看看我做了什么:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class C_Compile {
    public static void main(String args[]){

        String ret = compile();
        System.out.println(ret);

    }
    public static String compile()
    {
        String log="";
        String myDirectory = "C:\\";
        try {
            String s= null;
            //change this string to your compilers location
            Process p = Runtime.getRuntime().exec("cmd /C gcc hello.c", null, new java.io.File(myDirectory));

            BufferedReader stdError = new BufferedReader(new
                    InputStreamReader(p.getErrorStream()));
            boolean error=false;

            log+="\n....\n";
            while ((s = stdError.readLine()) != null) {
                log+=s;
                error=true;
                log+="\n";
            }
            if(error==false) log+="Compilation Successful !!!";

        } catch (IOException e) {
            e.printStackTrace();
        }
        return log;
    }


    public int runProgram()
    {
        int ret = -1;
        try
        {
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec("cmd.exe /c start a.exe");
            proc.waitFor();
            ret = proc.exitValue();
        } catch (Throwable t)
        {
            t.printStackTrace();
            return ret;
        }
        return ret;
    }
}

我得到以下结果:

    ....
hello.c: In function 'main':
hello.c:9:1: error: expected ';' before '}' token

但我想知道是否有可能从听众那里得到诊断。我想获取行号、位置、语法错误的类型,这些错误将稍后输入到数组中以进行进一步处理。

以下是我想在 Java 中拥有的东西:

http://prntscr.com/sgvya

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    List<CaptureErrors> myerrors = new ArrayList<CaptureErrors>();
    MyDiagnosticListener listener = new MyDiagnosticListener(); 
    StandardJavaFileManager fileManager  = compiler.getStandardFileManager(listener, null, null); 

    String fileToCompile = "C:\\Users\\User\\Desktop\\MyC.java";

    Iterable fileObjects = fileManager.getJavaFileObjectsFromStrings(Arrays.asList(fileToCompile));  
    CompilationTask task = compiler.getTask(null, fileManager, listener, null, null, fileObjects); 
    Boolean result = task.call();
    if(result == true){
        System.out.println("Compilation has succeeded");
    }
    myerrors = listener.getlistofErrors();
    for (CaptureErrors e : myerrors)
    {
        System.out.println("Code: " + e.getCode());
        System.out.println("Kind: " + e.getKind());
        System.out.println("Line Number: " + e.getLinenumber());
       // System.out.println("Message: "+ e.getMessage(Locale.ENGLISH));
        //System.out.println("Source: " + e.getSource());
        System.out.println("End position: "+ e.getEndposition());
        System.out.println("Position: "+ e.getPosition());
        System.out.println("\n");

    }
4

1 回答 1

1

而不是Runtime.exec()使用ProcessBuilderredirectErrorStream(true)就可以了。这样,您将能够从编译器输出中捕获stdoutstderr 。而不是通过直接从cmd /c调用gcc可执行文件来调用ProcessBuilder. 检查exit code子进程的状态。非 0 退出代码通常意味着子进程中的一些错误。然后使用一些正则表达式从输出流(也将包含 gcc.exe 的 stderr 输出)中提取错误消息和行号。

于 2013-02-12T13:42:21.063 回答