定义

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

结构和说明

行为型模式-解释器模式 - 图1

示例代码

  1. public class InterpreterDemo {
  2. /**
  3. * 抽象表达式
  4. */
  5. public static abstract class AbstractExpression {
  6. /**
  7. * 解释的操作
  8. *
  9. * @param ctx
  10. * 上下文对象
  11. */
  12. public abstract void interpret(Context ctx);
  13. }
  14. /**
  15. * 终结符表达式
  16. */
  17. public static class TerminalExpression extends AbstractExpression {
  18. @Override
  19. public void interpret(Context ctx) {
  20. // 实现与语法规则中的终结符相关联的解释操作
  21. }
  22. }
  23. /**
  24. * 非终结符表达式
  25. */
  26. public static class NonterminalExpression extends AbstractExpression {
  27. @Override
  28. public void interpret(Context ctx) {
  29. // 实现与语法规则中的非终结符相关联的解释操作
  30. }
  31. }
  32. /**
  33. * 上下文,包含解释器之外的一些全局信息
  34. */
  35. public static class Context {
  36. }
  37. /**
  38. * 使用解释器的客户
  39. */
  40. public static class Client {
  41. // 主要按照语法规则对特定的句子构建抽象语法树
  42. // 然后调用解释操作
  43. }
  44. }

调用顺序

行为型模式-解释器模式 - 图2

优缺点

优点

  • 易于实现语法

在解释器模式中,一条语法规则用一个解释器对象来解释执行。对于解释器的实现来讲,功能就变得比较简单,只需要考虑这一条语法规则的实现就可以了,其他的都不用管。

  • 易于扩展新的语法

正是由于采用一个解释器对象负责一条语法规则的方式,使得扩展新的语法非常容易。扩展了新的语法,只需要增加新的解释器对象,在创建抽象语法树的时候使用这个新的解释器对象就可以。

缺点

  • 不适合复杂的语法

如果语法非常复杂,构建解释器模式需要的抽象语法树的工作是非常艰巨的,再加上还可能会构建多个抽象语法树。所以解析模式不太适合复杂的语法,对于复杂的语法,使用语法分析程序或编译器生成器可能会更好一些。

思考

本质

分离实现,解释执行。

何时选用

  • 当一个语言需要解释执行,并且可以讲该语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式。

在使用解释器模式的时候,还有两个特点需要考虑,一个是语法相对应该比较简单,太复杂的语法不太适合使用解释器模式;另一个效率要求不是很高,对效率要求很高的情况下,不适合使用解释器模式。

相关模式

TODO 后面补上。