anchor.diff:  			}
   	;
   	
  -mult returns [ExpressionNode expr]
  +mult returns [ExprTree expr] //[ExpressionNode expr]
       :   op1=negation {$expr = $op1.expr;} 
  -    	(	'*' op2=negation {$expr = new MultNode($expr, $op2.expr);}
  -    	|	'/' op2=negation {$expr = new DivNode($expr, $op2.expr);}
  -    	|	'%' op2=negation {$expr = new ModNode($expr, $op2.expr);}
  +    	(	'*' op2=negation {$expr = new ExprTree($expr, $op2.expr, "*", 'a');}//{$expr = new MultNode($expr, $op2.expr);}
  +    	|	'/' op2=negation {$expr = new ExprTree($expr, $op2.expr, "/", 'a');}//{$expr = new DivNode($expr, $op2.expr);}
  +    	// TODO: Line below fails to compile
  +    	// |	'%' op2=negation {$expr = new ExprTree($expr, $op2.expr, "%", 'a');}//{$expr = new ModNode($expr, $op2.expr);}
       	)*
       ;
       
  -add returns [ExpressionNode expr]
  +add returns [ExprTree expr] //[ExpressionNode expr]
       :   op1=mult {$expr = $op1.expr;}
  -    	(	'+' op2=mult {$expr = new AddNode($expr, $op2.expr);}
  -    	| 	'-' op2=mult {$expr = new SubNode($expr, $op2.expr);}
  +    	(	'+' op2=mult {$expr = new ExprTree($expr, $op2.expr, "+", 'a');}//{$expr = new AddNode($expr, $op2.expr);}
  +    	| 	'-' op2=mult {$expr = new ExprTree($expr, $op2.expr, "-", 'a');}//{$expr = new SubNode($expr, $op2.expr);}
       	)*
       ;
       
  -shift returns [ExpressionNode expr]
  +shift returns [ExprTree expr]//[ExpressionNode expr]
       :   op1=add {$expr = $op1.expr;}
  -    	(	'<<' op2=add {$expr = new LeftShiftNode($expr, $op2.expr);}
  -    	| 	'>>' op2=add {$expr = new RightShiftNode($expr, $op2.expr);}
  +      ( '<<' op2=add {$expr = new ExprTree(new ExprTree("int(" + $op1.text + ")"), new ExprTree(new ExprTree("2"), $op2.expr, "^", 'a'), "*", 'a');}
  +      |   '>>' op2=add {$expr = new ExprTree(new ExprTree("int(" + $op1.text + ")"), new ExprTree(new ExprTree("2"), $op2.expr, "^", 'a'), "/", 'a');}
  +      )*
  +//    	(	'<<' op2=add {$expr = new LeftShiftNode($expr, $op2.expr);}
  +//    	| 	'>>' op2=add {$expr = new RightShiftNode($expr, $op2.expr);}
  +//    	)*
  +    ;
  +
  +relation returns [ExprTree expr]//[ExpressionNode expr]
  +    :   op1=shift {$expr = $op1.expr;}
  +    	(	'<' op2=shift {$expr = new ExprTree($expr, $op2.expr, "<", 'r');}//{$expr = new LessNode($expr, $op2.expr);}
  +    	| 	'<=' op2=shift {$expr = new ExprTree($expr, $op2.expr, "<=", 'r');}//{$expr = new LessEqualNode($expr, $op2.expr);}
  +    	| 	'>=' op2=shift {$expr = new ExprTree($expr, $op2.expr, ">=", 'r');}//{$expr = new GreatEqualNode($expr, $op2.expr);}
  +    	| 	'>' op2=shift {$expr = new ExprTree($expr, $op2.expr, ">", 'r');}//{$expr = new GreatNode($expr, $op2.expr);}
       	)*
       ;
  -
  -relation returns [ExpressionNode expr]
  -    :   op1=shift {$expr = $op1.expr;}
  -    	(	'<' op2=shift {$expr = new LessNode($expr, $op2.expr);}
  -    	| 	'<=' op2=shift {$expr = new LessEqualNode($expr, $op2.expr);}
  -    	| 	'>=' op2=shift {$expr = new GreatEqualNode($expr, $op2.expr);}
  -    	| 	'>' op2=shift {$expr = new GreatNode($expr, $op2.expr);}
  +    
  +equivalence returns [ExprTree expr] // [ExpressionNode expr]
  +    :   op1=relation {$expr = $op1.expr;}
  +    	(	'==' op2=relation {$expr = new ExprTree($expr, $op2.expr, "=", 'r');}//{$expr = new EquivNode($expr, $op2.expr);}
  +    	// TODO: Not equal to in our LPN?
  +    	|	'!=' op2=relation {$expr = new ExprTree(new ExprTree($expr, $op2.expr, "=", 'r'), null, "~", 'l');}//{$expr = new NotEquivNode($expr, $op2.expr);}
       	)*
       ;
       
  -equivalence returns [ExpressionNode expr]
  -    :   op1=relation {$expr = $op1.expr;}
  -    	(	'==' op2=relation {$expr = new EquivNode($expr, $op2.expr);}
  -    	|	'!=' op2=relation {$expr = new NotEquivNode($expr, $op2.expr);}
  +bitwiseAnd returns [ExprTree expr]//[ExpressionNode expr]
  +    :   op1=equivalence {$expr = $op1.expr;} 
  +    	(	'&' op2=equivalence {$expr = new ExprTree($expr, $op2.expr, "&", 'w');}//{$expr = new BitAndNode($expr, $op2.expr);}
       	)*
       ;
       
  -bitwiseAnd returns [ExpressionNode expr]
  -    :   op1=equivalence {$expr = $op1.expr;} 
  -    	(	'&' op2=equivalence {$expr = new BitAndNode($expr, $op2.expr);}
  +bitwiseXor returns [ExprTree expr]//[ExpressionNode expr]
  +    :   op1=bitwiseAnd {$expr = $op1.expr;}
  +    	(	'^' op2=bitwiseAnd {$expr = new ExprTree($expr, $op2.expr, "X", 'w');}//{$expr = new BitXorNode($expr, $op2.expr);}
       	)*
       ;
       
  -bitwiseXor returns [ExpressionNode expr]
  -    :   op1=bitwiseAnd {$expr = $op1.expr;}
  -    	(	'^' op2=bitwiseAnd {$expr = new BitXorNode($expr, $op2.expr);}
  +bitwiseOr returns [ExprTree expr]//[ExpressionNode expr]
  +    :   op1=bitwiseXor {$expr = $op1.expr;}
  +    	(	'|' op2=bitwiseXor {$expr = new ExprTree($expr, $op2.expr, "|", 'w');}//{$expr = new BitOrNode($expr, $op2.expr);}
       	)*
       ;
       
  -bitwiseOr returns [ExpressionNode expr]
  -    :   op1=bitwiseXor {$expr = $op1.expr;}
  -    	(	'|' op2=bitwiseXor {$expr = new BitOrNode($expr, $op2.expr);}
  +and returns [ExprTree expr] //[ExpressionNode expr]
  +    :   op1=bitwiseOr {$expr = $op1.expr;}
  +    	(	'&&' op2=bitwiseOr {$expr = new ExprTree($expr, $op2.expr, "&&", 'l');}//{$expr = new AndNode($expr, $op2.expr);}
  +    	// TODO: Temporarily set the type to 'l'.
       	)*
       ;
       
  -and returns [ExpressionNode expr]
  -    :   op1=bitwiseOr {$expr = $op1.expr;}
  -    	(	'&&' op2=bitwiseOr {$expr = new AndNode($expr, $op2.expr);}
  +or returns [ExprTree expr]//[ExpressionNode expr]
  +    :   op1=and {$expr = $op1.expr;}
  +    	(	'||' op2=and {$expr = new ExprTree($expr, $op2.expr, "||", 'l');}//{$expr = new OrNode($expr, $op2.expr);}
  +    	// TODO: Temporarily set the type to 'l'.
       	)*
       ;
  -    
  -or returns [ExpressionNode expr]
  -    :   op1=and {$expr = $op1.expr;}
  -    	(	'||' op2=and {$expr = new OrNode($expr, $op2.expr);}
  +
  +implication returns [ExprTree expr] //[ExpressionNode expr]
  +    :	op1=or {$expr = $op1.expr;}//{$expr = $op1.expr;}
  +    	(	'->' op2=or  {$expr = new ExprTree($expr, $op2.expr, "->", 'l');}//{$expr = new ImplicationNode($expr, $op2.expr);}
       	)*
       ;
  -
  -implication returns [ExpressionNode expr]
  -    :	op1=or {$expr = $op1.expr;}
  -    	(	'->' op2=or  {$expr = new ImplicationNode($expr, $op2.expr);}
  -    	)*
  -    ;
  -    
  -expression returns [ExpressionNode expr]
  +    
  +expression returns [ExprTree expr] // [ExpressionNode expr]
       :   op1=implication {$expr = $op1.expr;}
       	('?' op2=expression ':' op3=expression 
       		{
  -    			$expr = new TernaryNode($expr, $op2.expr, $op3.expr);
  +    			//$expr = new TernaryNode($expr, $op2.expr, $op3.expr);
  +    			// op1?op2:op3 == int(op1)*op2+int(~op1)*op3
  +    			//$expr = new ExprTree($expr);
  +    			$expr = new ExprTree(new ExprTree(new ExprTree("int("+$op1.text + ")"), $op2.expr, "*", 'a'), 
  +    			                     new ExprTree(new ExprTree("int(~("+$op1.text + "))"), $op3.expr, "*", 'a'), 
  +    			                     "+", 'a');
       		}
       	)?
       ;
  
positive.code: }
  
  @header{
      package platu.lpn.io;
      
      import java.util.Map.Entry;
      import java.util.HashMap;
  
negative.code: 					for(int i = 0; i < arraySize; i++){
  						String name = $arrayName.text + varCount++;
  						int index = VariableIndex++;
  						//VarNode v = new VarNode(name, index);
  						ExprTree v = new ExprTree(name);
  						array.add(v);
  						
  						// add variable and value to state vector
  						StatevectorMap.put(name, 0);
  						
  						// generate variable index and create new var node  
  		   			VarIndexMap.insert(name, index);
  					}
  					// TODO: ArrayNodeMap? 
  //					ArrayNodeMap.put($arrayName.text, new ArrayNode($arrayName.text, array, 1));
  					VarCountMap.put($arrayName.text, 0);
  				}
  