3.3设计模式——Interpreter 解释器模式(行为型)

意图

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

结构

  • AbstractExpression声明一个程序的解释操作,这个接口为抽象语法树中所有结点所共享。
  • TerminalExpression实现与文法中的终结符相关联的解释操作;一个句子中的每个终结符都需要该类的一个实例。
  • NonterminalExpression对文法中的每一条规则都需要一个NonterminalExpression类;为每个符号都维护一个AbstractExpression类型的实例变量;为文法中的非终结符实现解释(Interpret)操作。
  • Context构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树,该抽象语法树由NonterminalExpression和TerminalExpression的实例装配而成;调用解释操作。

适用性

Interpreter模式适用于当有一个语言需要解释执行,并且可能将该语言中的句子表示为一个抽象语法树时,以下情况效果最好:

  • 该文法简单。对于复杂的发文,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具时更好的选择。它们无须构建抽象语法树即可解释表达式,这样可以节省空间还可能节省时间。
  • 效率不是一个关键问题。最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种形式。不过,即使在这种情况下,转换器仍然可用该模式实现。

代码示例

// 抽象表达式接口
interface AbstractExpression {
    Object interpret(Context context);
}

// 终结符表达式
class TerminalExpression implements AbstractExpression {
    private String literal;

    public TerminalExpression(String literal) {
        this.literal = literal;
    }

    @Override
    public Object interpret(Context context) {
        return literal;
    }
}

// 非终结符表达式
class NonterminalExpression implements AbstractExpression {
    private AbstractExpression leftExpression;
    private AbstractExpression rightExpression;

    public NonterminalExpression(AbstractExpression leftExpression, AbstractExpression rightExpression) {
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    @Override
    public Object interpret(Context context) {
        // TODO: 实现解释操作
        return null;
    }
}

// 上下文
class Context {
    private String input;
    private int index;

    public Context(String input) {
        this.input = input;
        this.index = 0;
    }

    public char currentChar() {
        return input.charAt(index);
    }

    public void nextChar() {
        index++;
    }
}

// 解释器
class ExpressionParser {
    private Context context;

    public ExpressionParser(String input) {
        this.context = new Context(input);
    }

    public AbstractExpression parse() {
        AbstractExpression expression = parseExpression();
        if (context.currentChar() != '\0') {
            throw new RuntimeException("Unexpected character: " + context.currentChar());
        }
        return expression;
    }

    private AbstractExpression parseExpression() {
        AbstractExpression leftExpression = parseTerm();
        while (context.currentChar() == '+') {
            context.nextChar();
            AbstractExpression rightExpression = parseTerm();
            leftExpression = new NonterminalExpression(leftExpression, rightExpression);
        }
        return leftExpression;
    }

    private AbstractExpression parseTerm() {
        if (Character.isDigit(context.currentChar())) {
            int number = 0;
            while (Character.isDigit(context.currentChar())) {
                number = number * 10 + (context.currentChar() - '0');
                context.nextChar();
            }
            return new TerminalExpression(String.valueOf(number));
        } else {
            throw new RuntimeException("Unexpected character: " + context.currentChar());
        }
    }
}

// 测试
public class Main {
    public static void main(String[] args) {
        String expression = "1+2+3";
        ExpressionParser parser = new ExpressionParser(expression);
        AbstractExpression parsedExpression = parser.parse();
        // TODO: 构建抽象语法树并调用解释操作
    }
}
  • AbstractExpression 接口: 定义所有表达式类必须实现的方法 interpret(Context context),用于解释表达式并返回结果。
  • TerminalExpression 类: 代表终结符表达式,存储一个字符串并返回其值。
  • NonterminalExpression 类: 代表非终结符表达式,存储两个子表达式并返回它们的加法结果。
  • Context 类: 存储输入字符串和当前解析位置,提供读取字符和移动位置的方法。
  • ExpressionParser 类: 解析输入字符串并生成表达式树,提供 parse() 方法解析整个表达式,以及 parseExpression() 和 parseTerm() 方法解析表达式和项。
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值