📄 senseparser.cup
字号:
/* tab:4 * "Copyright (c) 2000-2003 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * Copyright (c) 2002-2003 Intel Corporation * All rights reserved. * * This file is distributed under the terms in the attached INTEL-LICENSE * file. If you do not find these files, copies can be found by writing to * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA, * 94704. Attention: Intel License Inquiry. */package net.tinyos.tinydb.parser;// CUP specification for sensor query parserimport java_cup.runtime.*;import java.util.*;import java.io.*;import javax.swing.*;import net.tinyos.tinydb.*;action code {: byte queryId = 1; int epochDur = 1024; TinyDBQuery tinyDBQuery = new TinyDBQuery(queryId, epochDur); 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); } :};parser code {: 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); } :}/* Terminals (tokens returned by the scanner). */terminal String NAME;terminal RPAREN, LPAREN, PERIOD, COMMA,COLON;//terminal SUM, CNT, AVG, MAX, MIN, MIN3, NOOP;//terminal EXPAVG, WINAVG, WINMIN, WINMAX, WINSUM, WINCNT, DELTA, TREND, WINRAND, ADPDELTA;terminal AND, OR;terminal GREATER_THAN, LESS_THAN, EQUAL, GREATER_EQUAL, LESS_EQUAL, NOT_EQUAL;terminal SELECT, FROM, WHERE, GROUP_BY;terminal Integer CONSTANT;terminal EPOCH, DURATION, ONE_SHOT, FOR;terminal AS;terminal ACTION, BUFFER, ONEVENT;terminal QUERY_STRING;terminal CREATE;terminal SIZE;terminal INTO;terminal DROPALL;terminal String ARITHMETIC_OP;/* Non terminals */non terminal TinyDBQuery query;non terminal select_stat, select_stat_list;non terminal AggOp agg; //tagg,agg_or_tagg;non terminal SelOp rel_op;non terminal FieldInfo attr;non terminal FieldInfo attr_core;non terminal from_stat, from_stat_list;non terminal where_stat;non terminal SelStmt condition;non terminal Vector more_conditions;non terminal ArithExpressionClass group_by_stat;non terminal String bool_op;non terminal epoch_stat, action_stat;non terminal source;non terminal arith_expr;non terminal query_core;non terminal create_buffer_stat;non terminal on_event_stat,event_param_list,event_param;non terminal QueryField field_entry;non terminal Vector field_list;non terminal Vector constant_list;precedence left NAME;precedence left BUFFER;//precedence nonassoc CONSTANT;start with query;query ::= on_event_stat query_core:qc action_stat{: RESULT = (TinyDBQuery)qc; :}| create_buffer_stat:qc2{: RESULT = (TinyDBQuery)qc2; :}| DROPALL {: tinyDBQuery.setDropTables(); RESULT = tinyDBQuery;:};query_core ::= select_stat from_stat where_stat group_by_stat:gf epoch_stat{: 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); 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); 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; :};create_buffer_stat ::= CREATE NAME:n SIZE CONSTANT:c AS LPAREN query_core:qc RPAREN{: ((TinyDBQuery)qc).useRamBuffer(c.shortValue()); ((TinyDBQuery)qc).setBufferName(n,true); RESULT = qc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -