C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

模式设计c#--行为型--interpreter

名称 Interpreter
结构 o_interpreter.bmp
意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
适用性
  • 当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:
  • 该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。
  • 效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。

Code Example
namespace Interpreter_DesignPattern
{
    
using System;
    
using System.Collections;

    
class Context 
    
{
        
    }


    
abstract class AbstractExpression 
    
{
        
abstract public void Interpret(Context c);
    }


    
// class for terminal symbol
    class TerminalExpression : AbstractExpression
    
{
        
override public void Interpret(Context c)    
        
{
            
        }

    }


    
// class for grammar rule (one per rule needed)
    class NonterminalExpression : AbstractExpression
    
{
        
override public void Interpret(Context c)    
        
{
            
        }
    
    }

    
// to extend grammar, just add other NonterminalExpression classes

    
/// <summary>
    
///    Summary description for Client.
    
/// </summary>

    public class Client
    
{
        
public static int Main(string[] args)
        
{
            Context c 
= new Context();
            ArrayList l 
= new ArrayList(); //really need a tree here!

            
// build up context information 
            
// . . .

            
// Populate abstract syntax tree with data
            l.Add(new TerminalExpression());
            l.Add(
new NonterminalExpression());

            
// interpret
            foreach (AbstractExpression exp in l)
            
{
                exp.Interpret(c);
            }

                    
            
return 0;
        }

    }

}


解析表达式:
// Interpreter pattern -- Real World example  


using System;
using System.Collections;

namespace DoFactory.GangOfFour.Interpreter.RealWorld
{

  
// MainApp test application 

  
class MainApp
  
{
    
static void Main()
    
{
      
string roman = "MCMXXVIII";
      Context context 
= new Context(roman);

      
// Build the 'parse tree' 
      ArrayList tree = new ArrayList();
      tree.Add(
new ThousandExpression());
      tree.Add(
new HundredExpression());
      tree.Add(
new TenExpression());
      tree.Add(
new OneExpression());

      
// Interpret 
      foreach (Expression exp in tree)
      
{
        exp.Interpret(context);
      }


      Console.WriteLine(
"{0} = {1}"
        roman, context.Output);

      
// Wait for user 
      Console.Read();
    }

  }


  
// "Context" 

  
class Context
  
{
    
private string input;
    
private int output;

    
// Constructor 
    public Context(string input)
    
{
      
this.input = input;
    }


    
// Properties 
    public string Input
    
{
      
getreturn input; }
      
set{ input = value; }
    }


    
public int Output
    
{
      
getreturn output; }
      
set{ output = value; }
    }

  }


  
// "AbstractExpression" 

  
abstract class Expression
  
{
    
public void Interpret(Context context)
    
{
      
if (context.Input.Length == 0
        
return;

      
if (context.Input.StartsWith(Nine()))
      
{
        context.Output 
+= (9 * Multiplier());
        context.Input 
= context.Input.Substring(2);
      }

      
else if (context.Input.StartsWith(Four()))
      
{
        context.Output 
+= (4 * Multiplier());
        context.Input 
= context.Input.Substring(2);
      }

      
else if (context.Input.StartsWith(Five()))
      
{
        context.Output 
+= (5 * Multiplier());
        context.Input 
= context.Input.Substring(1);
      }


      
while (context.Input.StartsWith(One()))
      
{
        context.Output 
+= (1 * Multiplier());
        context.Input 
= context.Input.Substring(1);
      }

    }


    
public abstract string One();
    
public abstract string Four();
    
public abstract string Five();
    
public abstract string Nine();
    
public abstract int Multiplier();
  }


  
// Thousand checks for the Roman Numeral M 
  
// "TerminalExpression" 

  
class ThousandExpression : Expression
  
{
    
public override string One() return "M"; }
    
public override string Four()return " "; }
    
public override string Five()return " "; }
    
public override string Nine()return " "; }
    
public override int Multiplier() return 1000; }
  }


  
// Hundred checks C, CD, D or CM 
  
// "TerminalExpression" 

  
class HundredExpression : Expression
  
{
    
public override string One() return "C"; }
    
public override string Four()return "CD"; }
    
public override string Five()return "D"; }
    
public override string Nine()return "CM"; }
    
public override int Multiplier() return 100; }
  }


  
// Ten checks for X, XL, L and XC 
  
// "TerminalExpression" 

  
class TenExpression : Expression
  
{
    
public override string One() return "X"; }
    
public override string Four()return "XL"; }
    
public override string Five()return "L"; }
    
public override string Nine()return "XC"; }
    
public override int Multiplier() return 10; }
  }


  
// One checks for I, II, III, IV, V, VI, VI, VII, VIII, IX 
  
// "TerminalExpression" 

  
class OneExpression : Expression
  
{
    
public override string One() return "I"; }
    
public override string Four()return "IV"; }
    
public override string Five()return "V"; }
    
public override string Nine()return "IX"; }
    
public override int Multiplier() return 1; }
  }

}

 
Output
MCMXXVIII = 1928

posted on 2006-01-03 16:02 梦在天涯 阅读(878) 评论(0)  编辑 收藏 引用 所属分类: Design pattern


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1785089
  • 排名 - 5

最新评论

阅读排行榜