00001 //# RecordGram.h: Grammar for record command lines 00002 //# Copyright (C) 2000 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id$ 00027 00028 #ifndef TABLES_RECORDGRAM_H 00029 #define TABLES_RECORDGRAM_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/casa/BasicSL/String.h> 00034 #include <casacore/tables/TaQL/TableGram.h> 00035 #include <casacore/tables/TaQL/TaQLStyle.h> 00036 #include <casacore/tables/Tables/Table.h> 00037 #include <casacore/casa/OS/Mutex.h> 00038 #include <map> 00039 00040 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00041 00042 //# Forward Declarations 00043 class TableExprNode; 00044 class TableExprNodeSet; 00045 class TableExprNodeSetElem; 00046 class RecordInterface; 00047 class Table; 00048 00049 // <summary> 00050 // Global functions for flex/bison scanner/parser for RecordGram 00051 // </summary> 00052 00053 // <use visibility=local> 00054 00055 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00056 // </reviewed> 00057 00058 // <prerequisite> 00059 //# Classes you should understand before using this one. 00060 // <li> RecordGram.l and .y (flex and bison grammar) 00061 // </prerequisite> 00062 00063 // <synopsis> 00064 // Global functions are needed to define the input of the flex scanner 00065 // and to start the bison parser. 00066 // The input is taken from a string. 00067 // </synopsis> 00068 00069 // <motivation> 00070 // It is necessary to be able to give a record select command in ASCII. 00071 // This can be used in a CLI or in the record browser to get a subset 00072 // of a record or to sort a record. 00073 // </motivation> 00074 00075 // <todo asof="$DATE:$"> 00076 //# A List of bugs, limitations, extensions or planned refinements. 00077 // </todo> 00078 00079 // <group name=RecordGramFunctions> 00080 00081 // Declare the bison parser (is implemented by bison command). 00082 int recordGramParseCommand (const String& command); 00083 00084 // The yyerror function for the parser. 00085 // It throws an exception with the current token. 00086 void RecordGramerror (const char*); 00087 00088 // Give the current position in the string. 00089 // This can be used when parse errors occur. 00090 Int& recordGramPosition(); 00091 00092 // Declare the input routine for flex/bison. 00093 int recordGramInput (char* buf, int max_size); 00094 00095 // A function to remove escaped characters. 00096 inline String recordGramRemoveEscapes (const String& in) 00097 { return tableGramRemoveEscapes (in); } 00098 00099 // A function to remove quotes from a quoted string. 00100 inline String recordGramRemoveQuotes (const String& in) 00101 { return tableGramRemoveQuotes (in); } 00102 00103 // </group> 00104 00105 00106 00107 // <summary> 00108 // Helper class for values in RecordGram 00109 // </summary> 00110 00111 // <use visibility=local> 00112 00113 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00114 // </reviewed> 00115 00116 // <synopsis> 00117 // A record selection command is lexically analyzed via flex. 00118 // An object of this class is used to hold a value (like a name 00119 // or a literal) for later use in the parser code. 00120 // </synopsis> 00121 00122 class RecordGramVal 00123 { 00124 public: 00125 Int type; //# i=Int, f=Double, c=DComplex, s=String r=Regex 00126 String str; //# string literal; table name; field name; unit 00127 Bool bval; //# bool literal 00128 Int64 ival; //# integer literal 00129 Double dval[2]; //# Double/DComplex literal 00130 }; 00131 00132 00133 00134 00135 // <summary> 00136 // Select-class for flex/bison scanner/parser for RecordGram 00137 // </summary> 00138 00139 // <use visibility=local> 00140 00141 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00142 // </reviewed> 00143 00144 // <prerequisite> 00145 //# Classes you should understand before using this one. 00146 // <li> RecordGram.l and .y (flex and bison grammar) 00147 // </prerequisite> 00148 00149 // <synopsis> 00150 // This class is needed for the the actions in the flex scanner 00151 // and bison parser. 00152 // This stores the information by constructing RecordGram objects 00153 // as needed and storing them in a List. 00154 // 00155 // An expression can be given as a string and parsed by the <src>parse</src> 00156 // function. 00157 // The grammar used is as much as possible the same as that for the 00158 // WHERE clause in TaQL (see Note 199). 00159 // It is possible to set the TaQL style to use by setting 00160 // <src>theirTaQLStyle</src> before calling the parse functions. 00161 // A better way is to define the style with the 'USING STYLE' part of 00162 // the command (similar to TaQL). 00163 // </synopsis> 00164 00165 // <motivation> 00166 // It is necessary to be able to give a record select command in ASCII. 00167 // It is used by the ACSIS people. 00168 // </motivation> 00169 00170 //# <todo asof="$DATE:$"> 00171 //# A List of bugs, limitations, extensions or planned refinements. 00172 //# </todo> 00173 00174 00175 class RecordGram 00176 { 00177 public: 00178 // Define the types of tokens in the grammar. 00179 enum Token {Node, Val, Elem, Set}; 00180 00181 // Convert an expression string to an expression tree. 00182 // The expression will operate on a series of Record objects. 00183 // The given record is needed to know the type of the fields used in 00184 // the expression. 00185 //# The record will be put into the static variable to be used by 00186 //# the other functions. 00187 static TableExprNode parse (const RecordInterface& record, 00188 const String& expression); 00189 00190 // Convert an expression string to an expression tree. 00191 // The expression will operate on the given table. 00192 //# The record will be put into the static variable to be used by 00193 //# the other functions. 00194 static TableExprNode parse (const Table& table, 00195 const String& expression); 00196 00197 // Create a TableExprNode from a literal. 00198 static TableExprNode handleLiteral (RecordGramVal*); 00199 00200 // Find the field name and create a TableExprNode from it. 00201 static TableExprNode handleField (const String& name); 00202 00203 // Handle a function. 00204 static TableExprNode handleFunc (const String& name, 00205 const TableExprNodeSet& arguments); 00206 00207 // Handle a regex. 00208 static TableExprNode handleRegex (const TableExprNode& left, 00209 const String& regex); 00210 00211 // Set the final node pointer. 00212 static void setNodePtr (TableExprNode* nodePtr) 00213 { theirNodePtr = nodePtr; } 00214 00215 // Define the global TaQLStyle to use. 00216 // By default it is glish style. 00217 static TaQLStyle theirTaQLStyle; 00218 00219 // Add a token to the list of tokens to be deleted 00220 // for the possible tokens in the RecordGram.yy union. 00221 static void addToken (TableExprNode* ptr); 00222 static void addToken (RecordGramVal* ptr); 00223 static void addToken (TableExprNodeSet* ptr); 00224 static void addToken (TableExprNodeSetElem* ptr); 00225 // Delete a token and remove from the list. 00226 static void deleteToken (TableExprNode* ptr); 00227 static void deleteToken (RecordGramVal* ptr); 00228 static void deleteToken (TableExprNodeSet* ptr); 00229 static void deleteToken (TableExprNodeSetElem* ptr); 00230 // Delete all tokens not deleted yet. 00231 static void deleteTokenStorage(); 00232 00233 private: 00234 // Do the conversion of an expression string to an expression tree. 00235 static TableExprNode doParse (const String& expression); 00236 00237 // Add a token to the list of tokens to be deleted. 00238 static void addToken (void* ptr, Token type) 00239 { theirTokens[ptr] = type; } 00240 // Remove a token from the list of tokens to be deleted. 00241 static void removeToken (void* ptr) 00242 { theirTokens.erase (ptr); } 00243 00244 static std::map<void*, Token> theirTokens; 00245 static const RecordInterface* theirRecPtr; 00246 static const Table* theirTabPtr; 00247 static TableExprNode* theirNodePtr; 00248 static Mutex theirMutex; 00249 }; 00250 00251 00252 00253 } //# NAMESPACE CASACORE - END 00254 00255 #endif