java - 是否可以为 Java 中的 C 程序打印诊断信息?

标签 java c eclipse compiler-construction mingw

我想从一个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");

    }

最佳答案

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

关于java - 是否可以为 Java 中的 C 程序打印诊断信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14833558/

相关文章:

java - drools 6.0 中未知的 KieSession 名称(尝试将 drools 添加到现有的 maven/eclipse 项目中)

java - 无法在文件浏览器中查看所有文件

java - 语法错误: Encountered "BEGIN"

java - 从 Guava 集合中继承 HashBasedTable

c - 直接函数调用是否比回调函数调用执行得更快?

eclipse - 使用深色 Eclipse 颜色主题和比较编辑器

java - 尝试通过导入所有 JAR 文件在 eclipse 中运行 "Word Count"程序时 getCredentials 方法错误

java - 聊天 TCP 上的空白 Jframe 加载

c - 标记化 c block 中的段错误

c - 使用 float 格式说明符打印 int 变量