是否可以在Java中为C程序打印出诊断信息?

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

/* Hello World program */ #include 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 myerrors = new ArrayList(); 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"); } 

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