原版设计模式之解释器模式(Interpreter)

Intent (定义)

Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.(给定一种语言,为其语法定义一个表示,以及一个使用该表示来解释该语言中的句子的解释器。

Motivation (举例)

For example, searching for strings that match a pattern is a common problem. Regular expressions are a standard language for specifying patterns of strings. Rather than building custom algorithms to match each pattern against strings, search algorithms could interpret a regular expression that specifies a set of strings to match.(例如,搜索匹配模式的字符串是一个常见的问题。正则表达式是用于指定字符串模式的标准语言。搜索算法可以解释指定一组匹配字符串的正则表达式,而不是构建自定义算法来将每个字符串与字符串进行匹配。

The Interpreter pattern describes how to define a grammar for simple languages, represent sentences in the language, and interpret these sentences. In this example, the pattern describes how to define a grammar for regular expressions, represent a particular regular expression, and how to interpret that regular expression.(解释器模式描述了如何为简单语言定义语法,在语言中表示句子,并解释这些句子。在本示例中,该模式描述了如何为正则表达式定义语法,表示一个特定的正则表达式,以及如何解释该正则表达式。

Suppose the following grammar defines the regular expressions:(假设以下语法定义了正则表达式:

expression ::= literal | alternation | sequence | repetition |
‘(’ expression ‘)’
alternation ::= expression ‘|’ expression
sequence ::= expression ‘&’ expression
repetition ::= expression '
literal ::= ‘a’ | ‘b’ | ‘c’ | … { ‘a’ | ‘b’ | ‘c’ | … }

The symbol expression is the start symbol, and literal is a terminal symbol defining simple words.(符号表达式是开始符号,文字是定义简单单词的终端符号。

The Interpreter pattern uses a class to represent each grammar rule. Symbols on the right-hand side of the rule are instance variables of these classes.(解释器模式使用一个类来表示每个语法规则。规则右侧的符号是这些类的实例变量。

The grammar above is represented by five classes: an abstract class RegularExpression and its four subclasses LiteralExpression, AlternationExpression, SequenceExpression,and RepetitionExpression.(上面的语法由五个类表示:一个抽象类RegularExpression【正则表达式】 及其四个子类LiteralExpression【文字表达式】,AlternationExpression【其他表达式】,SequenceExpression【序列表达式】,RepetitionExpression【重复表达式】

The last three classes define variables that hold subexpressions.(最后三个类定义了包含子表达形式的变量。
在这里插入图片描述
Every regular expression defined by this grammar is represented by an abstract syntax tree made up of instances of these classes. For example, the abstract syntax tree (由此语法定义的每个正则表达式都由这些类实例组成的抽象语法树表示。例如,抽象语法树
在这里插入图片描述
represents the regular expression (表示正则表达式
raining & (dogs | cats) *

We can create an interpreter for these regular expressions by defining the Interpret operation on each subclass of RegularExpression. Interpret takes as an argument the
context in which to interpret the expression. The context contains the input string and information on how much of it has been matched so far. Each subclass of RegularExpression implements Interpret to match the next part of the input string based on the current context. (我们可以通过对RegularExpression的每个子类定义解释操作来为这些正则表达式创建一个解释器。Interpret 将解释表达式的上下文作为一个参数。上下文包含输入字符串和到目前为止匹配了多少的信息。RegularExpression 的每个子类实现Interpret ,根据当前上下文以匹配输入字符串的下一部分。

For example,(例如

  • LiteralExpression will check if the input matches the literal it defines,(文字表达式将检查输入是否与它所定义的文字相匹配,
  • AlternationExpression will check if the input matches any of its alternatives,(其他表达式将检查输入是否匹配其任何可选项,
  • RepetitionExpression will check if the input has multiple copies of expression it repeats。(重复表达式将检查输入是否有多个它重复的表达式副本,

Applicability (适用点)

Use the Interpreter pattern when there is a language to interpret, and you can represent statements in the language as abstract syntax trees.(当有一种语言要解释时,请使用解释器模式,并且您可以将该语言中的语句表示为抽象语法树。

The Interpreter pattern works best when the grammar is simple.(当语法很简单时,解释器模式的效果最好。

For complex grammars, the class hierarchy for the grammar
becomes large and unmanageable. Tools such as parser generators are a better alternative in such cases. They can interpret expressions without building abstract syntax trees, which can save space and possibly time.(对于复杂的语法,语法的类层次结构会变得很大且无法管理。在这种情况下,解析器生成器等工具是一个更好的选择。它们可以解释表达式而不构建抽象语法树,这可以节省空间和时间。

efficiency is not a critical concern. The most efficient interpreters are usually not implemented by interpreting parse trees directly but by first translating them into another form. For example, regular expressions are often transformed into state machines. But even then, the translator can be implemented by the Interpreter pattern, so the pattern is still applicable.(提高效率并不是一个关键的问题。最有效的解释器通常不是通过直接解释解析树来实现的,而是首先将它们转换为另一种形式。例如,正则表达式经常被转换为状态机。但即便如此,翻译器也可以通过解释器模式来实现,因此该模式仍然适用。

Structure (结构)

在这里插入图片描述

Participants (参与者)

  • AbstractExpression (RegularExpression) (抽象表达式
    • declares an abstract Interpret operation that is common to all nodes in the abstract syntax tree.(声明一个对抽象语法树中的所有节点都通用的抽象解释操作。
  • TerminalExpression (LiteralExpression)(终端表达式
    • implements an Interpret operation associated with terminal symbols in the grammar.(实现了与语法中的终端符号关联的解释操作。
    • an instance is required for every terminal symbol in a sentence.(一个句子中的每个终端符号都需要一个实例。
  • NonterminalExpression (AlternationExpression, RepetitionExpression, SequenceExpressions)(非终端表达式
    • one such class is required for every rule R ::= R1 R2 … Rn in the grammar.(语法中的每个规则R::=R1 R2…Rn都需要这样的类。
    • maintains instance variables of type AbstractExpression for each of the symbols R1 through Rn.(为每个符号R1到Rn维护AbstractExpression 类型的实例变量。
    • implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.(为语法中的非终端符号实现了一个解释操作。解释通常通过Rn的变量递归调用自己。
  • Context (上下文
    • contains information that’s global to the interpreter.(包含解释器需要的全局信息。
  • Client (客户端
    • builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes.(构建(或给定)一个抽象的语法树,表示语法定义的语言中的特定句子。抽象语法树是由NonterminalExpression 和TerminalExpression 的实例组装而成的。
    • invokes the Interpret operation.(调用解释操作。

Collaborations (约定)

  • The client builds (or is given) the sentence as an abstract syntax tree of NonterminalExpression and TerminalExpression instances. Then the client initializes the context and invokes the Interpret operation.(客户端构建(或被给出)这个句子作为一个非终端表达式和终端表达式实例的抽象语法树。然后,客户端初始化上下文并调用解释操作。
  • Each NonterminalExpression node defines Interpret in terms of Interpret on each subexpression. The Interpret operation of each TerminalExpression defines the base case in the recursion.(每个NonterminalExpression 节点根据在每个子表达式上的解释来定义Interpret 。每个TerminalExpression 的解释操作定义了递归中的基本语法。
  • The Interpret operations at each node use the context to store and access the state of the interpreter.(每个节点上的解释操作都使用上下文来存储和访问解释器的状态

Related Patterns (相关模式)

Composite (183): The abstract syntax tree is an instance of the Composite pattern.(组合模式(183):抽象语法树是组合模式的一个实例。

Flyweight (218) shows how to share terminal symbols within the abstract syntax tree.(享元模式(218)展示了如何在抽象语法树中共享终端符号。

Iterator (289): The interpreter can use an Iterator to traverse the structure.(迭代器(289):解释器可以使用一个迭代器来遍历该结构。

Visitor (366) can be used to maintain the behavior in each node in the abstract syntax tree in one class.(访问者模式(366)可以用于维护一个类中的抽象语法树中的每个节点中的行为。

posted @ 2022-06-17 16:06  伟衙内  阅读(96)  评论(0编辑  收藏  举报