libdap  Updated for version 3.17.0
D4ConstraintEvaluator.h
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 #ifndef D4CEDRIVER_H_
00027 #define D4CEDRIVER_H_
00028 
00029 #include <string>
00030 #include <vector>
00031 #include <stack>
00032 
00033 namespace libdap {
00034 
00035 class location;
00036 class DMR;
00037 class BaseType;
00038 class Array;
00039 class D4Dimension;
00040 
00044 class D4ConstraintEvaluator {
00045         struct index {
00046                 // start and stride are simple numbers; stop is either the stopping index or
00047                 // if to_end is true, is ignored and the subset runs to the end of the dimension
00048                 unsigned long long start, stride, stop;
00049                 // true if the slice indicates it does not contain a specific 'stop' value but
00050                 // goes to the end, whatever that value is.
00051                 bool rest;
00052                 // An empty slice ([]) means either the entire dimension or apply the shared
00053                 // dimension slice, depending on whether the corresponding shared dimension has
00054                 // been sliced.
00055                 bool empty;
00056 
00057                 // Added because the parser code needs it. Our code does not use this. jhrg 11/26/13
00058                 index(): start(0), stride(0), stop(0), rest(false), empty(false) {}
00059                 index(unsigned long long i, unsigned long long s, unsigned long long e, bool r, bool em)
00060                         : start(i), stride(s), stop(e), rest(r), empty(em) {}
00061         };
00062 
00063         index make_index() { return index(0, 1, 0, true /*rest*/, true /*empty*/); }
00064 
00065         index make_index(const std::string &is);
00066 
00067         index make_index(const std::string &i, const std::string &s, const std::string &e);
00068         index make_index(const std::string &i, unsigned long long s, const std::string &e);
00069 
00070         index make_index(const std::string &i, const std::string &s);
00071         index make_index(const std::string &i, unsigned long long s);
00072 
00073         bool d_trace_scanning;
00074         bool d_trace_parsing;
00075         bool d_result;
00076         std::string d_expr;
00077 
00078         DMR *d_dmr;
00079 
00080         std::vector<index> d_indexes;
00081 
00082         std::stack<BaseType*> d_basetype_stack;
00083 
00084         // d_expr should be set by parse! Its value is used by the parser right before
00085         // the actual parsing operation starts. jhrg 11/26/13
00086         std::string *expression() { return &d_expr; }
00087 #if 0
00088         void set_array_slices(const std::string &id, Array *a);
00089 #endif
00090         void search_for_and_mark_arrays(BaseType *btp);
00091         BaseType *mark_variable(BaseType *btp);
00092         BaseType *mark_array_variable(BaseType *btp);
00093 
00094         D4Dimension *slice_dimension(const std::string &id, const index &i);
00095 
00096         void push_index(const index &i) { d_indexes.push_back(i); }
00097 
00098         void push_basetype(BaseType *btp) { d_basetype_stack.push(btp); }
00099         BaseType *top_basetype() const { return d_basetype_stack.empty() ? 0 : d_basetype_stack.top(); }
00100         // throw on pop with an empty stack?
00101         void pop_basetype() { d_basetype_stack.pop(); }
00102 
00103         void throw_not_found(const std::string &id, const std::string &ident);
00104         void throw_not_array(const std::string &id, const std::string &ident);
00105 
00106         friend class D4CEParser;
00107 
00108 public:
00109         D4ConstraintEvaluator() : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(0) { }
00110         D4ConstraintEvaluator(DMR *dmr) : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(dmr) { }
00111 
00112         virtual ~D4ConstraintEvaluator() { }
00113 
00114         bool parse(const std::string &expr);
00115 
00116         bool trace_scanning() const { return d_trace_scanning; }
00117         void set_trace_scanning(bool ts) { d_trace_scanning = ts; }
00118 
00119         bool trace_parsing() const { return d_trace_parsing; }
00120         void set_trace_parsing(bool tp) { d_trace_parsing = tp; }
00121 
00122         bool result() const { return d_result; }
00123         void set_result(bool r) { d_result = r; }
00124 
00125         DMR *dmr() const { return d_dmr; }
00126         void set_dmr(DMR *dmr) { d_dmr = dmr; }
00127 
00128         void error(const libdap::location &l, const std::string &m);
00129 };
00130 
00131 } /* namespace libdap */
00132 #endif /* D4CEDRIVER_H_ */