- Intent
to define a representation of the grammar of a given language, along with an interpreter that use this representation to interpret sentences in the language.
- Benefits
- It's easier to change and extend the grammar.
- Implementing the grammar is straightforward.
- 適用情境
- The grammar of the language is not complicated.
- Efficiency is not a priority.
- Class Diagram
[caption id="attachment_239" align="alignnone" width="548" caption="Interpreter pattern"][/caption]
- Sample Code
這個範例大概是最近看來比較辛苦的,居然出現了直譯器這個詞,想當初compiler課程我可是將近直接放棄XD,雖然老師上課很偉大都給openbook exam,但還是很多人直接退選了,因為真的有難度!!
下面是一個 Reverse Polish notation,這個表示式真實的呈現了直譯器模式的核心意涵。
grammar expression as below
expression ::= plus | minus | ariable | number
plus ::= expression expression '+'
minus ::= expression expression '-'
variable ::= 'a' | 'b' | 'c' | ... | 'z'
digit = '0'| '1'| ... '9'
number ::= digit | digit number
以下是要展示的語法輸入內涵,將透過範例程式做更明確的實質內容呈現( interprete it )
a b + // i.e a+b
a b c + - // i.e a+b-c
a b + c a - - /// i.e a+b-c-apackage interpreter;
import java.util.HashMap;
import java.util.Stack;
interface Expression {
public int interpret(HashMap<String, Expression> variables);
}
class Number implements Expression {
private int number;
public Number(int number) {
this.number = number;
}
@Override
public int interpret(HashMap<String, Expression> variables) {
// TODO Auto-generated method stub
return number;
}
}
class Plus implements Expression {
Expression leftOperand;
Expression rightOperand;
public Plus(Expression left, Expression right) {
this.leftOperand = left;
this.rightOperand = right;
}
public int interpret(HashMap<String, Expression> variables) {
return this.leftOperand.interpret(variables) + this.rightOperand.interpret(variables);
}
}
class Minus implements Expression {
Expression leftOperand;
Expression rightOperand;
public int interpret(HashMap<String, Expression> variables) {
return this.leftOperand.interpret(variables) - this.rightOperand.interpret(variables);
}
public Minus(Expression left, Expression right) {
this.leftOperand = left;
this.rightOperand = right;
}
}
class Variable implements Expression {
private String name;
public Variable(String name) {
this.name = name;
}
public int interpret(HashMap<String, Expression> variables) {
if (null == variables.get(name))
return 0;
return variables.get(name).interpret(variables);
}
}
class Evaluator implements Expression {
private Expression syntaxTree;
public Evaluator(String expression) {
Stack<Expression> expressionStack = new Stack<Expression>();
for (String token : expression.split(" ")) {
if (token.equals("+")) {
Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
expressionStack.push(subExpression);
} else if (token.equals("-")) {
// it's necessary remove first the right operand from the stack
Expression right = expressionStack.pop();
// ..and after the left one
Expression left = expressionStack.pop();
Expression subExpression = new Minus(left, right);
expressionStack.push(subExpression);
} else
expressionStack.push(new Variable(token));
}
syntaxTree = expressionStack.pop();
}
public int interpret(HashMap<String, Expression> context) {
return syntaxTree.interpret(context);
}
}
public class InterpreterPattern {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String expression = "w x z - +";
Evaluator sentence = new Evaluator(expression);
HashMap<String, Expression> variables = new HashMap<String, Expression>();
variables.put("w", new Number(5));
variables.put("x", new Number(10));
variables.put("z", new Number(42));
int result = sentence.interpret(variables);
System.out.println(result);
}
}
沒有留言:
張貼留言