
//----------------------------------------------------
// The following code was generated by CUP v0.10j
// Wed Jan 19 17:15:43 HKT 2005
//----------------------------------------------------

package net.tinyos.tinydb.parser;

import java_cup.runtime.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import net.tinyos.tinydb.*;

/** CUP v0.10j generated parser.
  * @version Wed Jan 19 17:15:43 HKT 2005
  */
public class senseParser extends java_cup.runtime.lr_parser {

  /** Default constructor. */
  public senseParser() {super();}

  /** Constructor which sets the default scanner. */
  public senseParser(java_cup.runtime.Scanner s) {super(s);}

  /** Production table. */
  protected static final short _production_table[][] = 
    unpackFromStrings(new String[] {
    "\000\102\000\002\002\004\000\002\003\005\000\002\003" +
    "\003\000\002\003\003\000\002\025\007\000\002\026\012" +
    "\000\002\026\011\000\002\026\007\000\002\033\003\000" +
    "\002\033\005\000\002\032\004\000\002\027\006\000\002" +
    "\027\002\000\002\031\005\000\002\031\003\000\002\030" +
    "\005\000\002\030\002\000\002\004\004\000\002\004\006" +
    "\000\002\005\005\000\002\005\003\000\002\006\005\000" +
    "\002\006\004\000\002\034\004\000\002\034\005\000\002" +
    "\010\003\000\002\010\005\000\002\011\005\000\002\011" +
    "\003\000\002\011\005\000\002\012\004\000\002\012\002" +
    "\000\002\013\005\000\002\013\003\000\002\023\004\000" +
    "\002\023\003\000\002\023\005\000\002\014\004\000\002" +
    "\014\005\000\002\014\002\000\002\015\005\000\002\015" +
    "\005\000\002\016\004\000\002\016\005\000\002\020\003" +
    "\000\002\020\003\000\002\017\004\000\002\017\002\000" +
    "\002\007\003\000\002\007\003\000\002\007\003\000\002" +
    "\007\003\000\002\007\003\000\002\007\003\000\002\021" +
    "\005\000\002\021\007\000\002\021\003\000\002\021\004" +
    "\000\002\021\002\000\002\022\007\000\002\022\004\000" +
    "\002\022\007\000\002\022\002\000\002\024\005\000\002" +
    "\024\007\000\002\024\003" });

  /** Access to production table. */
  public short[][] production_table() {return _production_table;}

