0

CまたはC++ファイルを入力として受け取り、ファイルをコンパイルして、プログラムで見つかったエラーの場所、位置、タイプを提供するプログラムをJavaで開発する必要があります。構文エラーの方が心配です。これをEclipse Javaで行う方法が必要です。Eclipse CDT プラグインをインストールしましたが、Java プログラム内からコンパイラを呼び出して、行番号、場所、位置を取得できるかどうかわかりません。

コンパイラ、つまり MinGW コンパイラをインストールしようとしましたが、エラーを出力できましたが、思い通りにエラーが表示されません。ここに私がリンクを試したもののリンクがあります

Cプログラムで見つかった構文エラーの行番号、位置を配列でキャプチャするのを手伝ってもらえますか?

4

1 に答える 1

1

stdoutと からの結果を解析する必要がありstderrます。リンクした質問では、それらにアクセスする方法を見つけることができます。

また、コンパイラ エラーのリスナーが必要だとも言いました。

public interface CompilerErrorListener {
    public void onSyntaxError(String filename, String functionName, 
        int lineNumber, int position, String message);

    public void invalidOutputLine(String line);
}

これは、任意の実装で実装できます。

public class CompilerErrorProcessor implements CompilerErrorListener {
    public void onSyntaxError(String filename, String functionName, 
        int lineNumber, int position, String message) {
        ....
        // your code here to process the errors, e.g. put them into an ArrayList
    }

    public void invalidOutputLine(String line) {
        // your error handling here
    }
}

それでは、コンパイラの出力を解析しましょう! (これはコンパイラの出力に依存し、2 行の出力しか提供していないことに注意してください)

BufferedReader stdError = ...
String line;

CompilerErrorListener listener = new CompilerErrorProcessor(...);

String fileName = "";
String functionName = "";
int lineNumber = -1;
int position = -1;
String message = null;

while ((line = stdError.readLine()) != null) {
    // the line always starts with "filename.c:"
    String[] a1 = line.split(":", 2);
    if (a1.length == 2) {
        // a1[0] is the filename, a1[1] is the rest
        if (! a1[0].equals(fileName)) {
            // on new file
            fileName = a1[0];
            functionName = "";
        }
        // here is the compiler message
        String msg = a1[1];
        if (msg.startsWith("In ")) {
            // "In function 'main':" - we cut the text between '-s
            String[] a2 = msg.split("'");
            if (a2.length == 3) {
                functionName = a2[1];
            } else {
                listener.invalidOutputLine(line);
            }
        } else {
            // "9:1: error: expected ';' before '}' token"
            String[] a2 = msg.split(":", 3);
            if (a2.length == 3) {
                lineNumber = Integer.parseInt(a2[0]);
                position = Integer.parseInt(a2[1]);
                message = a2[2];

                // Notify the listener about the error:
                listener.onSyntaxError(filename, functionName, lineNumber, position, message);
            } else {
                listener.invalidOutputLine(line);
            }
        }

    } else {
        listener.invalidOutputLine(line);
    }

}

もちろん、これは完全な例ではありません。他にも多くの可能性があるかもしれませんが、アイデアが得られたことを願っています。無効/未処理のブランチをログに記録することを忘れないでください。

特定のコンパイラを使用するため、その出力に適応する必要があります。また、コンパイラのバージョンの変更により、解析コードが変更される場合があります。出力の構造を発見するように細心の注意を払ってください。解析したいときに役立ちます。

于 2013-03-03T14:40:38.653 に答える