anchor.diff:  }
   
   @header{
  -    package platu.lpn.io;
  +    package verification.platu.lpn.io;
       
       import java.util.Map.Entry;
       import java.util.HashMap;
  
positive.code:     	}
      ;
  
  bitwiseNegation returns [ExpressionNode expr]
  	: 	{boolean neg = false;}
  		('~' {if(neg){neg = false;} else{neg = true;}})* unary
  			{
  				if(neg){
  					$expr = new BitNegNode($unary.expr);
  				}
  				else{
  					$expr = $unary.expr;
  
negative.code: 			}
  	;
  	
  mult returns [ExprTree expr] //[ExpressionNode expr]
      :   op1=negation {$expr = $op1.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 [ExprTree expr] //[ExpressionNode expr]
      :   op1=mult {$expr = $op1.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 [ExprTree expr]//[ExpressionNode expr]
      :   op1=add {$expr = $op1.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);}
      	)*
      ;
      
  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);}
      	)*
      ;
      
  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);}
      	)*
      ;
      
  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);}
      	)*
      ;
      
  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);}
      	)*
      ;
      
  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'.
      	)*
      ;
      
  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'.
      	)*
      ;
  
  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);}
      	)*
      ;
      
  expression returns [ExprTree expr] // [ExpressionNode expr]
      :   op1=implication {$expr = $op1.expr;}
      	('?' op2=expression ':' op3=expression 
      		{
      			//$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');
      		}
      	)?
      ;
  