.代码
using Spring.Expressions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; namespace ConsoleApplication49
{
public interface IExpressionContext
{
/// <summary>
/// 什么是终结符单词 客户端自己要给出
/// </summary>
Dictionary<string, string> map { get; set; }
string GetValueByKey(string key);
}
public class ExpressionContext : IExpressionContext
{
public Dictionary<string, string> map { get; set; }
public string GetValueByKey(string key)
{
if (map.ContainsKey(key))
return map[key];
return key;
}
}
public abstract class Expression
{
/// <summary>
/// 终结符
/// </summary>
private string key;
public string Key
{
get
{
return key;
} set
{
key = value;
}
} //解析公式和数值,其中var中的key值是是公式中的参数,value值是具体的数字
//这里字典可以抽象为上下文 ctx,此处自己扩展
public abstract string interpreter(IExpressionContext ctx); } public class VarExpression : Expression
{ public VarExpression(string _key)
{ this.Key = _key; } //从map中取之 public override string interpreter(IExpressionContext ctx)
{
if (ctx.map.ContainsKey(Key))
return ctx.GetValueByKey(Key);
else if (Key.IndexOf('(') >= )
{
var key1 = Key.Split('(')[];
return "(" + ctx.GetValueByKey(key1);
}
else if (Key.IndexOf(')') >= )
{
var key1 = Key.Split(')')[];
return ctx.GetValueByKey(key1) + ")";
}
return Key; } } public abstract class SymbolExpression : Expression
{ protected Expression left; protected Expression right; //所有的解析公式都应只关心自己左右两个表达式的结果 public SymbolExpression(Expression _left, Expression _right)
{ this.left = _left; this.right = _right; } } public class AddExpression : SymbolExpression
{ public AddExpression(Expression _left, Expression _right) : base(_left, _right)
{ } //把左右两个表达式运算的结果加起来 public override string interpreter(IExpressionContext ctx)
{ return (base.left.interpreter(ctx)) + "+" + (base.right.interpreter(ctx)); } }
public class SubExpression : SymbolExpression
{ public SubExpression(Expression _left, Expression _right) : base(_left, _right)
{ } //左右两个表达式相减 public override string interpreter(IExpressionContext ctx)
{ return base.left.interpreter(ctx) + "-" + base.right.interpreter(ctx); } }
public class MultExpression : SymbolExpression
{ public MultExpression(Expression _left, Expression _right) : base(_left, _right)
{ } //左右两个表达式相减 public override string interpreter(IExpressionContext ctx)
{ return base.left.interpreter(ctx) + "*" + base.right.interpreter(ctx); } }
public class Dividexpression : SymbolExpression
{ public Dividexpression(Expression _left, Expression _right) : base(_left, _right)
{ } //左右两个表达式相减 public override string interpreter(IExpressionContext ctx)
{ return base.left.interpreter(ctx) + "/" + base.right.interpreter(ctx); } }
public class PExpression : SymbolExpression
{ public PExpression(Expression _left, Expression _right) : base(_left, _right)
{ } //左右两个表达式相减 public override string interpreter(IExpressionContext ctx)
{ return base.left.interpreter(ctx) + "^" + base.right.interpreter(ctx); } } public class Calculator
{ //定义的表达式 private Expression expression; //构造函数传参,并解析 public Calculator(string exprStr)
{ //定义一个堆栈,安排运算的先后顺序 Stack<Expression> stack = new Stack<Expression>();
string[] sb = { "+", "-", "*", "/", "^" };
List<string> items = new List<string>();
string word = string.Empty;
char[] chs = exprStr.ToCharArray();
List<string> chsdict = new List<string>();
foreach (var item in chs)
{
chsdict.Add(item.ToString()); }
foreach (string ch in chsdict)
{ if (!sb.Contains(ch.ToString()))
{
word += ch.ToString();
//if (exprStr.IndexOf(ch) == exprStr.ToCharArray().Length - 1)
if (object.ReferenceEquals(ch, chsdict[chsdict.Count - ]))
{
items.Add(word);
}
}
else
{
items.Add(word.Clone().ToString());
items.Add(ch.ToString());
word = string.Empty;
} } int cx = ;
//表达式拆分为字符数组 char[] charArray = exprStr.ToCharArray(); //运算 Expression left = null; Expression right = null; for (int i = ; i < items.Count; i++)
{
if (cx >= items.Count)
{
break;
}
word = items[cx++]; switch (word)
{ case "+": //加法 //加法结果放到堆栈中 left = stack.Peek(); right = new VarExpression(items[cx++]); stack.Push(new AddExpression(left, right)); break; case "-": left = stack.Peek(); right = new VarExpression(items[cx++]); stack.Push(new SubExpression(left, right)); break;
case "^": left = stack.Peek(); right = new VarExpression(items[cx++]); stack.Push(new PExpression(left, right));
break;
case "/": left = stack.Peek(); right = new VarExpression(items[cx++]); stack.Push(new Dividexpression(left, right));
break;
case "*":
left = stack.Peek(); right = new VarExpression(items[cx++]); stack.Push(new MultExpression(left, right));
break;
default: //公式中的变量
stack.Push(new VarExpression(word));
break; } } //把运算结果抛出来 this.expression = stack.Peek(); } //开始运算 public string run(IExpressionContext ctx)
{ return this.expression.interpreter(ctx); } } public class Client
{ //运行四则运算 public static void Main(string[] args)
{
while (true)
{
string exp = string.Empty;
string expStr = getExpStr();
//赋值 得到终结符单词
Dictionary<string, string> maps = getValue(expStr);
Calculator cal = new Calculator(expStr);
IExpressionContext ctx = new ExpressionContext();
ctx.map = maps;
exp = cal.run(ctx);
var val = ExpressionEvaluator.GetValue(null, exp);
Console.WriteLine("运算结果为:" + expStr + "=" + exp + "=" + val.ToString());
}
Console.ReadKey(); } //获得表达式 public static String getExpStr()
{ Console.WriteLine("请输入表达式:"); return Console.ReadLine(); } //获得值映射 什么才是终结符单词客户端要自己给出定义 public static Dictionary<string, string> getValue(string exprStr)
{
exprStr = exprStr.Replace("(", "").Replace(")", ""); //定义非终结符
string[] sb = { "+", "-", "*", "/", "^" }; string copyExpStr = exprStr.Clone().ToString();
foreach (char ch in exprStr.ToCharArray())
{
if (sb.Contains(ch.ToString()))
{
copyExpStr = copyExpStr.Replace(ch.ToString(), ",");
} }
var items = copyExpStr.Split(','); Dictionary<string, string> map = new Dictionary<string, string>(); //解析有几个参数要传递 foreach (string ch in items)
{ if (!sb.Contains(ch.ToString()) && !Regex.IsMatch(ch, @"[0-9]+(.d+)?") && ch != "(" && ch != ")")
{ //解决重复参数的问题 if (!map.ContainsKey(ch.ToString()))
{
Console.WriteLine("请输入" + ch + "的值:"); string in1 = Console.ReadLine(); map.Add(ch.ToString(), in1); } } } return map; } }
}
2.客户端测试

c# 解释器模式与sping.net表达式的结合应用(金融里经常需要用到公式,这个公式是抽象的需要自己解释)的更多相关文章

  1. 解释器模式 Interpreter 行为型 设计模式(十九)

      解释器模式(Interpreter)   考虑上图中计算器的例子 设计可以用于计算加减运算(简单起见,省略乘除),你会怎么做?    你可能会定义一个工具类,工具类中有N多静态方法 比如定义了两个 ...

  2. 设计模式 笔记 解释器模式 Interpreter

    //---------------------------15/04/26---------------------------- //Interpreter 解释器模式----类行为型模式 /* 1 ...

  3. 设计模式之解释器模式(Interpreter)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  4. Matlab解释器模式

    解释器模式(Interperter),给定一个语言,定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,实际开发中EL表达式或者正则表达式的解释器就是采用这种设计模式.其模式结构如下图.本文使 ...

  5. 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)

    1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e,  要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...

  6. interpreter(解释器模式)

    一.引子 其实没有什么好的例子引入解释器模式,因为它描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发编译器中:在实际应用中,我们可能很少碰到去构造一个语言的文法的情况. 虽然你几乎用 ...

  7. [工作中的设计模式]解释器模式模式Interpreter

    一.模式解析 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 以上是解释器模式的类图,事实上我 ...

  8. 解释器模式(Interpreter Pattern)

    定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpre ...

  9. C#设计模式——解释器模式(Interpreter Pattern)

    一.概述 在软件开发特别是DSL开发中常常需要使用一些相对较复杂的业务语言,如果业务语言使用频率足够高,且使用普通的编程模式来实现会导致非常复杂的变化,那么就可以考虑使用解释器模式构建一个解释器对复杂 ...

随机推荐

  1. 前端安全系列:如何防止CSRF攻击?

    背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点.在移动互联网时代,前端人员除了传统的 XSS.CSRF 等安全问题之外,又时常遭遇网络劫持 ...

  2. 抽取JDBCTemplate

    抽取JDBCTemplate 为了解决DAO实现类中代码的重复问题,另外使得代码更通用,所以抽取一个公共的模板,使其更具有通用性. DAO实现类的代码 public class StudentDAOI ...

  3. RDLC报表系列二

    ---------------------ReportServer数据库权限表说明------------------ --用户表 select * from Users --角色表 select * ...

  4. fatal error: mysql.h: No such file or directory

    在ubuntu系统下安装mysql之后,和数据库连接的时候,出现如下错误:fatal error: mysql.h: No such file or directory 是因为缺少链接库,执行如下命名 ...

  5. 集群(heartbeat)搭建

    HA 即(high available cluster)高可用集群,又称双机热备,保证关键性业务的不间断提供服务. 如:两台机器A和B,正常情况A提供服务,B待命闲置:一但A宕机或服务宕掉,自动切换至 ...

  6. Android ListView根据项数的大小自动改变高度

    第一种:按照listview的项数确定高度 ListAdapter listAdapter = listView.getAdapter();      if (listAdapter == null) ...

  7. WebAPI认证与授权

    Web APi之认证(Authentication)及授权(Authorization)[一](十二) http://www.cnblogs.com/CreateMyself/p/4856133.ht ...

  8. MS-TEST 批处理执行测试时的资源文件目录问题

    What: 使用MS-TEST的 批处理执行它的测试 DLL  时,如: MSTest /testcontainer:C:\David\ADAccountGIT\AdAccountMSTest\ADA ...

  9. 使用jenkins SVN MSBuil配置.net mvc网站进行持续集成

    通过多次搭建Jenkins持续构建环境,终于对Jenkins有了进一步认识,在此把所学所得和大家分享一下,希望可以帮助大家快速掌握Jenkins的核心思想.看了很多文章,最终决定使用Jenkins.以 ...

  10. uwsgi的python2+3多版本共存实操使用virtualenv

    1首先,机器需要有python2和python3的可执行环境.确保pip和pip3命令可用.原理就是在哪个环境下安装uwsgi.uwsgi启动的时候,就用的哪个python版本 2安装virtuale ...