Advertisement
Ladies_Man

EXPR BUILDER (6)

Nov 10th, 2014
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.65 KB | None | 0 0
  1. public interface Expr<T> {
  2.     void accept(ExprVisitor<T> v);
  3. }
  4.  
  5. public interface Neg<T> extends Expr<T> {
  6.     Expr<T> a();    // операнд унарного минуса
  7. }
  8.  
  9. public interface Binary<T> extends Expr<T> {
  10.     Expr<T> a();    // первый операнд
  11.         Expr<T> b();    // второй операнд
  12.         char operation(); // ’+’, ’-’, ’*’, ’/’
  13. }  
  14.  
  15. public interface Var<T> extends Expr<T> {
  16. }
  17.  
  18. public interface Const<T> extends Expr<T> {
  19.     T value();  // значение константы
  20. }
  21.  
  22. //========================================================================================
  23. //========================================================================================
  24. //========================================================================================
  25.  
  26. public interface AbstractExprFactory<T> {
  27.     Neg<T> newNeg(Expr<T> a);
  28.         Binary<T> newBinary(Expr<T> a, Expr<T> b, char operation);
  29.      Var<T> newVar();
  30.         Const<T> newConst(T value);
  31. }
  32.  
  33. public class ExprFactory<T> implements AbstractExprFactory<T> {
  34.     private class Neg1<T> implements Neg<T> {
  35.         private Expr<T> a1;
  36.         public Neg1 (Expr<T> a) {
  37.             this.a1 = a;
  38.         }
  39.         public Expr<T> a() {
  40.             return a1;
  41.         }
  42.         public void accept (ExprVisitor<T> v) {
  43.             v.visitNeg(this);
  44.         }
  45.     }
  46.  
  47.     private class Binary1<T> implements Binary<T> {
  48.         private Expr<T> a1;
  49.         private Expr<T> b1;
  50.         private char operation1;
  51.         public Binary1 (Expr<T> a, Expr<T> b, char operation) {
  52.             this.a1 = a;
  53.             this.b1 = b;
  54.             this.operation1 = operation;
  55.         }
  56.         public Expr<T> a() {
  57.             return a1;
  58.         }
  59.         public Expr<T> b() {
  60.             return b1;
  61.         }
  62.         public char operation() {
  63.             return operation1;
  64.         }
  65.         public void accept (ExprVisitor<T> v) {
  66.             v.visitBinary(this);
  67.         }
  68.     }
  69.    
  70.     private class Var1<T> implements Var<T> {
  71.         public void accept (ExprVisitor<T> v) {
  72.             v.visitVar(this);
  73.         }
  74.     }
  75.  
  76.     private class Const1<T> implements Const<T> {
  77.         private T value1;
  78.         public Const1 (T value) {
  79.             this.value1 = value;
  80.         }
  81.         public  T value () {
  82.             return value1;
  83.         }
  84.         public void accept (ExprVisitor<T> v) {
  85.             v.visitConst(this);
  86.         }
  87.     }
  88.     //==============================
  89.     public Neg<T> newNeg (Expr<T> a) {
  90.         return new Neg1<T>(a);
  91.     }
  92.  
  93.     public Binary<T> newBinary (Expr<T> a, Expr<T> b, char operation) {
  94.         return new Binary1<T>(a, b, operation);
  95.     }
  96.    
  97.     public Var<T> newVar () {
  98.         return new Var1<T>();
  99.     }
  100.  
  101.     public  Const<T> newConst (T value) {
  102.         return new Const1<T>(value);
  103.     }
  104. }
  105.  
  106. //========================================================================================
  107. //========================================================================================
  108. //========================================================================================
  109.  
  110. public interface ExprVisitor<T> {
  111.     void visitNeg(Neg<T> e);
  112.      void visitBinary(Binary<T> e);
  113.      void visitVar(Var<T> e);
  114.      void visitConst(Const<T> e);
  115. }
  116.  
  117. public class EvalVisitor implements ExprVisitor<Integer>{
  118.     private int res;
  119.     private int x1;
  120.    
  121.     public EvalVisitor(int x) {
  122.         this.x1 = x;
  123.     }
  124.    
  125.     public int eval (Expr<Integer> e) {
  126.         e.accept(this);     //recognize subexpression
  127.         return res;         //update result of it on level above
  128.     }
  129.    
  130.     public void visitNeg(Neg<Integer> e) {
  131.         res = -eval(e.a());
  132.     }
  133.    
  134.     public void visitBinary(Binary<Integer> e) {
  135.         if (e.operation() == '+') {
  136.             res = eval(e.a()) + eval(e.b());//dig into operand
  137.         } else if (e.operation() == '-') {  //to check if its subexpr
  138.                    res = eval(e.a()) - eval(e.b());
  139.                } else if (e.operation() == '*') {
  140.                           res = eval(e.a()) * eval(e.b());
  141.                       } else if (e.operation() == '/') {
  142.                                  res = eval(e.a()) / eval(e.b());
  143.                              }
  144.     }
  145.    
  146.     public void visitVar(Var<Integer> e) {
  147.         res = x1;   //cant dig deeper => get and return variable
  148.     }
  149.    
  150.     public void visitConst(Const<Integer> e) {
  151.         res = e.value();    // -||- => get and return constant
  152.     }
  153. }
  154.  
  155. //========================================================================================
  156. //========================================================================================
  157. //========================================================================================
  158.  
  159. public interface StackMachine {
  160.     // Положить константу в стек
  161.         void pushConst(int value);
  162.  
  163.     // Положить в стек значение переменной x
  164.         void pushVar();
  165.  
  166.     // Изменить знак числа на вершине стека
  167.         void neg();
  168.  
  169.     // Бинарные арифметические операции.
  170.     // Каждая операция снимает два операнда со стека
  171.     // и кладёт на стек результат
  172.         void add();     // сложение
  173.         void sub();     // вычитание
  174.         void mul();     // умножение
  175.         void div();     // деление
  176. }
  177.  
  178. public class ExprBuilder implements StackMachine{
  179.         private AbstractExprFactory<Integer> factory1;
  180.     private Expr a, b;
  181.     private Expr[] data;
  182.     private int top;
  183.    
  184.     public ExprBuilder (AbstractExprFactory<Integer> factory) {
  185.         data = new Expr[100];
  186.         this.factory1 = factory;
  187.         top = 0;
  188.     }
  189.  
  190.     public Expr<Integer> pop () {
  191.         return data[--top];
  192.     }
  193.    
  194.     public void pushConst (int value) {
  195.         data[top++] = factory1.newConst(value);
  196.     }
  197.    
  198.     public void pushVar() {
  199.         data[top++] = factory1.newVar();
  200.     }
  201.    
  202.     public void neg() {
  203.         this.a = pop();
  204.         data[top++] = factory1.newNeg(a);
  205.     }
  206.    
  207.     public void add() {
  208.         this.a = pop();
  209.         this.b = pop();
  210.         data[top++] = factory1.newBinary(a, b, '+');
  211.     }
  212.    
  213.     public void sub() {
  214.         this.a = pop();
  215.         this.b = pop();
  216.         data[top++] = factory1.newBinary(b, a, '-');
  217.     }
  218.    
  219.     public void mul() {
  220.         this.a = pop();
  221.         this.b = pop();
  222.         Binary<Integer> bin2 = factory1.newBinary(a, b, '*');
  223.         data[top++] = bin2;
  224.     }
  225.    
  226.     public void div() {
  227.         this.a = pop();
  228.         this.b = pop();
  229.         Binary<Integer> bin2 = factory1.newBinary(b, a, '/');
  230.         data[top++] = bin2;
  231.     }
  232.    
  233.     public Expr<Integer> result() {
  234.         return pop();
  235.     }
  236. }
  237.  
  238. //========================================================================================
  239. //========================================================================================
  240. //========================================================================================
  241.  
  242. public class Test
  243. {
  244.         public static void main(String[] args)
  245.         {
  246.                 try {
  247.                         java.util.Scanner input =
  248.                                 new java.util.Scanner(System.in);
  249.                         int x = input.nextInt();
  250.                         input.nextLine();
  251.                         String expr = input.nextLine();
  252.  
  253.                         ExprBuilder builder =
  254.                                 new ExprBuilder(new ExprFactory<Integer>());
  255.                         ParsingDirector dir = new ParsingDirector(builder);
  256.                         dir.parse(expr);
  257.  
  258.                         EvalVisitor v = new EvalVisitor(x);
  259.                         System.out.println(v.eval(builder.result()));
  260.                 } catch (java.lang.Exception e) {
  261.                         System.out.println("exception:␣" + e);
  262.                 }
  263.         }
  264. }
  265.  
  266. //========================================================================================
  267. //========================================================================================
  268. //========================================================================================
  269.  
  270. test1:
  271. => 50
  272. => 10-x
  273. <= -40
  274.  
  275. test2:
  276. => 50
  277. => 100-80-x
  278. <= -30
  279.  
  280. test3:
  281. => 20
  282. => -x+2*-(3+4*-(5+6*-(7+8*-(9+10*-(11+12)))))
  283. <= -85186
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement