2

Java プログラムから次の C コードをコンパイルしたい (構文エラーは意図的に残されています)。

/* Hello World program */

#include<stdio.h>

main()
{
    printf("Hello World")

}

Java プログラムで C ファイルをコンパイルし、コンソールで診断を行うようにしたいと考えています。例: 行 4 ; 期待され、5行目の無効な構文...

CodeBlock MinGW Compiler をインストールし、コードをコンパイルしてエラーを出力することができました。

私がしたことを見てください:

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 /cgcc実行可能ファイルを から直接呼び出しProcessBuilderます。exit code子プロセスからステータスを確認します。0 以外の終了コードは通常、子プロセスで何らかのエラーが発生したことを意味します。次に、いくつかの正規表現を使用して、出力ストリーム (gcc.exe の stderr 出力も含まれる) からエラー メッセージと行番号を抽出します。

于 2013-02-12T13:42:21.063 に答える