给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。
【角色】
- 抽象解释器(AbstractExpression):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
- 终结解释器(TerminalExpression):实现与文法中的终结符相关联的解释操作。一个句子中的每一个终结符需要该类的一个实例。
- 非终结解释器(NonterminalExpression):对文法中的规则的解释操作。
- 环境角色(Context):包含解释器之外的一些全局信息。
【优点】
- 扩展性好,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
【缺点】
- 会引起类膨胀。
- 采用递归调用方法,将会导致调试非常复杂。
使用了大量的循环和递归,效率是一个不容忽视的问题。
/*** 抽象表达式类(抽象解释器)*/public abstract class Expression {/*** 解释表达式*/abstract int interpreter(Map<String, Integer> var);}
/*** 变量解释器(终结解释器)*/public class VarExpression extends Expression {private String key;public VarExpression(String key) {this.key = key;}@Overrideint interpreter(Map<String, Integer> var) {return var.get(this.key);}}
/*** 符号解释器(非终结解释器)*/public class SymbolExpression extends Expression {protected Expression left;protected Expression right;public SymbolExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overrideint interpreter(Map<String, Integer> var) {return 0;}}
/*** 加号解析器*/public class AddExpression extends SymbolExpression {public AddExpression(Expression left, Expression right) {super(left, right);}@Overrideint interpreter(Map<String, Integer> var) {return left.interpreter(var) + right.interpreter(var);}}
/*** 减号解析器*/public class SubExpression extends SymbolExpression {public SubExpression(Expression left, Expression right) {super(left, right);}@Overrideint interpreter(Map<String, Integer> var) {return left.interpreter(var) - right.interpreter(var);}}
/*** 计算器(环境角色)*/public class Calculator {private Expression expression;/*** 构建计算器*/public Calculator(String expStr) {// 运算先后顺序Stack<Expression> stack = new Stack<>();// 表达式拆分为字符数组char[] charArray = expStr.toCharArray();Expression left = null;Expression right = null;for (int i = 0; i < charArray.length; i++) {switch (charArray[i]) {case '+':left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new AddExpression(left, right));break;case '-':left = stack.pop();right = new VarExpression(String.valueOf(charArray[++i]));stack.push(new SubExpression(left, right));break;default:stack.push(new VarExpression(String.valueOf(charArray[i])));break;}}this.expression = stack.pop();}/*** 运算*/public int run(Map<String, Integer> var) {return this.expression.interpreter(var);}}
public class InterpreterTest {public static void main(String[] args) {// 计算器String expStr = "a+b-c";Calculator calculator = new Calculator(expStr);Map<String, Integer> var = new HashMap<>();var.put("a", 10);var.put("b", 4);var.put("c", 6);System.out.println("表达式:" + expStr + "=" + calculator.run(var));}}----输出----表达式:a+b-c=8
