调车场计算算法的标记化

问题描述 投票:0回答:1

我有一个标记化算法和一些无法正确解析的数学表达式。

这是代码:

private void GetTokens()
{
    foreach (char token in test)
    {
        if (token.ToString().IsNumber() || token == '.' || token == ',')
        {
            currentToken.Append(token);
        }
        else if (token.IsOperator())
        {
            if (currentToken.Length > 0)
            {
                tokens.Add(currentToken.ToString());
                currentToken.Clear();
            }

            bool minusToNegative =
                tokens.Length > 0 && token == '-' && 
                tokens[^1].IsOperator() && tokens[^1] != ")";
            
            if (token == '(' && tokens[^1] == "-" && tokens[^2].IsNumber())
            {
                tokens[^1] = "+";
                tokens.Add("-1");
                tokens.Add("*");
            }
            
            if (minusToNegative)
            {
                currentToken.Append(token);
                continue;
            }

            tokens.Add(token.ToString());
        }
    }

    if (currentToken.Length > 0)
    {
        tokens.Add(currentToken.ToString());
    }
}

我尝试修复一个表达式,但它不适用于另一个表达式。有这样的例子:-(((-3)-10)--12) 和 -23-(2+3)。第一个的解析方法不适用于第二个,反之亦然。

如何解决所有情况?

c# tokenize shunting-yard
1个回答
0
投票

我建议采取稍微不同的方法:

private static void GetTokens()
{
    foreach (char token in test) {
        switch (token) {
            case >= '0' and <= '9' or '.' or ',':
                currentToken.Append(token);
                break;
            case '+' or '-' when tokens is [] or [.., "(" or "+" or "-" or "*" or "/"]:
                // Unary minus.
                AppendCurrentToken();
                currentToken.Append(token);
                break;
            case '+' or '-' or '*' or '/':
                // Operator
                AppendCurrentToken();
                tokens.Add(token.ToString());
                break;
            case '(' or ')':
                AppendCurrentToken();
                tokens.Add(token.ToString());
                break;
            default:
                break;
        }
    }
    AppendCurrentToken();


    void AppendCurrentToken()
    {
        if (currentToken.Length > 0) {
            tokens.Add(currentToken.ToString());
            currentToken.Clear();
        }
    }
}

我的测试输出是:

"(((-3)-10)--12)" ==>
(
(
(
-3
)
-
10
)
-
-12
)

"-23-(2+3)" ==>
-23
-
(
2
+3
)
© www.soinside.com 2019 - 2024. All rights reserved.