@@ -0,0 +1,1986 @@
+package net.opentsdb.query.expression;%0A%0Aimport com.google.common.base.Preconditions;%0A%0Apublic class ExpressionReader %7B%0A%0A  protected final char%5B%5D chars;%0A%0A  private int mark = 0;%0A%0A  public ExpressionReader(char%5B%5D chars) %7B%0A      Preconditions.checkNotNull(chars);%0A      this.chars = chars;%0A  %7D%0A%0A  public int getMark() %7B%0A      return mark;%0A  %7D%0A%0A  public char peek() %7B%0A      return chars%5Bmark%5D;%0A  %7D%0A%0A  public char next() %7B%0A      return chars%5Bmark++%5D;%0A  %7D%0A%0A  public void skip(int num) %7B%0A      mark+=num;%0A  %7D%0A%0A  public boolean isNextChar(char c) %7B%0A      return peek() == c;%0A  %7D%0A%0A  public boolean isNextSeq(CharSequence seq) %7B%0A      Preconditions.checkNotNull(seq);%0A      for (int i=0; i%3Cseq.length(); i++) %7B%0A          if (mark+i == chars.length) return false;%0A          if (chars%5Bmark+i%5D != seq.charAt(i)) %7B%0A              return false;%0A          %7D%0A      %7D%0A%0A      return true;%0A  %7D%0A%0A  public String readFuncName() %7B%0A      StringBuilder builder = new StringBuilder();%0A      while (peek() != '(' && !Character.isWhitespace(peek())) %7B%0A          builder.append(next());%0A      %7D%0A      return builder.toString();%0A  %7D%0A%0A  public boolean isEOF() %7B%0A      return mark == chars.length;%0A  %7D%0A%0A  public void skipWhitespaces() %7B%0A      for (int i=mark; i%3Cchars.length; i++) %7B%0A          if (Character.isWhitespace(chars%5Bi%5D)) %7B%0A              mark++;%0A          %7D else %7B%0A              break;%0A          %7D%0A      %7D%0A  %7D%0A%0A  public String readNextParameter() %7B%0A      StringBuilder builder = new StringBuilder();%0A      int numNested = 0;%0A      while (!Character.isWhitespace(peek())) %7B%0A          char ch = peek();%0A          if (ch == '(') numNested++;%0A          else if (ch == ')') numNested--;%0A          if (numNested %3C 0) %7B%0A              break;%0A          %7D%0A          if (numNested %3C= 0 && isNextSeq(%22,,%22)) %7B%0A              break;%0A          %7D%0A          builder.append(next());%0A      %7D%0A      return builder.toString();%0A  %7D%0A%0A  @Override%0A  public String toString() %7B%0A      // make a copy%0A      return new String(chars);%0A  %7D%0A%0A%7D%0A

Add the ExpressionReader class for parsing expressions.