我想从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中想要的内容:
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");
}
答案 0 :(得分:1)
代替Runtime.exec()
使用ProcessBuilder
和redirectErrorStream(true)
。这样,您就可以从编译器输出中捕获 stdout 和 stderr 。而不是通过cmd /c
调用直接从ProcessBuilder
调用 gcc 可执行文件。检查子进程的exit code
状态。非0 exitcode通常意味着子进程中的一些错误。然后使用一些正则表达式从输出流中提取错误消息和行号(这也包含gcc.exe的stderr输出)。