可自定义函数、并且函数可任意嵌套的中缀表达式解析器

来源:互联网 发布:u盘数据恢复免费破解版 编辑:程序博客网 时间:2024/06/03 19:24

中缀表达式解析器的特点:
- 可自定义函数、并且函数可任意嵌套的中缀表达式转化成声明函数参数个数的后缀表达式
- 支持算术运算和逻辑运算
- {}用来表示优先级,()用来标识自定义函数的参数列表

示例:
中缀表达式max(abs(random(-9,-1)),random(1,9))-3>0转化成声明函数参数个数的后缀表达式:-9,-1,2,random,(),1,abs,(),1,9,2,random,(),2,max,(),3,-,0,> (其中粗体数字为函数参数个数)

主要思路:

下面直接给出中缀表达式解析器的完整代码,包含有完整注释:

using UnityEngine;using System.Collections;using System.Collections.Generic;public class InToPostTransfer{    //操作符表    private static List<string> operatorList = new List<string>()    {        "!",        "+",        "-",        "*",        "/",        "%",        ">",        "<",        ">=",        "<=",        "==",        "!=",        "&&",        "||",        "=",        "&",        "|",    };    //自定义函数参数个数缓存字典    private static Dictionary<string, int> funcParamrterCountMap = new Dictionary<string, int>();    public static string InToPost(string infixExpression)    {        funcParamrterCountMap.Clear();        string postfixExpression = string.Empty;        //最终输出的后缀表达式        int index = 0;                                  //中缀表达式扫描游标        Stack<string> stack = new Stack<string>();      //操作符堆栈        bool isPreOperator = false;                     //前一个是否是操作符        int customFuncIdentifier = 0;                   //自定义表达式分配的唯一标识        while (index < infixExpression.Length || stack.Count > 0)        {            if (index >= infixExpression.Length)        //last something            {                postfixExpression += stack.Pop() + ",";            }            else if (infixExpression[index] == '{')     //'{',直接入栈            {                isPreOperator = false;                stack.Push("{");                index++;            }            else if (infixExpression[index] == '}')     //'}',依次出栈直到与{匹配            {                isPreOperator = false;                string operatorInStacktop = stack.Pop().ToString();                while (operatorInStacktop != "{")                {                    postfixExpression += operatorInStacktop + ",";                    operatorInStacktop = stack.Pop().ToString();                }                index++;            }            else if (infixExpression[index] == '(' || infixExpression[index] == ',')    //'(',意味着一个自定义函数参数列表的开始;',',函数列表分隔符。标识前一个是操作符,不做其它处理            {                isPreOperator = true;                index++;            }            else if (infixExpression[index] == ' ')                                     //' ',空格跳过            {                index++;            }            else if (infixExpression[index] == ')')                                     //')',意味着一个自定义函数参数列表的结束            {                isPreOperator = false;                string customFunction = stack.Pop().ToString();                         //自定义函数出栈                int parameterCount = funcParamrterCountMap[customFunction];             //获取自定义函数参数个数                string customFuncName = customFunction.Substring(0, customFunction.LastIndexOf("_"));                postfixExpression += parameterCount.ToString() + "," + customFuncName + ",(),";     //拼接到后缀表达式                index++;            }            else if (infixExpression[index] == '\'')                                    //'\'',意味着一个字符串            {                int lastIndexOfString = GetString(infixExpression, index);                string stringInExpression = infixExpression.Substring(index + 1, lastIndexOfString - index - 1);                postfixExpression += stringInExpression + ",";                index = lastIndexOfString + 1;            }            else            {                int lastIndexOfOperator = MatchOperator(infixExpression, index);        //操作符匹配                if (lastIndexOfOperator != -1)                                          //操作符匹配成功                {                    string operatorCurrent = infixExpression.Substring(index, lastIndexOfOperator - index);                    if (isPreOperator == true && operatorCurrent == "-")                //负号                    {                        postfixExpression += operatorCurrent;                        index = lastIndexOfOperator;                        isPreOperator = false;                    }                    else                    {                        isPreOperator = true;       //操作符                        if (stack.Count == 0)       //操作符堆栈为空,直接入栈                        {                            stack.Push(operatorCurrent);                            index = lastIndexOfOperator;                        }                        else                        {                            string operatorInStacktop = stack.Peek().ToString();        //操作符堆栈不为空,peek栈顶元素                            if (GetOperatorPriority(operatorCurrent) > GetOperatorPriority(operatorInStacktop))     //当前操作符的优先级比栈顶的高,入栈                            {                                stack.Push(operatorCurrent);                                index = lastIndexOfOperator;                            }                            else                            {                                postfixExpression += stack.Pop() + ",";                 //当前操作符的优先级不高于栈顶,先出栈再入栈                                stack.Push(operatorCurrent);                                index = lastIndexOfOperator;                            }                        }                    }                }                else                        {                    int lastIndexOfOperand = GetOperand(infixExpression, index);        //操作数匹配                    if (lastIndexOfOperand != -1)                                       //操作数匹配成功,拼接到后缀表达式                    {                        isPreOperator = false;                        string operandCurrent = infixExpression.Substring(index, lastIndexOfOperand - index);                        postfixExpression += operandCurrent + ",";                        index = lastIndexOfOperand;                    }                    else                                                                //自定义函数                    {                        isPreOperator = false;                        int lastIndexOfCustomFunction = GetCustomFunction(infixExpression, index);      //获取自定义函数                        string customFunction = infixExpression.Substring(index, lastIndexOfCustomFunction - index) + "_" + customFuncIdentifier;                           customFuncIdentifier++;                        funcParamrterCountMap.Add(customFunction, GetFuncParameterCount(infixExpression, lastIndexOfCustomFunction + 1));   //自定义函数参数个数缓存                        stack.Push(customFunction);                                                     //自定义函数入栈                        index = lastIndexOfCustomFunction;                    }                }            }        }        postfixExpression = postfixExpression.Substring(0, postfixExpression.Length - 1);        return postfixExpression;    }    //操作符匹配    private static int MatchOperator(string infixExpression, int beginIndex)    {        int lastIndex = beginIndex;        string str = infixExpression.Substring(beginIndex, lastIndex - beginIndex + 1);        while (operatorList.Contains(str) && lastIndex < infixExpression.Length)        {            lastIndex++;            if (lastIndex == infixExpression.Length)            {                continue;            }            str = infixExpression.Substring(beginIndex, lastIndex - beginIndex + 1);        }        if (lastIndex == beginIndex)        {            lastIndex = -1;        }        return lastIndex;    }    //获取操作数,包括:ture、false及数值    private static int GetOperand(string infixExpression, int beginIndex)    {        int lastIndex = beginIndex;        char ch = infixExpression[lastIndex];        switch (ch)        {             case 't':                if (infixExpression.Substring(beginIndex, 4) == "true")                {                    lastIndex = beginIndex + 4;                }                break;            case 'f':                if (infixExpression.Substring(beginIndex, 5) == "false")                {                    lastIndex = beginIndex + 5;                }                break;            default:                while ( (char.IsDigit(ch) || ch == '.') && lastIndex < infixExpression.Length )                {                    lastIndex++;                    if (lastIndex == infixExpression.Length)                    {                        continue;                    }                    ch = infixExpression[lastIndex];                }                break;        }        if (lastIndex == beginIndex)        {            lastIndex = -1;        }        return lastIndex;    }    //获取自定义函数    private static int GetCustomFunction(string infixExpression, int beginIndex)    {        int lastIndex = beginIndex;        char ch = infixExpression[lastIndex];        while (ch != '(' && lastIndex < infixExpression.Length )        {            lastIndex++;            if (lastIndex == infixExpression.Length)            {                continue;            }            ch = infixExpression[lastIndex];        }        return lastIndex;    }    //获取自定义函数参数个数    private static Stack<char> stackParam = new Stack<char>();    private static int GetFuncParameterCount(string infixExpression, int beginIndex)    {        stackParam.Clear();        int parametrCount = 1;        int index         = beginIndex;        char ch           = infixExpression[index];        if (ch == ')')        {            parametrCount = 0;        }        while (ch != ')' )        {            if (ch == '(')            {                stackParam.Push(ch);            }            else if ((ch == ',' || ch.Equals(','))                       && stackParam.Count == 0)            {                parametrCount++;            }            ch = infixExpression[++index];            while (ch == ')' && stackParam.Count != 0)            {                stackParam.Pop();                ch = infixExpression[++index];            }        }        return parametrCount;    }    //获取字符串    private static int GetString(string infixExpression, int beginIndex)    {        int lastIndex = beginIndex + 1;        char ch = infixExpression[lastIndex];        while (ch != '\'')        {            lastIndex++;            ch = infixExpression[lastIndex];        }        return lastIndex;    }    //获取操作符优先级    private static int GetOperatorPriority(string ope)    {        switch (ope)        {             case "||":                return 1;            case "&&":                return 2;            case "==":                return 3;            case "!=":                return 3;            case "<=":                return 4;            case ">=":                return 4;            case "<":                return 4;            case ">":                return 4;            case "+":                return 5;            case "-":                return 5;            case "*":                return 6;            case "/":                return 6;            case "%":                return 6;            case "!":                return 7;            case "{":                return 0;            default:                return -1;        }    }}
1 0
原创粉丝点击