【问题标题】:Is it possible to get the diagnostics printed out for a C program in Java?是否可以为 Java 中的 C 程序打印诊断信息?
【发布时间】:2013-02-12 13:22:30
【问题描述】:

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

    }

【问题讨论】:

  • 我认为您必须自己解析来自 C 编译器的响应才能获取行号和其他内容。
  • 你能详细说明一下吗?
  • 我的意思是你有一个字符串log,其中包含编译器的输出。它的字符串包含有关编译过程及其失败原因的信息。您可以解析字符串并手动获取行号和其他内容。这很混乱,但我不知道其他方式。
  • 谢谢。是的,从字符串日志中获取详细信息将是一件非常痛苦的事情。这就是为什么我想知道我是否可以打电话给听众或其他什么。

标签: java c eclipse compiler-construction mingw


【解决方案1】:

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

【讨论】:

  • 你能给我一个链接吗?
猜你喜欢
  • 2021-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-11
  • 2016-11-25
  • 1970-01-01
  • 2015-02-11
  • 1970-01-01
相关资源
最近更新 更多