1

ポーランド語表記を解決するインタープリターがあります。トークンにすべての操作と数値があり、トークンのリストがあります。たとえば- - 5 4 2、これらのトークンを含むリストは次のとおりです。

SubtractionToken、SubtractionToken、NumberToken、NumberToken、NumberToken、STOPToken。

トークンの例:

class SubstractToken : IBinaryOperation
{
    public Number Interpret(Number value1, Number value2)
    {
        Number c = new Number(value1.Value() - value2.Value());
        return c;
    }
}

class Number : IToken
{
    private int value;

    public Number(int val)
    {
        value = val;
    }

    public int Value()
    {
        return value;
    }

}

したがって、この問題を解決するために再帰関数を作成する方法がわかりません。SubstractionToken.Inrerpret(value, value) の場合、numberTokensそれ自体から減算する必要がある値を指定する必要がありますが、次のトークンが操作トークンの場合はどうなるでしょうか? または私たちは持ってい- 5 - 7 2ますか?最初の操作が行われるべきであることを検出するような再帰関数を実装する方法がわかりません - 7 2 次に - 5 および resultof(- 7 2)、結果を記憶し、以前の実行されていない操作に戻ります。何か助けはありますか?

4

2 に答える 2

3

これは通常、これまでに見た結果を格納する評価スタックで行います。入力に数字がある場合は、それをスタックにプッシュし、二項演算 (「-」など) がある場合は、スタックから 2 つの値をポップして解釈し、結果をプッシュします。何かのようなもの:

public static Number Evaluate(List<IToken> tokens, Stack<Number> eval) {
    if(tokens.Count == 0) {
        if(eval.Count != 1) throw new InvalidArgumentException("Invalid expression");
        return eval.Pop();
    }
    var tok = tokens[tokens.Count-1];
    tokens.RemoveAt(tokens.Count-1);
    if (tok is Number) {
        eval.Push(tok);
    }
    else if(tok is IBinaryOperation) {
        var result = ((IBinaryOperation)tok).Evaluate(eval.Pop(), eval.Pop());
        eval.Push(result);
    }
    //handle other cases
    return Evaluate(tokens, eval);
}

これは、必要に応じて簡単に反復関数にすることができます。

于 2016-05-25T16:24:06.857 に答える