zoukankan      html  css  js  c++  java
  • 解释器模式

    问题:
    解释器模式就是用“迷你语言”来表现程序要解决的问题,以“迷你语言”写成“迷你程序”来表现具体的问题,例如正则表达式就是一个很好的例子。所以,通常当有一个语言需要解释执行,并且可以将该语言中的句子表示为一个抽象语法树时,就可以使用解释器模式了。

    概念:
    给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    实现:
    1. 类图示例:

    2. 代码示例:(实现一个迷你语言解释器)

    //表达文本类
    class InterpreterContext
    {
    	private $expressionstore = [];
    
    	public function replace(Expression $exp, $value)
    	{
    		$this->expressionstore[$exp->getKey()] = $value;
    	}
    
    	public function lookup(Expression $exp)
    	{
    		return $this->expressionstore[$exp->getKey()];
    	}
    }
    //表达式基类
    abstract class Expression
    {
    	private static $keycount = 0;
    	private $key;
    	abstract public function interpret(InterpreterContext $context);
    
    	public function getKey()
    	{
    		if(!isset($this->key)) {
    			self::$keycount ++;
    			$this->key = self::$keycount;
    		}
    		return $this->key;
    	}
    }
    //字符串表达式类
    class LiteralExpression extends Expression
    {
    	private $value;
    
    	public function __construct($value)
    	{
    		$this->value = $value;
    	}
    
    	public function interpret(InterpreterContext $context)
    	{
    		$context->replace($this, $this->value);
    	}
    }
    //变量表达式类
    class VariableExpression extends Expression
    {
    	private $name;
    	private $val;
    
    	public function __construct($name, $val = null)
    	{
    		$this->name = $name;
    		$this->val = $val;
    	}
    
    	public function interpret(InterpreterContext $context)
    	{
    		if(!is_null($this->val)) {
    			$context->replace($this, $this->val);
    			$this->val = null;
    		}
    	}
    
    	public function setValue($value)
    	{
    		$this->val = $value;
    	}
    
    	public function getKey()
    	{
    		return $this->name;
    	}
    }
    //操作符表达式基类
    abstract class OperatorExpression extends Expression
    {
    	protected $l_op;
    	protected $r_op;
    
    	public function __construct(Expression $l_op, Expression $r_op)
    	{
    		$this->l_op = $l_op;
    		$this->r_op = $r_op;
    	}
    
    	public function interpret(InterpreterContext $context)
    	{
    		$this->l_op->interpret($context);
    		$this->r_op->interpret($context);
    		$result_l = $context->lookup($this->l_op);
    		$result_r = $context->lookup($this->r_op);
    		$this->doInterpret($context, $result_l, $result_r);
    	}
    
    	abstract protected function doInterpret(InterpreterContext $context, $result_l, $result_r);
    }
    //相等表达式类
    class EqualsExpression extends OperatorExpression
    {
    	protected function doInterpret(InterpreterContext $context, $result_l, $result_r)
    	{
    		$context->replace($this, $result_l == $result_r);
    	}
    }
    //布尔或表达式类
    class BooleanOrExpression extends OperatorExpression
    {
    	protected function doInterpret(InterpreterContext $context, $result_l, $result_r)
    	{
    		$context->replace($this, $result_l || $result_r);
    	}
    }
    //布尔与表达式类
    class BooleanAndExpression extends OperatorExpression
    {
    	protected function doInterpret(InterpreterContext $context, $result_l, $result_r)
    	{
    		$context->replace($this, $result_l && $result_r);
    	}
    }
    
    //应用:$input equals "4" or $input equals "four"
    $context = new InterpreterContext();
    $input = new VariableExpression('input');
    $statement = new BooleanOrExpression(
    	new EqualsExpression($input, new LiteralExpression('four')),
    	new EqualsExpression($input, new LiteralExpression('4'))
    );
    foreach(['four', '4', '52'] as $val) {
    	$input->setValue($val);
    	echo $val, ':';
    	$statement->interpret($context);
    	if($context->lookup($statement)) {
    		echo 'Yes<br>';
    	} else {
    		echo 'No<br>';
    	}
    }
    

    注:示例代码中同时也使用了模板方法模式和组合模式。

    效果:
    创建了解释器的核心类后,解释器很容易进行扩展。但是解释器模式为文法中的每一条规则至少定义了一个类,当语言变得复杂,文法包含的规则很多时,需要创建的类的数量会很快增加,因此解释器模式最好应用于相对小的语言。

  • 相关阅读:
    JavaEE(9)
    微信公众平台自定义菜单接口API指南
    企业微信公众平台建设指南
    微信公众平台消息接口开发(13)多语种互译
    PHP 挖掘 XML 和 HTML 数据
    微信公众平台消息接口开发(12)消息接口Bug
    微信公众平台通用接口API指南
    微信公众平台消息接口API指南
    JavaEE(8)
    JavaEE(7)
  • 原文地址:https://www.cnblogs.com/wujuntian/p/9657388.html
Copyright © 2011-2022 走看看