行为型模式之解释器模式

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文.
这种模式被用在 SQL 解析、符号处理引擎等。

模式结构和说明

在这里插入图片描述

解释器模式主要包括以下几个角色:
AbstractExpression:抽象表达式.声明一个抽象的解释操作,该接口为抽象语法树种所有的节点共享
TerminalExpression:终结符表达式.实现与文法中的终结符相关的解释操作.实现抽象表达式中所要求的方法.文法中每一个终结符都有一个具体的终结表达式与之相对应
NonterminalExpression:非终结符表达式。为文法中的非终结符相关的解释操作
Context:环境类.包含解释器之外的一些全局信息

抽象语法树描述了图和构成一个复杂的句子,通过对抽象语法树的分析,可以识别出语言中的终结符和非终结符.在解释器模式中由于每一种终结符表达式,非终结符表达式都会有一个具体的实例与之相对应,多以系统的扩展性比较好

示例代码

现在我们用解释器模式来实现一个基本的加、减、乘、除和求模运算。例如用户输入表达式“3 * 4 / 2 % 4”,输出结果为2

  1. 定义抽象表达式node
@implementation Node

- (int)interpret
{
    return 0;
}
@end

从上面的表达式可以,终结符有两种,一种是数字,另一个中是变量
2. 定义终结符表达式

@implementation ValueNode

+ (instancetype)valueNodeWithValue:(int)value
{
    ValueNode  *node = [[ValueNode alloc] init];
    node.value = value;
    return node;
}

- (int)interpret
{
    return self.value;
}
@end
@implementation SymbolNode

+ (instancetype)symbolNodeWithLeft:(Node *)left right:(Node *)right
{
    SymbolNode *node = [[[self class] alloc] init];
    node.leftN = left;
    node.rightN = right;
    return node;
}
@end
  1. 定义非终结表达式
@implementation MulNode

- (int)interpret
{
    return self.leftN.interpret * self.rightN.interpret;
}
@end
@implementation ModNode
- (int)interpret
{
    return self.leftN.interpret % self.rightN.interpret;
}
@end
@implementation DivNode

- (int)interpret
{
    return self.leftN.interpret / self.rightN.interpret;
}
@end
  1. 客户端使用
  Node *left = nil;
    Node *right = nil;
    NSMutableArray *nodeArr = [NSMutableArray array];
    NSString *str = @"3 * 4 / 2";
    NSArray *stateArr = [str componentsSeparatedByString:@" "];
    for (int i = 0; i < stateArr.count; i++) {
        if ([stateArr[i] isEqualToString:@"*"]) {
            left = nodeArr.lastObject;
            int value = [stateArr[++i] intValue];
            right = [ValueNode valueNodeWithValue:value];
            [nodeArr addObject:[MulNode symbolNodeWithLeft:left right:right]];
        } else if ([stateArr[i] isEqualToString:@"/"]){
            left = nodeArr.lastObject;
            int value = [stateArr[++i] intValue];
            right = [ValueNode valueNodeWithValue:value];
            [nodeArr addObject:[DivNode symbolNodeWithLeft:left right:right]];
        }else if ([stateArr[i] isEqualToString:@"%"]){
            left = nodeArr.lastObject;
            int value = [stateArr[++i] intValue];
            right = [ValueNode valueNodeWithValue:value];
            [nodeArr addObject:[ModNode symbolNodeWithLeft:left right:right]];
        } else {
        int value = [stateArr[i] intValue];
            [nodeArr addObject:[ValueNode valueNodeWithValue:value]];
        }
    }
    SymbolNode *node = nodeArr.lastObject;
    NSLog(@"最终的值为%d",[node interpret]);

模式讲解

优点

灵活的扩展性,想扩展语法规则时只需新增新的解释器就可以了。如上面的例子中,想增加乘除法,只想增加相应的解释类,并增加相应的表达式解释操作即可

缺点

  • 每一个文法都至少对应一个解释器,会产生大量的类,难于维护。
  • 解释器模式由于大量使用循环和递归,需要考虑效率的问题,而且调试也不方便。
  • 对于复杂的文法,构建其抽象语法树会显得异常繁琐。
  • 所以不推荐在重要的模块中使用解释器模式,维护困难。

总结

解释器模式使用解释器对象来表示和处理相应的语法规则,一般一个解释器处理一条语法规则。理论上来说,只要能用解释器对象把符合语法的表达式表示出来,而且能够构成抽象的语法树,那都可以使用解释器模式来处理。

Demo地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值