001package iterator.exprone; 002import java.util.Iterator; 003import java.util.NoSuchElementException; 004import enumeration.Op; 005 006public interface Expr { 007 int evaluate(); 008 Iterator<Object> postorderIterator(); 009} 010 011class Const implements Expr { 012 private final int v; 013 public Const(int v) { 014 this.v = v; 015 } 016 017 public int evaluate() { 018 return v; 019 } 020 public Iterator<Object> postorderIterator() { 021 return new LeafIterator<>(v); 022 } 023} 024 025class BinOp implements Expr { 026 private final Expr l; 027 private final Expr r; 028 private final Op op; 029 030 public BinOp(Expr l, Op op, Expr r) { 031 if ((l == null) || (op == null) || (r == null)) { 032 throw new IllegalArgumentException(); 033 } 034 this.op = op; 035 this.l = l; 036 this.r = r; 037 } 038 039 public int evaluate() { 040 return op.eval(l.evaluate(), r.evaluate()); 041 } 042 public Iterator<Object> postorderIterator() { 043 return new PostorderIterator<> 044 (op, l.postorderIterator(), r.postorderIterator()); 045 } 046} 047 048 049class PostorderIterator<T> implements Iterator<T> { 050 private T v; 051 private final Iterator<T> l; 052 private final Iterator<T> r; 053 054 PostorderIterator(T v, Iterator<T> l, Iterator<T> r) { 055 this.v = v; 056 this.l = l; 057 this.r = r; 058 } 059 public boolean hasNext() { 060 return r.hasNext() || l.hasNext() || (v != null); 061 } 062 public T next() { 063 if (l.hasNext()) { 064 return l.next(); 065 } else if (r.hasNext()) { 066 return r.next(); 067 } else if (v != null) { 068 T result = this.v; 069 this.v = null; 070 return result; 071 } 072 throw new NoSuchElementException(); 073 } 074 public void remove() { 075 throw new UnsupportedOperationException(); 076 } 077} 078 079class LeafIterator<T> implements Iterator<T> { 080 private T v; 081 082 public LeafIterator(T v) { 083 this.v = v; 084 } 085 public boolean hasNext() { 086 return (v != null); 087 } 088 public T next() { 089 if (v != null) { 090 T result = this.v; 091 this.v = null; 092 return result; 093 } 094 throw new NoSuchElementException(); 095 } 096 public void remove() { 097 throw new UnsupportedOperationException(); 098 } 099}