知识大全 老生常谈:解释器模式
Posted 表达式
篇首语:一箫一剑平生意,负尽狂名十五年。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 老生常谈:解释器模式相关的知识,希望对你有一定的参考价值。
解释器模式的目的:如果某一类问题一再的发生 此时比较好的做法是将此类问题的各个实例表达为一个简单语言中的语句 这样可以建造一个解释器 通过解释这些语句达到解决问题的目的
解释器模式的定义
定义语言的文法 并且建立一个解释器来解释该语言中的句子 它属于类的行为模式 这里的语言意思是使用规定格式和语法的代码
示意案例:
解释器这个模式在实际应用当中应用并不广泛 能想到的例子也不多 可能是我水平不够 这里我拿一个把大写数字输出为阿拉伯数字数字的需求来用解释器模式实现 例如
:伍千肆百参拾贰 输出为
:当用户输入的是数字字符串时 直接输入数字 例如 直接输出
解释器模式的结构
模式所涉及的角色
:抽象表达式角色 声明一个所有的具体表达式角色都需要实现的抽象接口 这个接口主要是一个interprect方法 我们叫解释方法
注意 本示例中的抽象表达式角色中的解释方法并非抽象方法 因为这个案例特殊 数字解释的方法过程一样
/// <summary> /// 抽象表达式角色 /// </summary> public abstract class Expression /// <summary> /// 汉字数字与阿拉伯数字数字的对应字典 /// </summary> protected Dictionary<string int> table = new Dictionary<string int>( ); public Expression() table Add( 壹 ); table Add( 贰 ); table Add( 参 ); table Add( 肆 ); table Add( 伍 ); table Add( 陆 ); table Add( 柒 ); table Add( 捌 ); table Add( 玖 ); /// <summary> /// 所有的具体表达式角色都需要实现的抽象方法 /// 这个方法为虚方法 并非抽象方法 为了代码复用 /// </summary> /// <param name= context >环境角色</param> public virtual void Interpret(Context context) //如果要处理的字符串长度为 则返回 if (context statement Length == ) return ; foreach (string key in table Keys) int value = table[key]; if (context statement EndsWith(key + GetPostifix())) context data += value * Multiplier(); context statement = context statement Substring( context statement Length this GetLength()); break; if (context statement EndsWith( 零 )) context statement = context statement Substring( context statement Length ); break; if (context statement Length == ) return ; /// <summary> /// 取汉字数字单位 /// 个位数为空 /// 十位数为十 /// 百位数为百 /// 千位数为千 /// </summary> /// <returns></returns> public abstract string GetPostifix(); /// <summary> /// 例如:个位上数字为 则最后为 * /// 例如:百位上数字为 则表示 * /// </summary> /// <returns></returns> public abstract int Multiplier(); /// <summary> /// 例如:个位的长度为一位 /// 例如数字三十 表示两位 /// 例如四百 表示两位 /// </summary> /// <returns></returns> public virtual int GetLength() return this GetPostifix() Length + ;终结符表达式角色 一个具体角色
> 实现了抽象表达式角色所要求的接口 主要是interpret方法
>:方法中的每一个终结符都有一个具体终结表达式与之相对应
说明 如果用户输入的内容不是汉字 而是数字字符串 则直接输出 不必解释
/// <summary> /// 终结符表达式角色 /// 如果能换算成数字则直接换算后返回 /// </summary> class TerminalExpression : Expression /// <summary> /// 重写解释方法 /// </summary> /// <param name= context >环境角色</param> public override void Interpret(Context context) int i = ; try i = int Parse(context statement); //如果是数字则说明能够直接转换 //也就是说用不到非终结表达式角色 context statement = ; context data = i; catch //说明输入的是汉字数字 不做任何处理 public override string GetPostifix() return ; public override int Multiplier() return ;非终结符表达式角色 这也是一个具体角色
>:文法中的每一条规则R=R R Rn都需要一个具体的非终结符表达式类;
>:对每一个R R 中的符号都持有一个静态类型为Expression的实例变量;
>:实现解释操作 解释操作以递归的方式调用上面所提到的代表R R 中的各个符号的实例变量
注意 本示例中由于解释的方法都一样 为些非终结符表达中的解释方法在没有重写的情况下调用抽象表达式角色的解释方法
/// <summary> /// 非终结表达式角色 /// 解释个位数 /// </summary> public class NonterminalOneExpression : Expression public override string GetPostifix() return ; public override int Multiplier() return ; public override int GetLength() return ; /// <summary> /// 非终结表达式角色 /// 解释十位数 /// </summary> public class NonterminalTenExpression : Expression public override string GetPostifix() return 拾 ; public override int Multiplier() return ; public override int GetLength() return ; /// <summary> /// 非终结表达式角色 /// 解释百位数 /// </summary> public class NonterminalHundredExpression : Expression public override string GetPostifix() return 百 ; public override int Multiplier() return ; public override int GetLength() return ; /// <summary> /// 非终结表达式角色 /// 解释千位数 /// </summary> public class NonterminalThousandExpression : Expression public override string GetPostifix() return 千 ; public override int Multiplier() return ; public override int GetLength() return ;客户端角色
>:建造一个抽象语法树;抽象语法树的每一个节点都代表一个语句 而在每一个节点上都可以执行解释方法 这个方法的执行就代表这个语句的解释
>:调用解释操作
string roman = 伍千肆百参拾贰 ; // Context context = new Context(roman); //构造抽象语法树 ArrayList tree = new ArrayList(); //加入终结符表达式 //如果能直接转换成数字则直接返回 tree Add(new TerminalExpression()); //非终结符 处理个位数 tree Add(new NonterminalOneExpression()); //非终结符 处理十位数 tree Add(new NonterminalTenExpression()); //非终结符 处理百位数 tree Add(new NonterminalHundredExpression()); //非终结器 处理千位数 tree Add(new NonterminalThousandExpression()); //对抽象语法树的每个枝节进行解释操作 foreach (Expression exp in tree) exp Interpret(context); Console WriteLine( = roman context data);环境角色 提供解释器之外的一些全局信息 比如变量的真实量值
/// <summary> /// 环境角色 /// </summary> public class Context /// <summary> /// 汉字表示的数字 /// </summary> public string statement get; set; /// <summary> /// 阿拉伯数字 /// </summary> public int data get; set; /// <summary> /// 构造函数 /// 接受一个汉字表达式数字 /// </summary> /// <param name= statement >汉字表达式数字</param> public Context(string statement) this statement = statement;解释器模式适用性
系统有一个简单的语言可供解释
一些重复发生的问题可以用这种简单的语言表达
cha138/Article/program/net/201311/13348相关参考
有很多方法可以把对象堆起来成为一个集合你可以把它们放进数组堆栈列表或者是散列表中这是你的自由 迭代器模式定
设计: 人类通过劳动改造世界创造文明创造物质财富和精神财富而最基础最主要的创造活动是造物设计便是造物活动进行预先的计划可以把任何造物活动的计划技术和计划过程理解为设计意指有目标和计划的创作行为&
设计模式之Interpreter(解释器) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! Int
请用简单通俗的话解释路由器访客模式的作用!访客网络,就是给外来人用的。它无法访问网内的用户情况,如共享文件,打印机,就很单纯的上网而已。正常网络,就可以电脑与电脑之间局域网内相互访问。请用通俗的话帮我
面试过程中,面试官会向应征者发问,而应征者的回答将成为面试官考虑是否接受他的重要依据。对应征者而言,了解这些问题背后的「猫腻」至关重要。本文对面试中经常出现的一些典型问题进行了
在上一篇你会在C#的类库中添加webservice吗?我谈到了webservice的应用本人一直学习设计模式而webservice就是代理模式的一种特别经典的应用 名词解释 &
牛皮癣的诊断与治疗是现在老生常谈的问题,由于牛皮癣是各个年龄段的人都会受到此病的侵害,导致婴儿也不能幸免于难。婴儿最常见的应该是尿布牛皮癣,婴儿经常会使用尿布,尿液中尿素就会导致牛皮癣的发生。那么,我
牛皮癣的诊断与治疗是现在老生常谈的问题,由于牛皮癣是各个年龄段的人都会受到此病的侵害,导致婴儿也不能幸免于难。婴儿最常见的应该是尿布牛皮癣,婴儿经常会使用尿布,尿液中尿素就会导致牛皮癣的发生。那么,我
不久,你就要毕业、走上工作岗位了。这是一个漫长岁月,将近四十年的职业生涯。作为父辈、一个经历了多年职业生涯的“过来人”,说几句“老生常谈”,对你今后的职业生涯应该有所帮助。关于找工作一下子找到自己喜欢
痤疮疾病的病因都会有哪些?痤疮是我们老生常谈的话题,几乎是每个人或多或少都会出现的皮肤问题。很多人对于痤疮,只是一味地抹药、擦洗治疗,对于病因却并不是很了解!了解了病因,我们才会更好的从根源上入手,对