定義:
給定一個語言读虏,定義它的文法的一種表示衙传,并定義一個解釋器吟吝,這個解釋器使用該表示來解釋語言中的句子-
UML:
image.png- AbstractExpression:定義解釋器的接口,約定解釋器的解釋操作菩佑。
- TerminalExpression:終結(jié)符解釋器自晰,用來實現(xiàn)語法規(guī)則中和終結(jié)符相關(guān)的操作,不再包含其他的解釋器稍坯。
- NonterminalExpression:非終結(jié)符解釋器缀磕,用來實現(xiàn)語法規(guī)則中非終結(jié)符相關(guān)的操作,通常一個解釋器對應(yīng)一個語法規(guī)則劣光,可以包含其他解釋器袜蚕。
- Context:上下文,通常包含各個解釋器需要的數(shù)據(jù)或是公共的功能绢涡。
- Client:客戶端牲剃,指的是使用解釋器的客戶端,通常在這里將按照語言的語法做的表達式轉(zhuǎn)換成使用解釋器對象描述的抽象語法樹雄可,然后調(diào)用解釋操作凿傅。
模型:四則運算+-實現(xiàn)
先使用巴科斯范式定義加減的語法:
expression ::= plus | minus | variable | number
plus ::= expression expression '+'
minus ::= expression expression '-'
variable ::= 'a' | 'b' | 'c' | ... | 'z'
digit = '0' | '1' | ... | '9'
number ::= digit | digit number
約定加減乘除使用逆波蘭表式語句如:
a b + -> a + b
a b c + - ->a - b + c
a b + c a - - ->a+b-c-a
抽象語句
interface Expression {
public int interpret(final Map<String, Expression> variables);
}
+語句處理類:
class Plus implements Expression {
//要記錄前后表達式
Expression leftOperand;
Expression rightOperand;
public Plus(final Expression left, final Expression right) {
leftOperand = left;
rightOperand = right;
}
public int interpret(final Map<String, Expression> variables) {
//具體操作前后表達式
return leftOperand.interpret(variables) + rightOperand.interpret(variables);
}
}
-語句處理類:
class Minus implements Expression {
Expression leftOperand;
Expression rightOperand;
public Minus(final Expression left, final Expression right) {
leftOperand = left;
rightOperand = right;
}
public int interpret(final Map<String, Expression> variables) {
return leftOperand.interpret(variables) - rightOperand.interpret(variables);
}
}
數(shù)字類:
class Number implements Expression {
private int number;
public Number(final int number) { this.number = number; }
public int interpret(final Map<String, Expression> variables) { return number; }
}
變量處理類:
class Variable implements Expression {
private String name;
public Variable(final String name) { this.name = name; }
public int interpret(final Map<String, Expression> variables) {
if (null == variables.get(name)) return 0; // Either return new Number(0).
return variables.get(name).interpret(variables);
}
}
設(shè)計一個能夠處理=-運算的計算器Client:
class Evaluator implements Expression {
//輸入的逆波蘭式語句
private Expression syntaxTree;
public Evaluator(final String expression) {
final Stack<Expression> expressionStack = new Stack<Expression>();
for (final String token : expression.split(" ")) {
if (token.equals("+")) {
//將前兩個表達式出棧生成新的+表達式
final Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());
expressionStack.push(subExpression);
} else if (token.equals("-")) {
final Expression right = expressionStack.pop();
final Expression left = expressionStack.pop();
final Expression subExpression = new Minus(left, right);
expressionStack.push(subExpression);
} else
//將終結(jié)表達式入棧
expressionStack.push(new Variable(token));
}
syntaxTree = expressionStack.pop();
}
public int interpret(final Map<String, Expression> context) {
return syntaxTree.interpret(context);
}
}
測試:
public class InterpreterExample {
public static void main(final String[] args) {
final String expression = "w x z - +";
final Evaluator sentence = new Evaluator(expression);
final Map<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));
final int result = sentence.interpret(variables);
System.out.println(result);
}
}
輸出:-27 ,執(zhí)行的是 5 + 10 - 42 = -27