3

私はこのプロジェクトをどこから始めるべきかを理解しようとしています。おそらく、誰かが私を正しい方向に導くことができます。

通訳を書かなければならない小さな言語が与えられました。言語は、括弧内の式のいずれかで構成されます。

(integer integer operator)

または、次の形式の式で構成される算術 IF ステートメント:

IF exp1 exp2 exp3 exp4

ここで、exp1 が負の場合は exp2 が返され、exp1 がゼロの場合は exp3 が返され、exp1 が正の場合は exp4 が返されます。

演算子は + または x (それぞれ加算と乗算) です。

スキャナー/パーサーを一緒に実装し、次に結果を出力するインタープリターを実装する必要があります。インタープリターの部分は難しくありませんが、スキャン/解析プロセスを開始する方法がわかりません。

私は Java を使用して開始し、入力を収集して文字列に格納する Scanner オブジェクトを用意しました。次に、区切り文字として何も使用せずに String を String 配列に分割します (これにより、各文字、記号、スペースなどが文字列の独自のインデックスに格納されます)。ここからどこへ行くべきか分からないので、これはこれを行う最善の方法ではないかもしれません。私が把握できない部分は、この構文に従わない場合にエラーを返す方法、または括弧や IF などを検出する方法です。

前の段落で説明したコードのスニペットを次に示します。

public void run() {
    Scanner sc = new Scanner(System.in);

    while (sc.hasNext()) {
        String sLine = sc.nextLine();
        String[] scanned = sLine.split("");

入力例:

(7 2 +)

Output: 9

IF (2 -2 +) (5 2 +) (5 -2 x) (5 2 x)

Output: -10

誰かが私にとって良い方向性を持っているなら、共有してください. :)

4

4 に答える 4

3

スタック ベースのアルゴリズムを使用して、後置式を処理できます。簡単なアイデアは、整数をスタックにプッシュし、演算子に遭遇したときにスタックから整数をポップし、+、- などの演算子によって言及された操作を実行することです。

于 2013-01-30T05:01:32.033 に答える
3

ANTLR、JavaCC、SampleCC、またはその他のパーサー ジェネレーター ツールを使用することは、大ハンマーを使用してナットを割ることになると思います。文法定義に再帰がない場合は、いくつかのメソッドで十分です。次のコードは、基本的なアイデアを示しています (コンパイルまたは動作しない可能性があります。開始方法の例としてゼロから書きました)。

public int parse(String input) {
Scanner scanner = new Scanner(input);

    return consumeLine(scanner);
}

public int consumeLine(Scanner scanner) {
    if( scanner.hasNext("(") ) {
        return consumeExpression(scanner);

    } else if( scanner.hasNext("IF") ) {
        return consumeIf(scanner);
    }
}


public int consumeExpression(Scanner scanner) {
    scanner.next("(");
    int a = scanner.nextInt();
    int b = scanner.nextInt();
    String op = scanner.next("[+-/*]");
    scanner.next(")");

    if( "+".equals(op) ) {
        return a + b;

    } else if( "-".equals(op) ) {
        return a - b;
    } ...

    throw new RuntimeException("parsing error");
}

public int consumeIf(Scanner scanner) {
    scanner.next("IF");
    int exp1 = consumeExpression(scanner);
    int exp2 = consumeExpression(scanner);
    int exp3 = consumeExpression(scanner);
    int exp4 = consumeExpression(scanner);

    if( exp1 < 0 ) {
        return exp2;
    } else if( exp1 == 0 ) {
        return exp3;
    } ...

    throw new RuntimeException("should not be here (TM)");
}
于 2013-01-30T05:47:23.563 に答える
1

Java に慣れている場合は、javacc を使用すると簡単です。コンパクトで簡単な方法でトークンとその処理方法について言及できます。コンパイルすると、ロジックを実行するために必要な Java ソースのすべてのコードが生成されます。

javacc イントロ

javacc よくある質問

于 2013-01-30T04:35:54.973 に答える
0

C++ とブースト スピリット ライブラリを使用することをお勧めします....

于 2013-01-30T04:54:43.443 に答える