  /** Parse-action table. */
  protected static final short[][] _action_table = 
    unpackFromStrings(new String[] {
    "\000\166\000\012\022\ufff5\036\011\040\004\043\007\001" +
    "\002\000\004\004\147\001\002\000\004\002\uffff\001\002" +
    "\000\004\002\146\001\002\000\004\002\ufffe\001\002\000" +
    "\004\022\025\001\002\000\004\004\012\001\002\000\006" +
    "\006\014\011\ufff1\001\002\000\004\011\022\001\002\000" +
    "\004\004\016\001\002\000\004\005\021\001\002\000\006" +
    "\005\ufff3\010\017\001\002\000\004\004\016\001\002\000" +
    "\004\005\ufff4\001\002\000\004\011\ufff2\001\002\000\004" +
    "\022\ufff6\001\002\000\006\002\uffc3\034\134\001\002\000" +
    "\024\002\uffe2\005\uffe2\023\062\024\uffe2\025\uffe2\027\uffe2" +
    "\031\uffe2\032\uffe2\034\uffe2\001\002\000\004\004\031\001" +
    "\002\000\006\004\031\006\052\001\002\000\030\002\uffed" +
    "\005\uffed\010\uffed\023\uffed\024\uffed\025\uffed\027\uffed\031" +
    "\uffed\032\uffed\034\uffed\042\uffed\001\002\000\050\002\uffe8" +
    "\005\uffe8\010\uffe8\014\uffe8\015\uffe8\016\uffe8\017\uffe8\020" +
    "\uffe8\021\uffe8\023\uffe8\024\uffe8\025\uffe8\027\uffe8\031\uffe8" +
    "\032\uffe8\033\046\034\uffe8\042\uffe8\044\uffe8\001\002\000" +
    "\054\002\uffe5\005\uffe5\006\037\007\040\010\uffe5\014\uffe5" +
    "\015\uffe5\016\uffe5\017\uffe5\020\uffe5\021\uffe5\023\uffe5\024" +
    "\uffe5\025\uffe5\027\uffe5\031\uffe5\032\uffe5\033\uffe5\034\uffe5" +
    "\042\uffe5\044\uffe5\001\002\000\030\002\ufff0\005\ufff0\010" +
    "\033\023\ufff0\024\ufff0\025\ufff0\027\ufff0\031\ufff0\032\ufff0" +
    "\034\ufff0\042\034\001\002\000\004\004\031\001\002\000" +
    "\004\004\035\001\002\000\024\002\uffef\005\uffef\023\uffef" +
    "\024\uffef\025\uffef\027\uffef\031\uffef\032\uffef\034\uffef\001" +
    "\002\000\030\002\uffee\005\uffee\010\uffee\023\uffee\024\uffee" +
    "\025\uffee\027\uffee\031\uffee\032\uffee\034\uffee\042\uffee\001" +
    "\002\000\010\004\uffeb\006\uffeb\026\042\001\002\000\004" +
    "\004\041\001\002\000\050\002\uffe6\005\uffe6\010\uffe6\014" +
    "\uffe6\015\uffe6\016\uffe6\017\uffe6\020\uffe6\021\uffe6\023\uffe6" +
    "\024\uffe6\025\uffe6\027\uffe6\031\uffe6\032\uffe6\033\uffe6\034" +
    "\uffe6\042\uffe6\044\uffe6\001\002\000\004\010\044\001\002" +
    "\000\006\004\uffec\006\uffec\001\002\000\010\004\uffea\006" +
    "\uffea\026\042\001\002\000\006\004\uffe9\006\uffe9\001\002" +
    "\000\004\004\047\001\002\000\046\002\uffe7\005\uffe7\010" +
    "\uffe7\014\uffe7\015\uffe7\016\uffe7\017\uffe7\020\uffe7\021\uffe7" +
    "\023\uffe7\024\uffe7\025\uffe7\027\uffe7\031\uffe7\032\uffe7\034" +
    "\uffe7\042\uffe7\044\uffe7\001\002\000\034\002\uffc0\005\uffc0" +
    "\014\uffc0\015\uffc0\016\uffc0\017\uffc0\020\uffc0\021\uffc0\027" +
    "\uffc0\031\uffc0\032\uffc0\034\uffc0\044\060\001\002\000\004" +
    "\005\057\001\002\000\004\004\031\001\002\000\004\044" +
    "\054\001\002\000\004\026\055\001\002\000\004\005\056" +
    "\001\002\000\032\002\uffc1\005\uffc1\014\uffc1\015\uffc1\016" +
    "\uffc1\017\uffc1\020\uffc1\021\uffc1\027\uffc1\031\uffc1\032\uffc1" +
    "\034\uffc1\001\002\000\050\002\uffe4\005\uffe4\010\uffe4\014" +
    "\uffe4\015\uffe4\016\uffe4\017\uffe4\020\uffe4\021\uffe4\023\uffe4" +
    "\024\uffe4\025\uffe4\027\uffe4\031\uffe4\032\uffe4\033\uffe4\034" +
    "\uffe4\042\uffe4\044\uffe4\001\002\000\004\026\061\001\002" +
    "\000\032\002\uffc2\005\uffc2\014\uffc2\015\uffc2\016\uffc2\017" +
    "\uffc2\020\uffc2\021\uffc2\027\uffc2\031\uffc2\032\uffc2\034\uffc2" +
    "\001\002\000\006\004\125\037\124\001\002\000\022\002" +
    "\uffda\005\uffda\024\064\025\uffda\027\uffda\031\uffda\032\uffda" +
    "\034\uffda\001\002\000\006\004\031\006\052\001\002\000" +
    "\020\002\uffd2\005\uffd2\025\066\027\uffd2\031\uffd2\032\uffd2" +
    "\034\uffd2\001\002\000\006\004\031\006\052\001\002\000" +
    "\016\002\uffc7\005\uffc7\027\072\031\073\032\071\034\uffc7" +
    "\001\002\000\010\002\ufffd\005\ufffd\034\ufffd\001\002\000" +
    "\004\026\100\001\002\000\004\030\074\001\002\000\010" +
    "\002\uffc9\005\uffc9\034\uffc9\001\002\000\004\026\075\001" +
    "\002\000\012\002\uffcb\005\uffcb\032\076\034\uffcb\001\002" +
    "\000\004\026\077\001\002\000\010\002\uffca\005\uffca\034" +
    "\uffca\001\002\000\010\002\uffc8\005\uffc8\034\uffc8\001\002" +
    "\000\016\002\uffd3\005\uffd3\027\uffd3\031\uffd3\032\uffd3\034" +
    "\uffd3\001\002\000\016\014\114\015\113\016\116\017\115" +
    "\020\117\021\112\001\002\000\024\002\uffdc\005\uffdc\012" +
    "\104\013\106\025\uffdc\027\uffdc\031\uffdc\032\uffdc\034\uffdc" +
    "\001\002\000\006\004\uffd5\006\uffd5\001\002\000\020\002" +
    "\uffdb\005\uffdb\025\uffdb\027\uffdb\031\uffdb\032\uffdb\034\uffdb" +
    "\001\002\000\006\004\uffd4\006\uffd4\001\002\000\006\004" +
    "\031\006\052\001\002\000\024\002\uffd7\005\uffd7\012\104" +
    "\013\106\025\uffd7\027\uffd7\031\uffd7\032\uffd7\034\uffd7\001" +
    "\002\000\020\002\uffd6\005\uffd6\025\uffd6\027\uffd6\031\uffd6" +
    "\032\uffd6\034\uffd6\001\002\000\006\004\uffcc\026\uffcc\001" +
    "\002\000\006\004\uffd0\026\uffd0\001\002\000\006\004\uffd1" +
    "\026\uffd1\001\002\000\006\004\uffce\026\uffce\001\002\000" +
    "\006\004\uffcf\026\uffcf\001\002\000\006\004\uffcd\026\uffcd" +
    "\001\002\000\006\004\122\026\121\001\002\000\024\002" +
    "\uffd9\005\uffd9\012\uffd9\013\uffd9\025\uffd9\027\uffd9\031\uffd9" +
    "\032\uffd9\034\uffd9\001\002\000\024\002\uffd8\005\uffd8\012" +
    "\uffd8\013\uffd8\025\uffd8\027\uffd8\031\uffd8\032\uffd8\034\uffd8" +
    "\001\002\000\024\002\uffe0\005\uffe0\010\uffe0\024\uffe0\025" +
    "\uffe0\027\uffe0\031\uffe0\032\uffe0\034\uffe0\001\002\000\004" +
    "\026\133\001\002\000\026\002\uffde\005\uffde\010\uffde\024" +
    "\uffde\025\uffde\027\uffde\031\uffde\032\uffde\033\131\034\uffde" +
    "\001\002\000\024\002\uffe3\005\uffe3\010\127\024\uffe3\025" +
    "\uffe3\027\uffe3\031\uffe3\032\uffe3\034\uffe3\001\002\000\006" +
    "\004\125\037\124\001\002\000\024\002\uffe1\005\uffe1\010" +
    "\uffe1\024\uffe1\025\uffe1\027\uffe1\031\uffe1\032\uffe1\034\uffe1" +
    "\001\002\000\004\004\132\001\002\000\024\002\uffdd\005" +
    "\uffdd\010\uffdd\024\uffdd\025\uffdd\027\uffdd\031\uffdd\032\uffdd" +
    "\034\uffdd\001\002\000\024\002\uffdf\005\uffdf\010\uffdf\024" +
    "\uffdf\025\uffdf\027\uffdf\031\uffdf\032\uffdf\034\uffdf\001\002" +
    "\000\006\004\136\035\137\001\002\000\004\002\000\001" +
    "\002\000\006\002\uffc5\006\143\001\002\000\004\006\140" +
    "\001\002\000\004\026\141\001\002\000\004\005\142\001" +
    "\002\000\004\002\uffc6\001\002\000\004\026\144\001\002" +
    "\000\004\005\145\001\002\000\004\002\uffc4\001\002\000" +
    "\004\002\001\001\002\000\006\006\150\041\151\001\002" +
    "\000\004\004\156\001\002\000\004\026\152\001\002\000" +
    "\006\006\154\033\153\001\002\000\004\006\164\001\002" +
    "\000\004\004\156\001\002\000\006\005\ufff9\010\162\001" +
    "\002\000\004\004\161\001\002\000\004\005\160\001\002" +
    "\000\004\002\ufffb\001\002\000\006\005\ufff7\010\ufff7\001" +
    "\002\000\004\004\156\001\002\000\004\005\ufff8\001\002" +
    "\000\004\022\025\001\002\000\004\005\166\001\002\000" +
    "\004\002\ufffc\001\002\000\004\005\170\001\002\000\004" +
    "\002\ufffa\001\002" });

