//执行函数校验 private ExpressionToken VerifyFunction(ExpressionToken funtionToken, Stack <ExpressionToken> verifyStack) { if (!(verifyStack.Count == 0)) { bool doPop = true; var args = new List <BaseMetadata>(); ExpressionToken parameter = null; //弹出函数的参数,直到遇到"("时终止 while (doPop && !(verifyStack.Count == 0)) { parameter = verifyStack.Pop(); if (ExpressionToken.ETokenType.ETOKEN_TYPE_CONSTANT == parameter.TokenType) { //常量 args.Add(parameter.Constant); } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_VARIABLE == parameter.TokenType) { args.Add(parameter.Variable); } else if ("(".Equals(parameter.GetSplitor())) { doPop = false; } else { //没有找到应该存在的右括号 throw new IllegalExpressionException("表达式不合法,函数\"" + funtionToken.TokenText + "\"遇到非法参数" + parameter.ToString() + ";位置:" + parameter.StartPosition , funtionToken.ToString() , funtionToken.StartPosition); } } if (doPop && (verifyStack.Count == 0)) { //操作栈以空,没有找到函数的左括号( throw new IllegalExpressionException("表达式不合法,函数\"" + funtionToken.TokenText + "\"缺少\"(\";位置:" + (funtionToken.StartPosition + funtionToken.ToString().Length) , funtionToken.ToString() , funtionToken.StartPosition); } //校验函数 var arguments = new BaseMetadata[args.Count]; arguments = args.ToArray(); Constant result = FunctionExecution.Verify(funtionToken.TokenText, funtionToken.StartPosition, arguments); return(ExpressionToken.CreateConstantToken(result)); } else { //没有找到应该存在的右括号 throw new IllegalExpressionException("表达式不合法,函数\"" + funtionToken.TokenText + "\"不完整" , funtionToken.ToString() , funtionToken.StartPosition); } }
/// <summary> /// 执行操作符校验 /// </summary> /// <param name="opToken"></param> /// <param name="verifyStack"></param> /// <returns></returns> private ExpressionToken VerifyOperator(ExpressionToken opToken, Stack <ExpressionToken> verifyStack) { //判定几元操作符 Operator op = opToken.Op; int opType = op.OpType; //取得相应的参数个数 var args = new BaseMetadata[opType]; ExpressionToken argToken = null; for (int i = 0; i < opType; i++) { if (!(verifyStack.Count == 0)) { argToken = verifyStack.Pop(); if (ExpressionToken.ETokenType.ETOKEN_TYPE_CONSTANT == argToken.TokenType) { args[i] = argToken.Constant; } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_VARIABLE == argToken.TokenType) { args[i] = argToken.Variable; } else { //如果取到的Token不是常量,也不是变量,则抛出错误 throw new IllegalExpressionException("表达式不合法,操作符\"" + op.Token + "\"参数错误;位置:" + argToken.StartPosition , opToken.ToString() , opToken.StartPosition); } } else { //栈已经弹空,没有取道操作符对应的操作数 throw new IllegalExpressionException("表达式不合法,操作符\"" + op.Token + "\"找不到相应的参数,或参数个数不足;" , opToken.ToString() , opToken.StartPosition); } } //执行操作符校验,并返回校验 Constant result = op.Verify(opToken.StartPosition, args); return(ExpressionToken.CreateConstantToken(result)); }
/// <summary> /// 将子窜转化成Token并加入列表 /// </summary> /// <param name="tokenString"></param> /// <param name="tokens"></param> private void AddToken(string tokenString, List <ExpressionToken> tokens) { ExpressionToken token = null; //null if (ExpressionTokenHelper.IsNull(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_NULL, null); tokens.Add(token); } else //boolean if (ExpressionTokenHelper.IsBoolean(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_BOOLEAN, Convert.ToBoolean(tokenString)); tokens.Add(token); } else //integer if (ExpressionTokenHelper.IsInteger(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_INT, Convert.ToInt32(tokenString)); tokens.Add(token); } else //long if (ExpressionTokenHelper.IsLong(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_LONG, Convert.ToInt64(tokenString.Substring(0, tokenString.Length - 1))); tokens.Add(token); } else //float if (ExpressionTokenHelper.IsFloat(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_FLOAT, Convert.ToSingle(tokenString.Substring(0, tokenString.Length - 1))); tokens.Add(token); } else //double if (ExpressionTokenHelper.IsDouble(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_DOUBLE, Convert.ToDouble(tokenString)); tokens.Add(token); } else //Date if (ExpressionTokenHelper.IsDateTime(tokenString)) { try { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_DATE, Convert.ToDateTime(tokenString.Substring(1, tokenString.Length - 1))); } catch (Exception e) { throw new IllegalExpressionException("日期参数格式错误"); } tokens.Add(token); } else //String if (ExpressionTokenHelper.IsString(tokenString)) { token = ExpressionToken.CreateConstantToken(DataType.DATATYPE_STRING, tokenString.Substring(1, tokenString.Length - 1)); tokens.Add(token); } else //分割符 if (ExpressionTokenHelper.IsSplitor(tokenString)) { token = ExpressionToken.CreateSplitorToken(tokenString); tokens.Add(token); } else //函数 if (ExpressionTokenHelper.IsFunction(tokenString)) { token = ExpressionToken.CreateFunctionToken(tokenString.Substring(1, tokenString.Length)); tokens.Add(token); } else //操作符 if (ExpressionTokenHelper.IsOperator(tokenString)) { Operator op = ExpressionParser.GetOperator(tokenString); token = ExpressionToken.CreateOperatorToken(op); tokens.Add(token); } else { //剩下的都应该是变量,这个判断依赖于生成的RPN是正确的前提 //变量,在boolean型和null型判别后,只要是字母打头的,不是$的就是变量 token = ExpressionToken.CreateVariableToken(tokenString); tokens.Add(token); } }
/** * 执行逆波兰式 * @return */ public Constant Execute(List <ExpressionToken> _RPNExpList) { if (_RPNExpList == null || _RPNExpList.Count == 0) { throw new ArgumentException("无法执行空的逆波兰式队列"); } //初始化编译栈 Stack <ExpressionToken> compileStack = new Stack <ExpressionToken>(); foreach (ExpressionToken expToken in _RPNExpList) { if (ExpressionToken.ETokenType.ETOKEN_TYPE_CONSTANT == expToken.TokenType) { //读取一个常量,压入栈 compileStack.Push(expToken); } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_VARIABLE == expToken.TokenType) { //读取一个变量 //从上下文获取变量的实际值,将其转化成常量Token,压入栈 Variable varWithValue = VariableContainer.GetVariable(expToken.Variable.VariableName); if (varWithValue != null) { //生成一个有值常量,varWithValue.getDataValue有可能是空值 ExpressionToken constantToken = ExpressionToken.CreateConstantToken( varWithValue.GetDataType() , varWithValue.DataValue); compileStack.Push(constantToken); } else { //throw new IllegalStateException("变量\"" +expToken.getVariable().getVariableName() + "\"不是上下文合法变量" ); //当变量没有定义时,视为null型 ExpressionToken constantToken = ExpressionToken.CreateConstantToken( DataType.DATATYPE_NULL , null); compileStack.Push(constantToken); } } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_OPERATOR == expToken.TokenType) { Operator op = expToken.Op; //判定几元操作符 int opType = op.OpType; //取得相应的参数个数 Constant[] args = new Constant[opType]; ExpressionToken argToken = null; for (int i = 0; i < opType; i++) { if (!(compileStack.Count == 0)) { argToken = compileStack.Pop(); if (ExpressionToken.ETokenType.ETOKEN_TYPE_CONSTANT == argToken.TokenType) { args[i] = argToken.Constant; } else { //如果取出的Token不是常量,则抛出错误 throw new Exception("操作符" + op.Token + "找不到相应的参数,或参数个数不足;位置:" + expToken.StartPosition); } } else { //栈已经弹空,没有取道操作符对应的操作数 throw new Exception("操作符" + op.Token + "找不到相应的参数,或参数个数不足;位置:" + expToken.StartPosition); } } //构造引用常量对象 Reference reference = new Reference(expToken, args); ExpressionToken resultToken = ExpressionToken.CreateReference(reference); //将引用对象压入栈 compileStack.Push(resultToken); } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_FUNCTION == expToken.TokenType) { if (!(compileStack.Count == 0)) { ExpressionToken onTop = compileStack.Pop(); //检查在遇到函数词元后,执行栈中弹出的第一个词元是否为“)” if (")".Equals(onTop.GetSplitor())) { bool doPop = true; List <Constant> argsList = new List <Constant>(); ExpressionToken parameter = null; //弹出函数的参数,直到遇到"("时终止 while (doPop && !(compileStack.Count == 0)) { parameter = compileStack.Pop(); if (ExpressionToken.ETokenType.ETOKEN_TYPE_CONSTANT == parameter.TokenType) { argsList.Add(parameter.Constant); } else if ("(".Equals(parameter.GetSplitor())) { doPop = false; } else { //在函数中遇到的既不是常量,也不是"(",则报错 throw new Exception("函数" + expToken.TokenText + "执行时遇到非法参数" + parameter.ToString()); } } if (doPop && (compileStack.Count == 0)) { //操作栈以空,没有找到函数的左括号( throw new Exception("函数" + expToken.TokenText + "执行时没有找到应有的\"(\""); } //执行函数 Constant[] arguments = new Constant[argsList.Count]; arguments = argsList.ToArray(); //构造引用常量对象 Reference reference = new Reference(expToken, arguments); ExpressionToken resultToken = ExpressionToken.CreateReference(reference); //将引用对象压入栈 compileStack.Push(resultToken); } else { //没有找到应该存在的右括号 throw new Exception("函数" + expToken.TokenText + "执行时没有找到应有的\")\""); } } else { //没有找到应该存在的右括号 throw new Exception("函数" + expToken.TokenText + "执行时没有找到应有的\")\""); } } else if (ExpressionToken.ETokenType.ETOKEN_TYPE_SPLITOR == expToken.TokenType) { //读取一个分割符,压入栈,通常是"("和")" compileStack.Push(expToken); } } //表达式编译完成,这是编译栈内应该只有一个编译结果 if (compileStack.Count == 1) { ExpressionToken token = compileStack.Pop(); Constant result = token.Constant; //执行Reference常量 if (result.IsReference) { Reference resultRef = (Reference)result.DataValue; return(resultRef.Execute()); } else { //返回普通的常量 return(result); } } else { var errorBuffer = new StringBuilder("\r\n"); while (!(compileStack.Count == 0)) { ExpressionToken onTop = compileStack.Pop(); errorBuffer.Append("\t").Append(onTop.ToString()).Append("\r\n"); } throw new Exception("表达式不完整.\r\n 结果状态异常:" + errorBuffer.ToString()); } }