可自定义函数、并且函数可任意嵌套的中缀表达式解析器
来源:互联网 发布: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
- 可自定义函数、并且函数可任意嵌套的中缀表达式解析器
- 可任意自定义的UITableViewCell
- 可任意自定义的UITableViewCell
- 可任意自定义的UITableViewCell
- 可任意自定义的UITableViewCell
- 可任意自定义的UITableViewCell
- taoism版脚本引擎已经加入如下函数,所以函数可任意嵌套
- 可支持任意级选择器级联的控件函数
- 可任意自定义的UITableViewCell高度
- DataTable.Select()中的表达式可使用的函数
- DataTable.Select()中的表达式可使用的函数
- DataTable.Select()中的表达式可使用的函数
- DataTable.Select()中的表达式可使用的函数
- DataTable.Select()中的表达式可使用的函数
- MonoBehaviour可重写的函数
- MonoBehaviour可重写的函数
- 可重复使用的JS函数
- Python 小技巧:任意属性值可在构造函数中设置的 Bunch Pattern
- 基于webmagic爬取并下载百度图片
- POJ 2828 Buy Tickets 线段树单点更新
- CentOS7部署轻量级web服务器nginx+php
- NFC 安卓开发
- Hibernate的主键生成策略
- 可自定义函数、并且函数可任意嵌套的中缀表达式解析器
- mysql与oracle
- NYOJ33 蛇形填数
- Nginx负载均衡的4种方案配置实例
- MATALAB常用统计学的相关函数
- JWebFileTrans- 一款可以从网络上下载文件的小程序(一)
- 匿名对象
- 手势密码
- jquery笔记:事件 focusin, focusout,scroll, select