  /** Access to parse-action table. */
  public short[][] action_table() {return _action_table;}

  /** <code>reduce_goto</code> table. */
  protected static final short[][] _reduce_table = 
    unpackFromStrings(new String[] {
    "\000\166\000\010\003\005\026\004\027\007\001\001\000" +
    "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
    "\001\001\000\006\004\023\025\022\001\001\000\002\001" +
    "\001\000\004\030\012\001\001\000\002\001\001\000\004" +
    "\031\014\001\001\000\002\001\001\000\002\001\001\000" +
    "\004\031\017\001\001\000\002\001\001\000\002\001\001" +
    "\000\002\001\001\000\004\022\134\001\001\000\004\012" +
    "\062\001\001\000\012\005\031\006\025\010\026\011\027" +
    "\001\001\000\012\006\025\010\047\011\027\024\050\001" +
    "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
    "\000\002\001\001\000\010\006\025\010\035\011\027\001" +
    "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
    "\000\004\034\042\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\004\034\044" +
    "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\010\006\025" +
    "\010\052\011\027\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
    "\000\002\001\001\000\002\001\001\000\006\013\125\023" +
    "\122\001\001\000\004\014\064\001\001\000\014\006\025" +
    "\010\047\011\027\015\102\024\101\001\001\000\004\017" +
    "\066\001\001\000\012\006\025\010\047\011\027\024\100" +
    "\001\001\000\004\021\067\001\001\000\002\001\001\000" +
    "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
    "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\004\007\117" +
    "\001\001\000\006\016\104\020\106\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\014\006\025" +
    "\010\047\011\027\015\107\024\101\001\001\000\006\016" +
    "\110\020\106\001\001\000\002\001\001\000\002\001\001" +
    "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
    "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
    "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\004\023\127" +
    "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
    "\001\000\002\001\001\000\002\001\001\000\002\001\001" +
    "\000\002\001\001\000\002\001\001\000\002\001\001\000" +
    "\002\001\001\000\002\001\001\000\002\001\001\000\002" +
    "\001\001\000\002\001\001\000\002\001\001\000\002\001" +
    "\001\000\006\032\154\033\166\001\001\000\002\001\001" +
    "\000\002\001\001\000\002\001\001\000\006\032\154\033" +
    "\156\001\001\000\002\001\001\000\002\001\001\000\002" +
    "\001\001\000\002\001\001\000\002\001\001\000\006\032" +
    "\154\033\162\001\001\000\002\001\001\000\006\004\023" +
    "\025\164\001\001\000\002\001\001\000\002\001\001\000" +
    "\002\001\001\000\002\001\001" });

  /** Access to <code>reduce_goto</code> table. */
  public short[][] reduce_table() {return _reduce_table;}

  /** Instance of action encapsulation class. */
  protected CUP$senseParser$actions action_obj;

  /** Action encapsulation object initializer. */
  protected void init_actions()
    {
      action_obj = new CUP$senseParser$actions(this);
    }

  /** Invoke a user supplied parse action. */
  public java_cup.runtime.Symbol do_action(
    int                        act_num,
    java_cup.runtime.lr_parser parser,
    java.util.Stack            stack,
    int                        top)
    throws java.lang.Exception
  {
    /* call code in generated class */
    return action_obj.CUP$senseParser$do_action(act_num, parser, stack, top);
  }

  /** Indicates start state. */
  public int start_state() {return 0;}
  /** Indicates start production. */
  public int start_production() {return 0;}

  /** <code>EOF</code> Symbol index. */
  public int EOF_sym() {return 0;}

  /** <code>error</code> Symbol index. */
  public int error_sym() {return 1;}



		public String errorMsg = "no errors";
	
	private boolean errorSet = false;
	
	public void report_error(String message, Object info) {
		Symbol cur_token = (Symbol) info;
		
		//System.out.println("errorMsg = " + errorMsg);
		//System.out.println("cur_token.sym = " + cur_token.sym);
		
		
		if (message.equals("Syntax error")) {
			if (cur_token.sym == 0)
				errorMsg = "Bad Syntax - Possibly missing clause";
			else
				errorMsg = "Syntax error at " + cur_token.value;
			errorSet = true;
		}
		
		if (!errorSet) {
			errorMsg = "Can't parse query string";
		}
		
		System.out.println("errorMsg = " + errorMsg);
	}
	
	public void syntax_error(Symbol cur_token) {
		report_error("Syntax error", cur_token);
	}
	
	
	
}

/** Cup generated class to encapsulate user supplied action code.*/
class CUP$senseParser$actions {


		byte queryId = 1;
	int epochDur = 1024;
	TinyDBQuery tinyDBQuery = new TinyDBQuery(queryId, epochDur);
  byte curRelOp=0;
	
	Vector aggFields = new Vector();
	Vector selList = new Vector();
	HashMap fields = new HashMap();
	Vector conds = new Vector();
	Vector eventParams = new Vector();
	short fieldIndex = 0;
	short groupIdx = -1;
	String catalogTableName = null;
	
	Catalog catalog = Catalog.curCatalog;
	
	class ArithExpressionClass {
	    String fieldOp;
	    short fieldConstant;
	    FieldInfo finf;
	    boolean isAttr;
	}
	
	class AggField {
	    AggOp fieldOp;
	    ArithExpressionClass fieldData;
	}
	
	class FieldInfo {
	    boolean isAgg;
	    AggField af;
	    QueryField qf;
	}
	
	class SelStmt {
	    SelOp op;
	    ArithExpressionClass aexp;
	    short c;
		short c2;
		short c3;
	    String s;
	}
	
	public QueryField getQueryField(String column, byte aggOp, short fid) {
	    QueryField qf = null;
	    String hashKey = column + aggOp;
		
	    if (fields.get(hashKey) == null) {
			//we can't verify that this is a valid query field just yet,
			//since we don't know the source table
			qf = new QueryField(column, QueryField.UNKNOWN_TYPE);
			
			qf.setIdx(fid);
			qf.setOp(aggOp);
			fields.put(hashKey, qf);
			//System.out.println("ADDED FIELD : " + column);
			//tinyDBQuery.addField(qf);
	    } else qf = (QueryField) fields.get(hashKey);
	    return qf;
	}
	
	public QueryField getQueryField(String column, byte aggOp) {
	    String hashKey = column + aggOp;
	    if (fields.get(hashKey) != null)
			return ((QueryField)fields.get(hashKey));
	    else
			return getQueryField(column, aggOp, fieldIndex++);
	}
	
