c# - 数组元素的反向波兰表示法。 (例如 : array_name[i, j])

标签 c# regex algorithm stack rpn

我需要将 array_name[i, i*k, i-k] 等表达式转换为逆波兰表示法。 我基本上在做的是尝试翻译这样的表达式: if(array_name[i, j+k]>=a+b) array_name[i, j*k] = a+2; else x = a / b; 使用正则表达式进入 RPN。 我已经有一个非常丑陋的巨大正则表达式,它匹配:if, else, + - * / = == ( ) <= >= < > !=以及所有匹配此模式的单词:[a-zA-z][a-zA-z0-9_]* .而且我还有将中缀算术表达式转换为 RPN 的代码。在这里:

/// <summary>
/// Returns the collection of all the lexemes of the expression 
/// using Regex.
/// The Regex created works fine with 'if else' constructions and is good 
///with 
///any variable name possible in C#, with arithmetical expressions, 
///like +, -, /, and all the boolean operators.
/// </summary>
/// <param name="input">String expression in infix notation.</param>
/// <returns>Collection of all the lexemes of the expression</returns>
private static MatchCollection GetMatchCollection(string input)
{
    var rx =
        new Regex(
            @"/\bif\b|\belse\b|\(|\)|\+|\-|\*|\<=|\>=|\\|\>|\<|(?<![!=])[!=]=(?!=)|([a-zA-Z][a-zA-z0-9_]*)|(\d+\.?\d*)|(?<!=)=(?!=)|\/|/^/g");
    return rx.Matches(input);
}


/// <summary>
/// Translates the infix expression into RPN
/// </summary>
/// <param name="input">String expression in infix notation.</param>
/// <returns>RPN expression</returns>
public static string Translate(string input)
{
    var mc = GetMatchCollection(input);

    var id = new Regex(@"[a-zA-z][a-zA-z0-9_]*"); // regex for identifiers
    var num = new Regex(@"\d+\.?\d*"); // regex for decimals
    var skobki = new Regex(@"\(|\)"); // regex for braces
    object[] operators =
    {
        "(", ")", "else", "*", "/", "+", "-", "=", "<", ">", "<=", ">=", "==", "!=", "&&",
        "||", "if"
    }; // operators by priority

    var opers = new Regex(@"\(|\)|\+|\-|\*|\/|<=?|>=?|!=|=|&&|\|\|\bif\b|\belse\b"); // regex for operators

    var stOper = new Stack();
    var expr = new ArrayList();
    foreach (Match m in mc)
    {
        var m1 = id.Match(m.Value);
        if (m1.Success) { expr.Add(m1.Value); continue; }
        m1 = num.Match(m.Value);
        if (m1.Success) { expr.Add(m1.Value); continue; }
        m1 = skobki.Match(m.Value);
        if (m1.Success)
        {
            if (m1.Value == "(") { stOper.Push(m1.Value); continue; }
            var op = stOper.Pop().ToString();
            while (op != "(")
            {
                expr.Add(op);
                op = stOper.Pop().ToString();
            }
            continue;
        }
        m1 = opers.Match(m.Value);
        if (m1.Success)
        {
            try
            {
                while (Array.IndexOf(operators, m1.Value) > Array.IndexOf(operators, stOper.Peek()))
                {
                    if (stOper.Peek().ToString() == "(") break;
                    expr.Add(stOper.Pop().ToString());
                }
            }
            catch (Exception)
            {
                // stack is empty
            }
            stOper.Push(m1.Value);
        }
    }
    while (stOper.Count != 0)
    {
        expr.Add(stOper.Pop().ToString());
    }


    // Make the RPN expression string 
    // from the ArrayList expr.
    var res = new StringBuilder();
    foreach (var s in expr)
        res.Append(s).Append(' ');
    return res.ToString();
}

我如何修改代码来制作方法 public static string Translate(string input)将像 array_name[i,k*i-1] 这样的简单表达式转换成 RPN 表达式?

请注意,public static string Translate(string input)方法仅适用于简单的算术表达式,但不适用于我上面提供的表达式(if-else 语句)。

最佳答案

正则表达式不是要走的路。 Parse它,可能利用了一些 parser generator , 变成 abstract syntax tree并将其输出到RPN中,即trivial .

关于c# - 数组元素的反向波兰表示法。 (例如 : array_name[i, j]),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28480507/

相关文章:

c# - C# 中是否存在所谓的数组类型不匹配异常?

c# - .Net 3.5 中的 Expression.Assign 是否等效?

c# - 以编程方式循环遍历 DatagridView 并选中复选框

c# - 可以在字符类中使用.NET RegEx向后引用来排除以前匹配的字符吗?

python - 我如何矢量化并加速这个大型数组计算?

java - 完美数表现

c# - void AjaxManager_AjaxRequest 可以将 JSON 数据发送回浏览器吗?

c# - 如何匹配一个字符串,但前提是同一字符串尚未匹配或不匹配破折号?

php - MySQL 使用 REGEXP 或 LIKE 来选择带有数据库别名的表名

arrays - 包含列表中每个单词的最小 "scrabble board"