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

    【角色】

    • 抽象解释器(AbstractExpression):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
    • 终结解释器(TerminalExpression):实现与文法中的终结符相关联的解释操作。一个句子中的每一个终结符需要该类的一个实例。
    • 非终结解释器(NonterminalExpression):对文法中的规则的解释操作。
    • 环境角色(Context):包含解释器之外的一些全局信息。

    【优点】

    • 扩展性好,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。

    【缺点】

    • 会引起类膨胀。
    • 采用递归调用方法,将会导致调试非常复杂。
    • 使用了大量的循环和递归,效率是一个不容忽视的问题。

      1. /**
      2. * 抽象表达式类(抽象解释器)
      3. */
      4. public abstract class Expression {
      5. /**
      6. * 解释表达式
      7. */
      8. abstract int interpreter(Map<String, Integer> var);
      9. }
      1. /**
      2. * 变量解释器(终结解释器)
      3. */
      4. public class VarExpression extends Expression {
      5. private String key;
      6. public VarExpression(String key) {
      7. this.key = key;
      8. }
      9. @Override
      10. int interpreter(Map<String, Integer> var) {
      11. return var.get(this.key);
      12. }
      13. }
      1. /**
      2. * 符号解释器(非终结解释器)
      3. */
      4. public class SymbolExpression extends Expression {
      5. protected Expression left;
      6. protected Expression right;
      7. public SymbolExpression(Expression left, Expression right) {
      8. this.left = left;
      9. this.right = right;
      10. }
      11. @Override
      12. int interpreter(Map<String, Integer> var) {
      13. return 0;
      14. }
      15. }
      1. /**
      2. * 加号解析器
      3. */
      4. public class AddExpression extends SymbolExpression {
      5. public AddExpression(Expression left, Expression right) {
      6. super(left, right);
      7. }
      8. @Override
      9. int interpreter(Map<String, Integer> var) {
      10. return left.interpreter(var) + right.interpreter(var);
      11. }
      12. }
      1. /**
      2. * 减号解析器
      3. */
      4. public class SubExpression extends SymbolExpression {
      5. public SubExpression(Expression left, Expression right) {
      6. super(left, right);
      7. }
      8. @Override
      9. int interpreter(Map<String, Integer> var) {
      10. return left.interpreter(var) - right.interpreter(var);
      11. }
      12. }
      1. /**
      2. * 计算器(环境角色)
      3. */
      4. public class Calculator {
      5. private Expression expression;
      6. /**
      7. * 构建计算器
      8. */
      9. public Calculator(String expStr) {
      10. // 运算先后顺序
      11. Stack<Expression> stack = new Stack<>();
      12. // 表达式拆分为字符数组
      13. char[] charArray = expStr.toCharArray();
      14. Expression left = null;
      15. Expression right = null;
      16. for (int i = 0; i < charArray.length; i++) {
      17. switch (charArray[i]) {
      18. case '+':
      19. left = stack.pop();
      20. right = new VarExpression(String.valueOf(charArray[++i]));
      21. stack.push(new AddExpression(left, right));
      22. break;
      23. case '-':
      24. left = stack.pop();
      25. right = new VarExpression(String.valueOf(charArray[++i]));
      26. stack.push(new SubExpression(left, right));
      27. break;
      28. default:
      29. stack.push(new VarExpression(String.valueOf(charArray[i])));
      30. break;
      31. }
      32. }
      33. this.expression = stack.pop();
      34. }
      35. /**
      36. * 运算
      37. */
      38. public int run(Map<String, Integer> var) {
      39. return this.expression.interpreter(var);
      40. }
      41. }
      1. public class InterpreterTest {
      2. public static void main(String[] args) {
      3. // 计算器
      4. String expStr = "a+b-c";
      5. Calculator calculator = new Calculator(expStr);
      6. Map<String, Integer> var = new HashMap<>();
      7. var.put("a", 10);
      8. var.put("b", 4);
      9. var.put("c", 6);
      10. System.out.println("表达式:" + expStr + "=" + calculator.run(var));
      11. }
      12. }
      13. ----输出----
      14. 表达式:a+b-c=8