anchor.diff:      }
       ;
   
  -timestamp
  -    : DOUBLE | QUOTED_STRING
  -    ;
  +timestamp returns [DateTime t]
  +    : NUMBER {
  +        String str = $NUMBER.text.trim();
  +        try {
  +            $t = new DateTime(NumberFormat.getInstance().parse(str));
  +        }
  +        catch(ParseException e) {
  +            throw new IllegalArgumentException("Unable to parse number [" + str + "]");
  +        }
  +    }
  +    | QUOTED_STRING { $t = new DateTime(unescape($QUOTED_STRING.text)); }
  +    ;
  
positive.code: import com.metamx.druid.query.filter.*;
  import com.metamx.druid.query.dimension.*;
  import com.metamx.druid.*;
  import com.google.common.base.*;
  import com.google.common.collect.Lists;
  import java.util.*;
  import org.joda.time.*;
  }
  
  @parser::members {
  
negative.code:     ;
  
  constant returns [ConstantPostAggregator c]
      : value=NUMBER  { double v = Double.parseDouble($value.text); $c = new ConstantPostAggregator(Double.toString(v), v); }
      ;
  
  /* time filters must be top level filters */
  