	public short removeField(String name, byte aggOp) {
	    String hashKey = name + aggOp;
	    //System.out.println("IN REMOVEFIELD: " + name + "  ,OP  " + aggOp);
	    QueryField qf = (QueryField)fields.get(hashKey);
	    if (qf != null) {
			fields.remove(hashKey);
			return qf.getIdx();
	    }
	    else return 0xFF;
	}
	
	public boolean validEpochDur(int epochDur) {
	    return (epochDur > 64 && epochDur < 700000);
	}
	
	
  private final senseParser parser;

  /** Constructor */
  CUP$senseParser$actions(senseParser parser) {
    this.parser = parser;
  }

  /** Method with the actual generated action code. */
  public final java_cup.runtime.Symbol CUP$senseParser$do_action(
    int                        CUP$senseParser$act_num,
    java_cup.runtime.lr_parser CUP$senseParser$parser,
    java.util.Stack            CUP$senseParser$stack,
    int                        CUP$senseParser$top)
    throws java.lang.Exception
    {
      /* Symbol object for return from actions */
      java_cup.runtime.Symbol CUP$senseParser$result;

      /* select the action based on the action number */
      switch (CUP$senseParser$act_num)
        {
          /*. . . . . . . . . . . . . . . . . . . .*/
          case 65: // arith_expr ::= attr 
            {
              Object RESULT = null;
		int aleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int aright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		FieldInfo a = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		// e.g. light
		ArithExpressionClass exp = new ArithExpressionClass();
	exp.isAttr = true;
	exp.finf = a;
	RESULT = exp;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(18/*arith_expr*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 64: // arith_expr ::= LPAREN attr ARITHMETIC_OP CONSTANT RPAREN 
            {
              Object RESULT = null;
		int aleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left;
		int aright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).right;
		FieldInfo a = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).value;
		int arithOpleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int arithOpright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String arithOp = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int arithConstleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int arithConstright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Integer arithConst = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		// e.g. (light * 20)
		ArithExpressionClass exp = new ArithExpressionClass();
	
	//if (a.qf.getType() == QueryField.STRING) {
	//    SensorQueryer.errorMessage = "Arithmetic operations not supported on STRING fields";
	//
	//    return null;
	//}
	
	exp.finf = a;
	exp.fieldOp = arithOp;
	exp.fieldConstant = arithConst.shortValue();
	exp.isAttr = false;
	RESULT = exp;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(18/*arith_expr*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 63: // arith_expr ::= attr ARITHMETIC_OP CONSTANT 
            {
              Object RESULT = null;
		int aleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int aright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		FieldInfo a = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int arithOpleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int arithOpright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		String arithOp = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int arithConstleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int arithConstright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer arithConst = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		// e.g. light * 20
		ArithExpressionClass exp = new ArithExpressionClass();
	
	//if (a.qf.getType() == QueryField.STRING) {
	//    SensorQueryer.errorMessage = "Arithmetic operations not supported on STRING fields";
	//    return null;
	//}
	exp.finf = a;
	exp.fieldOp = arithOp;
	exp.fieldConstant = arithConst.shortValue();
	exp.isAttr = false;
	RESULT = exp;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(18/*arith_expr*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 62: // action_stat ::= 
            {
              Object RESULT = null;
		 
              CUP$senseParser$result = new java_cup.runtime.Symbol(16/*action_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 61: // action_stat ::= ACTION NAME LPAREN CONSTANT RPAREN 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).value;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		//System.out.println("NAME: " + n);
		tinyDBQuery.setOutputCommand(n, c.shortValue());
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(16/*action_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 60: // action_stat ::= ACTION NAME 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		tinyDBQuery.setOutputCommand(n);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(16/*action_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 59: // action_stat ::= ACTION BUFFER LPAREN CONSTANT RPAREN 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		tinyDBQuery.useRamBuffer(c.shortValue());
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(16/*action_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 58: // epoch_stat ::= 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(15/*epoch_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 57: // epoch_stat ::= FOR CONSTANT 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		tinyDBQuery.setNumEpochs(c.shortValue());
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(15/*epoch_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 56: // epoch_stat ::= ONE_SHOT 
            {
              Object RESULT = null;
		
    if (tinyDBQuery.getFromQid() != TinyDBQuery.NO_FROM_QUERY || tinyDBQuery.isFromCatalogTable())
	tinyDBQuery.setEpoch(TinyDBQuery.kEPOCH_DUR_ONE_SHOT);
    else
	SensorQueryer.errorMessage = "One shot, non-nested queries not supported.";
    
              CUP$senseParser$result = new java_cup.runtime.Symbol(15/*epoch_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 55: // epoch_stat ::= EPOCH DURATION CONSTANT FOR CONSTANT 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int c2left = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int c2right = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer c2 = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
    if (validEpochDur(c.intValue())) {
	tinyDBQuery.setEpoch(c.intValue()); 
	tinyDBQuery.setNumEpochs(c2.shortValue());
	
    } else {
	SensorQueryer.errorMessage = "Invalid epoch duration, " + c;
        RESULT = null;
    }

              CUP$senseParser$result = new java_cup.runtime.Symbol(15/*epoch_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 54: // epoch_stat ::= EPOCH DURATION CONSTANT 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		 
   if (validEpochDur(c.intValue())) {
       tinyDBQuery.setEpoch(c.intValue()); 
   } else {
       SensorQueryer.errorMessage = "Invalid epoch duration, " + c;
       RESULT = null;
   }
 
              CUP$senseParser$result = new java_cup.runtime.Symbol(15/*epoch_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 53: // rel_op ::= NOT_EQUAL 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_NEQ); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 52: // rel_op ::= LESS_EQUAL 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_LE); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 51: // rel_op ::= GREATER_EQUAL 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_GE); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 50: // rel_op ::= EQUAL 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_EQ); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 49: // rel_op ::= LESS_THAN 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_LT); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 48: // rel_op ::= GREATER_THAN 
            {
              SelOp RESULT = null;
		 RESULT = new SelOp(SelOp.OP_GT); 
              CUP$senseParser$result = new java_cup.runtime.Symbol(5/*rel_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 47: // group_by_stat ::= 
            {
              ArithExpressionClass RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(13/*group_by_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 46: // group_by_stat ::= GROUP_BY arith_expr 
            {
              ArithExpressionClass RESULT = null;
		int aObjleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int aObjright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Object aObj = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		ArithExpressionClass a = (ArithExpressionClass) aObj;
	if (a.finf.isAgg && a.finf.af.fieldData.finf.isAgg) {
		SensorQueryer.errorMessage = "Too much nesting in group by expression.";
		RESULT = null;
	} else
		RESULT = a;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(13/*group_by_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 45: // bool_op ::= OR 
            {
              String RESULT = null;
		 RESULT = "OR";
     curRelOp=1;
     System.out.println("JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ");
              CUP$senseParser$result = new java_cup.runtime.Symbol(14/*bool_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 44: // bool_op ::= AND 
            {
              String RESULT = null;
		 RESULT = "AND";

              CUP$senseParser$result = new java_cup.runtime.Symbol(14/*bool_op*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 43: // more_conditions ::= bool_op condition more_conditions 
            {
              Vector RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		SelStmt c = (SelStmt)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int vleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int vright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Vector v = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		v.addElement(c);
	RESULT = v;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(12/*more_conditions*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 42: // more_conditions ::= bool_op condition 
            {
              Vector RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		SelStmt c = (SelStmt)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		Vector v = new Vector();
	v.addElement(c);
	RESULT = v;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(12/*more_conditions*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 41: // condition ::= arith_expr rel_op NAME 
            {
              SelStmt RESULT = null;
		int aObjleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int aObjright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		Object aObj = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int rleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int rright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		SelOp r = (SelOp)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		ArithExpressionClass a = (ArithExpressionClass)aObj;
	SelStmt s = new SelStmt();
	// if (a.finf.qf.getType() != QueryField.STRING) {
	//    SensorQueryer.errorMessage = "Non-numeric field value not allowed with non-STRING fields";
	//    return null;
	// }
	s.op = r;
	s.aexp = a;
	s.s = n;
	
	RESULT = s;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(11/*condition*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 40: // condition ::= arith_expr rel_op CONSTANT 
            {
              SelStmt RESULT = null;
		int aObjleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int aObjright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		Object aObj = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int rleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int rright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		SelOp r = (SelOp)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		ArithExpressionClass a = (ArithExpressionClass) aObj;
	SelStmt s = new SelStmt();
	
	//	   if (a.finf.qf.getType() == QueryField.STRING) {
	//	      SensorQueryer.errorMessage = "Numeric field value not allowed with STRING fields";
	//      return null;
	//   }
	
	if (a.finf.isAgg && a.finf.af.fieldData.finf.isAgg) {
		SensorQueryer.errorMessage = "Too much nesting in WHERE clause.";
		RESULT = null;
	}
	
	
	s.op = r;
	s.aexp = a;
	s.c = c.shortValue();
	
	RESULT = s;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(11/*condition*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 39: // where_stat ::= 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(10/*where_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 38: // where_stat ::= WHERE condition more_conditions 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		SelStmt c = (SelStmt)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int vleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int vright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Vector v = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		conds.addElement(c);
	for (int i = 0; i < v.size(); i++) {
		conds.addElement(v.elementAt(i));
	}
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(10/*where_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 37: // where_stat ::= WHERE condition 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		SelStmt c = (SelStmt)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		conds.addElement(c);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(10/*where_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 36: // source ::= NAME AS NAME 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		
		
              CUP$senseParser$result = new java_cup.runtime.Symbol(17/*source*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 35: // source ::= NAME 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
	    String ln = n.toLowerCase();
	if (!ln.equals("sensors")) {
		try {
		    catalogTableName = ln;
		    System.out.println("CATALOG TABLE NAME = " + ln);
		    byte tid = (byte)CatalogTables.getTableIdFromName(ln);
		    if (tid != CatalogTables.USER_DEFINED_TABLE_ID)
				tinyDBQuery.setFromCatalogTable(tid);
		    else
				throw new NoSuchElementException();
			
		} catch (NoSuchElementException e) {
		    TinyDBQuery query;
		/*
		    if ((query = TinyDBQuery.getQueryForBufName(ln)) != null) {
				System.out.println("Table : " + ln + " = table id " + query.getId());
				tinyDBQuery.setFromQid((byte)query.getId());
		    } else {
		*/
				//SensorQueryer.errorMessage = "Unknown table : " + n;
				//we don't know about this table -- pass in a buffer name
				tinyDBQuery.useRamBuffer((short)0);  //don't know the size ...
				tinyDBQuery.setInputBufferName(catalogTableName);
				//return null;
		//	    }
		}
	}
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(17/*source*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 34: // source ::= QUERY_STRING CONSTANT 
            {
              Object RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		//System.out.println("got : " + c);
		tinyDBQuery.setFromQid(c.byteValue());
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(17/*source*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 33: // from_stat_list ::= source 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(9/*from_stat_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 32: // from_stat_list ::= from_stat_list COMMA source 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(9/*from_stat_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 31: // from_stat ::= 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(8/*from_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 30: // from_stat ::= FROM from_stat_list 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(8/*from_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 29: // attr_core ::= agg arith_expr RPAREN 
            {
              FieldInfo RESULT = null;
		int aggleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int aggright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		AggOp agg = (AggOp)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int arithObjleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int arithObjright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Object arithObj = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		ArithExpressionClass ac = (ArithExpressionClass)arithObj;
	if (ac.finf.isAgg) {
		//if this is an agg of an agg, set the operator of the inner
		//query field to be the inner agg operator
		AggField inner = ac.finf.af;
		if (inner.fieldData.finf.isAgg) {
			SensorQueryer.errorMessage = "Nested aggregate expressions with nesting greater than 2 not allowed.";
			return null;
		}
		short fid = removeField(inner.fieldData.finf.qf.getName(), AggOp.AGG_NOOP);
		//weirdness -- set the qf field, but don't unset the isAgg field,
		//since we'll need to fire an error about this double nesting
		//later if this doesn't turn out to be a nested query
		
		//also, nested queries convert a single aggregate expression to
		//a query field, which we don't want to do
		if (fid == 0xFF)
			ac.finf.qf= getQueryField(inner.fieldData.finf.qf.getName(), inner.fieldOp.toByte());
		else
			ac.finf.qf= getQueryField(inner.fieldData.finf.qf.getName(), inner.fieldOp.toByte(), fid);
	} else {
		if (ac.finf.qf.getType() == QueryField.STRING) {
			SensorQueryer.errorMessage = "Can't aggregate on a STRING field.";
			RESULT = null;
			return null;
		}
	}
	FieldInfo f = new FieldInfo();
	f.isAgg = true;
	AggField af = new AggField();
	af.fieldOp = agg;
	af.fieldData = (ArithExpressionClass)arithObj;
	f.af = af;
	RESULT = f;
	
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(7/*attr_core*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 28: // attr_core ::= NAME 
            {
              FieldInfo RESULT = null;
		int columnleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int columnright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String column = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
	    QueryField qf = getQueryField(column,AggOp.AGG_NOOP);
	FieldInfo f = new FieldInfo();
	f.isAgg = false;
	f.qf = qf;
	RESULT = f;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(7/*attr_core*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 27: // attr_core ::= NAME PERIOD NAME 
            {
              FieldInfo RESULT = null;
		int n1left = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int n1right = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String n1 = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int n2left = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int n2right = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n2 = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		//System.out.println("in attr code");
		//System.out.println("n1 = " + n1);
		FieldInfo f = new FieldInfo();
	f.isAgg = false;
	
	QueryField qf = getQueryField(n2,AggOp.AGG_NOOP);
	
	f.qf = qf;
	RESULT = f;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(7/*attr_core*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 26: // attr ::= attr_core AS NAME 
            {
              FieldInfo RESULT = null;
		int aleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int aright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		FieldInfo a = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int aliasleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int aliasright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String alias = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		FieldInfo f = (FieldInfo)a;
	
    RESULT = a;
    if (f.isAgg) {
		f.af.fieldData.finf.qf.setAlias(alias);
    } else {
		f.qf.setAlias(alias);
    }
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(6/*attr*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 25: // attr ::= attr_core 
            {
              FieldInfo RESULT = null;
		int aleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int aright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		FieldInfo a = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		RESULT = a;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(6/*attr*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 24: // constant_list ::= CONSTANT COMMA constant_list 
            {
              Vector RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int argsleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int argsright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Vector args = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		System.out.println("###List const added");
    System.out.println("Args before: " + args);
    args.addElement(c);
    System.out.println("Args after" + args);
    RESULT = args;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(26/*constant_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 23: // constant_list ::= CONSTANT COMMA 
            {
              Vector RESULT = null;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		Vector v = new Vector();
    v.addElement(c);
    RESULT = v;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(26/*constant_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 22: // agg ::= NAME LPAREN 
            {
              AggOp RESULT = null;
		int nameleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int nameright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		String name = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		// check if agg with this name is registered
		AggregateEntry agg = catalog.getAggregateCatalog().getAggregate(name);
	if (agg == null)  {
		SensorQueryer.errorMessage = "No aggregate " + name + " in catalog";
		return null;
	}
	
	//check if number of arguments matchers info in catalog
    if (agg.getArgCount() != 0) {//no argument aggregate
		SensorQueryer.errorMessage = "Aggegate " + name + " expects " + agg.getArgCount() + " arguments." +
			"Given 0";
		return null;
	}
	
	try {
		RESULT = new AggOp(name);
    } catch (IllegalArgumentException e) {
		SensorQueryer.errorMessage = "Invalid arguments for " + name;
		return null;
    }
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(4/*agg*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 21: // agg ::= NAME LPAREN constant_list 
            {
              AggOp RESULT = null;
		int nameleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int nameright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String name = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int argsleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int argsright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Vector args = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		// check if agg with this name is registered
		AggregateEntry agg = catalog.getAggregateCatalog().getAggregate(name);
	if (agg == null)  {
		SensorQueryer.errorMessage = "No aggregate " + name + " in catalog";
		return null;
	}
    
    //check if number of arguments matchers info in catalog
    if (agg.getArgCount() != args.size()) {
		SensorQueryer.errorMessage = "Aggegate " + name + " expects " + agg.getArgCount() + " arguments. " +
			"Given " + args.size();
		return null;
	}
	try {
		Collections.reverse(args);//HACK, solves parsing order problem
		RESULT = new AggOp(name, args);
    } catch (IllegalArgumentException e) {
		SensorQueryer.errorMessage = "Invalid arguments for " + name;
		return null;
    }
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(4/*agg*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 20: // select_stat_list ::= attr 
            {
              Object RESULT = null;
		int atleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int atright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		FieldInfo at = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		selList.addElement(at);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(3/*select_stat_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 19: // select_stat_list ::= select_stat_list COMMA attr 
            {
              Object RESULT = null;
		int atleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int atright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		FieldInfo at = (FieldInfo)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		selList.addElement(at);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(3/*select_stat_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 18: // select_stat ::= SELECT select_stat_list INTO NAME 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		
	tinyDBQuery.setBufferCreateTable(false);
	tinyDBQuery.setBufferName(n,false);
	tinyDBQuery.useRamBuffer((short)0); //who cares about size?
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(2/*select_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 17: // select_stat ::= SELECT select_stat_list 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(2/*select_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 16: // event_param_list ::= 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(22/*event_param_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 15: // event_param_list ::= LPAREN event_param RPAREN 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(22/*event_param_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 14: // event_param ::= NAME 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		eventParams.addElement(n);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(23/*event_param*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 13: // event_param ::= NAME COMMA event_param 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		
		eventParams.addElement(n);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(23/*event_param*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 12: // on_event_stat ::= 
            {
              Object RESULT = null;

              CUP$senseParser$result = new java_cup.runtime.Symbol(21/*on_event_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 11: // on_event_stat ::= ONEVENT NAME event_param_list COLON 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		
		tinyDBQuery.setEvent(n);
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(21/*on_event_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 10: // field_entry ::= NAME NAME 
            {
              QueryField RESULT = null;
		int nameleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int nameright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		String name = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		int typeleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int typeright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		String type = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
	try {
	    byte type_b = Catalog.stringToType(type);
	    RESULT = new QueryField(name, name, type_b);
	    
	} catch (java.text.ParseException e) {
	    SensorQueryer.errorMessage = "Unknown type : " + type;
	    return null;
	}
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(24/*field_entry*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 9: // field_list ::= field_entry COMMA field_list 
            {
              Vector RESULT = null;
		int feleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left;
		int feright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).right;
		QueryField fe = (QueryField)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).value;
		int flleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int flright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Vector fl = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		fl.addElement(fe);
    RESULT = fl;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(25/*field_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 8: // field_list ::= field_entry 
            {
              Vector RESULT = null;
		int feleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int feright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		QueryField fe = (QueryField)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		Vector v = new Vector();
    v.addElement(fe);
    RESULT = v;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(25/*field_list*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 7: // create_buffer_stat ::= CREATE NAME LPAREN field_list RPAREN 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).value;
		int fleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int fright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Vector f = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
    short index = (short)f.size();
	
    Enumeration e = f.elements();
    while (e.hasMoreElements()) {
		QueryField qf = (QueryField)e.nextElement();
		qf.setIdx(--index);
		tinyDBQuery.addField(qf);
		tinyDBQuery.useRamBuffer((short)1);
		tinyDBQuery.setBufferName(n,true);
		tinyDBQuery.setBufferCreateTable(true);
    }
    Vector fields = new Vector();
    for (int i = 0; i < tinyDBQuery.numFields(); i++) {
		fields.addElement(tinyDBQuery.getField(i));
    }
    System.out.println("Adding table : " + n);
    CatalogTables.addCatalogTable(n, fields);
    
    RESULT = tinyDBQuery;

              CUP$senseParser$result = new java_cup.runtime.Symbol(20/*create_buffer_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 6: // create_buffer_stat ::= CREATE NAME SIZE CONSTANT LPAREN field_list RPAREN 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-5)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-5)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-5)).value;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-3)).value;
		int fleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int fright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Vector f = (Vector)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
    short index = (short)f.size();
	
    Enumeration e = f.elements();
    while (e.hasMoreElements()) {
		QueryField qf = (QueryField)e.nextElement();
		qf.setIdx(--index);
		tinyDBQuery.addField(qf);
		tinyDBQuery.useRamBuffer(c.shortValue());
		tinyDBQuery.setBufferName(n,true);
		tinyDBQuery.setBufferCreateTable(true);
    }
    Vector fields = new Vector();
    for (int i = 0; i < tinyDBQuery.numFields(); i++) {
		fields.addElement(tinyDBQuery.getField(i));
    }
    System.out.println("Adding table : " + n);
    CatalogTables.addCatalogTable(n, fields);
    
    RESULT = tinyDBQuery;

              CUP$senseParser$result = new java_cup.runtime.Symbol(20/*create_buffer_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-6)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 5: // create_buffer_stat ::= CREATE NAME SIZE CONSTANT AS LPAREN query_core RPAREN 
            {
              Object RESULT = null;
		int nleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-6)).left;
		int nright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-6)).right;
		String n = (String)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-6)).value;
		int cleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left;
		int cright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).right;
		Integer c = (Integer)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).value;
		int qcleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int qcright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Object qc = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
	((TinyDBQuery)qc).useRamBuffer(c.shortValue());
	((TinyDBQuery)qc).setBufferName(n,true);
	
	RESULT = qc;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(20/*create_buffer_stat*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-7)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 4: // query_core ::= select_stat from_stat where_stat group_by_stat epoch_stat 
            {
              Object RESULT = null;
		int gfleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int gfright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		ArithExpressionClass gf = (ArithExpressionClass)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		Enumeration e;
	Iterator i;
	boolean hasAgg = false;
	//System.out.println("in query code");
	
	
	//first, verify that all of the query fields actually exist in the source table
	i = fields.values().iterator();
	while (i.hasNext()) {
		QueryField qf = (QueryField)i.next();
		QueryField realqf = null;
		
		//WARNING -- we don't type check fields right now --
		// if we wanted to do this, we'd need to
		if (catalogTableName == null) {
			realqf = catalog.getAttr(qf.getName());
		} else {
			System.out.println("Looking for field " + qf.getName() + " in table " + catalogTableName);
			try {
				CatalogTables.getTableIdFromName(catalogTableName);
				System.out.println("Got table Id.");
				realqf = CatalogTables.getTableFieldInfo(catalogTableName, qf.getName());
				System.out.println("got field info.");
				if (realqf == null)
					System.out.println("QF IS NULL!");
				else
					System.out.println("Got qf = " + qf);
			} catch (NoSuchElementException ex) {
				//table doesn't exist -- ask user for type
				
				String[] possibleValues = new String[Catalog.numTypes()];
				for (int j = 0; j < Catalog.numTypes(); j++) {
					possibleValues[j] = Catalog.getTypeName(j);
				}
				Object selectedValue = JOptionPane.showInputDialog(
					null,
					"Select the type for field " + catalogTableName + "." + qf.getName() + ":",
					"Field Type:", JOptionPane.INFORMATION_MESSAGE,
					null,
					possibleValues, possibleValues[0]);
				if (selectedValue != null) {
					realqf = new QueryField(catalogTableName, Catalog.stringToType((String)selectedValue));
				}
			}
		}
		if (realqf == null) {
			SensorQueryer.errorMessage = "Can't find field " + qf.getName() + " in catalog";
			return null;
		}
		qf.setType(realqf.getType());
		
	}
	
	/* If this query is nested -- e.g. it has a from qid, we'll need to
	 make sure that we translate aggregate expressions into aggregate
	 query fields.
	
	 Also, for non-nested queries, we don't allow nested aggregate expressions
	 (e.g. avg(avg(light)) )
	 */
	/*
	 if (tinyDBQuery.getFromQid() != TinyDBQuery.NO_FROM_QUERY) {
	 //have to map aggregate expressions to
	 //query fields
	 
	 //first, look for aggregates in WHERE claues
	 e = conds.elements();
	 while (e.hasMoreElements()) {
	 SelStmt s = (SelStmt)e.nextElement();
	 FieldInfo finf = s.aexp.finf;
	 if (finf.isAgg && !finf.af.fieldData.finf.isAgg) {
	 byte op = finf.af.fieldOp.toByte();
	 byte type = finf.af.fieldData.finf.qf.getType();
	 short fid = removeField(finf.af.fieldData.finf.qf.getName(), AggOp.AGG_NOOP);
	 finf.isAgg = false;
	 if (fid == 0xFF)
	 finf.qf = getQueryField(finf.af.fieldData.finf.qf.getName(), op);
	 else
	 finf.qf = getQueryField(finf.af.fieldData.finf.qf.getName(), op,fid);
	 finf.qf.setType(type);
	 System.out.println("EXPR QUERY FIELD = " + finf.qf);
	 }
	 }
	
	 //and then in the SELECT clause
	 e = selList.elements();
	 while (e.hasMoreElements()) {
	 FieldInfo finf = (FieldInfo)e.nextElement();
	 
	 if (finf.isAgg && !finf.af.fieldData.finf.isAgg) {
	 byte op = finf.af.fieldOp.toByte();
	 byte type = finf.af.fieldData.finf.qf.getType();
	 short fid = removeField(finf.af.fieldData.finf.qf.getName(), AggOp.AGG_NOOP);
	 finf.isAgg = false;
	 if (fid == 0xFF)
	 finf.qf = getQueryField(finf.af.fieldData.finf.qf.getName(), op);
	 else
	 finf.qf = getQueryField(finf.af.fieldData.finf.qf.getName(), op,fid);
	 finf.qf.setType(type);
	 //		     System.out.println("SEL QUERY FIELD = " + finf.qf);
	 }
	 }
	
	 //finally, the GROUP BY clause
	 if (gf != null && gf.finf.isAgg) {
	 AggField af = gf.finf.af;
	 QueryField nestedqf = af.fieldData.finf.qf;
	 byte type = nestedqf.getType();
	 QueryField qf = getQueryField(nestedqf.getName(),AggOp.AGG_NOOP);
	
	 if (qf == null) {
	 SensorQueryer.errorMessage = "GROUP BY field cannot appear elsewhere in query.";
	 return null;
	 }
	 gf.finf.isAgg = false;
	 short fid = removeField(nestedqf.getName(),AggOp.AGG_NOOP);
	 gf.finf.qf = getQueryField(nestedqf.getName(), af.fieldOp.toByte(), fid);
	 gf.finf.qf.setType(type);
	 }
	 
	 }
	 */
	
	//first add fields
	i = fields.values().iterator();
	while (i.hasNext()) {
		QueryField qf = (QueryField)i.next();
		tinyDBQuery.addField(qf);
	}
	
	//then add select statements
	e = conds.elements();
	while (e.hasMoreElements()) {
		SelStmt s = (SelStmt)e.nextElement();
		FieldInfo finf = s.aexp.finf;
		SelExpr se;
		if (finf.isAgg /*&& tinyDBQuery.getFromQid() == TinyDBQuery.NO_FROM_QUERY*/) {
			SensorQueryer.errorMessage = "Nested selections aggregates are not allowed!";
			return null;
		}
		if (s.aexp.isAttr) {
			if (finf.qf.getType() == QueryField.STRING) {
				if (s.s == null) {
					SensorQueryer.errorMessage = "Illegal numerical constant in "+
						"WHERE clause over string attribtute " + finf.qf.getName();
					return null;
				}
				se = new SelExpr(finf.qf.getIdx(), s.op, s.s);
			} else {
				if (s.s != null) {
					SensorQueryer.errorMessage = "Invalid string constant in WHERE clause "+
						"over numerical attribtute " + finf.qf.getName();
					return null;
				}
				
				se = new SelExpr(finf.qf.getIdx(), s.op, s.c);
			}
		} else {
			if (finf.qf.getType() == QueryField.STRING) {
				SensorQueryer.errorMessage = "Invalid mathematical expression over "+
					"string attribute " + finf.qf.getName();
				return null;
			}
			if (s.s != null) {
				SensorQueryer.errorMessage = "Invalid string constant in WHERE clause "+
					"over numerical attribtute " + finf.qf.getName();
				return null;
			}
			
			se = new SelExpr(finf.qf.getIdx(), s.aexp.fieldOp, s.aexp.fieldConstant, s.op, s.c);
		}
		//System.out.println("GOT SEL EXPR: " + e);
    se.relOp = curRelOp;
    curRelOp = 0;
		tinyDBQuery.addExpr(se);
	}
	
	//and then add aggregate expressions
	e = selList.elements();
	while (e.hasMoreElements()) {
		FieldInfo f = (FieldInfo)e.nextElement();
		if (f.isAgg) {
			ArithExpressionClass a = f.af.fieldData;
			FieldInfo inner = a.finf;
			
			//we're assuming all aggregates are numerical
			if (inner.qf.getType() == QueryField.STRING) {
				SensorQueryer.errorMessage = "Can't aggregate on a STRING field.";
				return null;
			}
			 
			
			AggExpr ae;
			if (inner.isAgg /*&& tinyDBQuery.getFromQid() == TinyDBQuery.NO_FROM_QUERY*/) {
				SensorQueryer.errorMessage = "Nested aggregates not supported ." ;//in non-nested queries.";
				return null;
			}
			if (gf != null && gf.finf.isAgg /*&& tinyDBQuery.getFromQid() == TinyDBQuery.NO_FROM_QUERY*/) {
				SensorQueryer.errorMessage = "Can't group by an aggregate field."; // in a non-nested query.";
				return null;
			}
			
			if (a.isAttr) {
				ae = new AggExpr(inner.qf.getIdx(), f.af.fieldOp);
			} else {
				ae = new AggExpr(inner.qf.getIdx(), a.fieldOp, a.fieldConstant, f.af.fieldOp);
			}
			if (gf != null) {
				if (!gf.isAttr) {
					ae.setGroupFieldOp(gf.fieldOp);
					ae.setGroupFieldConst(gf.fieldConstant);
				}
				ae.setGroupField(gf.finf.qf.getIdx());
			}
			//System.out.println("GOT AGG EXPR: " + ae);
       ae.relOp = curRelOp;
      curRelOp = 0;
			tinyDBQuery.addExpr(ae);
			hasAgg = true;
		}
	}
	
	if (!hasAgg && gf != null) {
		SensorQueryer.errorMessage = "GROUP BY can only be used with aggregate queries.";
		return null;
	}
	
	if (eventParams.size() != 0) {
		SensorQueryer.errorMessage = "Parameterized events currently unsupported.";
		return null;
	}
	
	if (tinyDBQuery.getEpoch() != TinyDBQuery.kEPOCH_DUR_ONE_SHOT && tinyDBQuery.isFromCatalogTable()) {
		SensorQueryer.errorMessage = "Continuous queries over catalog tables are not allowed (use the ONCE keyword).";
		return null;
	}
	 //finally, optimize this sucker
	 QueryOpt.optimizeQuery(catalog, tinyDBQuery);

	 RESULT = tinyDBQuery;
	
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(19/*query_core*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-4)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 3: // query ::= DROPALL 
            {
              TinyDBQuery RESULT = null;
		
	tinyDBQuery.setDropTables();
	RESULT = tinyDBQuery;

              CUP$senseParser$result = new java_cup.runtime.Symbol(1/*query*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 2: // query ::= create_buffer_stat 
            {
              TinyDBQuery RESULT = null;
		int qc2left = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left;
		int qc2right = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right;
		Object qc2 = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).value;
		
		RESULT = (TinyDBQuery)qc2;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(1/*query*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 1: // query ::= on_event_stat query_core action_stat 
            {
              TinyDBQuery RESULT = null;
		int qcleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int qcright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		Object qc = (Object)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		
		RESULT = (TinyDBQuery)qc;
	
              CUP$senseParser$result = new java_cup.runtime.Symbol(1/*query*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-2)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          return CUP$senseParser$result;

          /*. . . . . . . . . . . . . . . . . . . .*/
          case 0: // $START ::= query EOF 
            {
              Object RESULT = null;
		int start_valleft = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left;
		int start_valright = ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).right;
		TinyDBQuery start_val = (TinyDBQuery)((java_cup.runtime.Symbol) CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).value;
		RESULT = start_val;
              CUP$senseParser$result = new java_cup.runtime.Symbol(0/*$START*/, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-1)).left, ((java_cup.runtime.Symbol)CUP$senseParser$stack.elementAt(CUP$senseParser$top-0)).right, RESULT);
            }
          /* ACCEPT */
          CUP$senseParser$parser.done_parsing();
          return CUP$senseParser$result;

          /* . . . . . .*/
          default:
            throw new Exception(
               "Invalid action number found in internal parse table");

        }
    }
}

