1 2 // -*- mode: c++; c-basic-offset:4 -*- 3 4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data 5 // Access Protocol. 6 7 // Copyright (c) 2002,2003 OPeNDAP, Inc. 8 // Author: James Gallagher <jgallagher@opendap.org> 9 // 10 // This library is free software; you can redistribute it and/or 11 // modify it under the terms of the GNU Lesser General Public 12 // License as published by the Free Software Foundation; either 13 // version 2.1 of the License, or (at your option) any later version. 14 // 15 // This library is distributed in the hope that it will be useful, 16 // but WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 // Lesser General Public License for more details. 19 // 20 // You should have received a copy of the GNU Lesser General Public 21 // License along with this library; if not, write to the Free Software 22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 23 // 24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. 25 26 #ifndef D4CEDRIVER_H_ 27 #define D4CEDRIVER_H_ 28 29 #include <string> 30 #include <vector> 31 #include <stack> 32 33 namespace libdap { 34 35 class location; 36 class DMR; 37 class BaseType; 38 class Array; 39 class D4Dimension; 40 class D4FilterClause; 41 class D4FilterClauseList; 42 43 /** 44 * Driver for the DAP4 Constraint Expression parser. 45 */ 46 class D4ConstraintEvaluator { 47 struct index { 48 // start and stride are simple numbers; stop is either the stopping index or 49 // if rest is true, is ignored and the subset runs to the end of the dimension 50 unsigned long long start, stride, stop; 51 // true if the slice indicates it does not contain a specific 'stop' value but 52 // goes to the end, whatever that value is. 53 bool rest; 54 // An empty slice ([]) means either the entire dimension or apply the shared 55 // dimension slice, depending on whether the corresponding shared dimension has 56 // been sliced. 57 bool empty; 58 // When a slice is applied to an Array with Maps, we need to know the name of 59 // each dimension. These names are then used to apply the slice to each of the 60 // Maps (Maps may have fewer dimensions than the Array, but the idea that a 61 // Map is a simple vector doesn't hold for DAP4, so the mapping between a slice's 62 // indexes and the set of Maps can be complex - use the names to make sure 63 // all cases are covered. The value of this field may be empty. 64 std::string dim_name; 65 66 // Added because the parser code needs it. Our code does not use this. jhrg 11/26/13 indexindex67 index(): start(0), stride(0), stop(0), rest(false), empty(false), dim_name("") {} indexindex68 index(unsigned long long i, unsigned long long s, unsigned long long e, bool r, bool em, const std::string &n) 69 : start(i), stride(s), stop(e), rest(r), empty(em), dim_name(n) {} 70 }; 71 make_index()72 index make_index() { return index(0, 1, 0, true /*rest*/, true /*empty*/, ""); } 73 74 index make_index(const std::string &is); 75 76 index make_index(const std::string &i, const std::string &s, const std::string &e); 77 index make_index(const std::string &i, unsigned long long s, const std::string &e); 78 79 index make_index(const std::string &i, const std::string &s); 80 index make_index(const std::string &i, unsigned long long s); 81 82 bool d_trace_scanning; 83 bool d_trace_parsing; 84 bool d_result; 85 std::string d_expr; 86 87 DMR *d_dmr; 88 89 std::vector<index> d_indexes; 90 91 std::stack<BaseType*> d_basetype_stack; 92 93 // d_expr should be set by parse! Its value is used by the parser right before 94 // the actual parsing operation starts. jhrg 11/26/13 expression()95 std::string *expression() { return &d_expr; } 96 97 void search_for_and_mark_arrays(BaseType *btp); 98 BaseType *mark_variable(BaseType *btp); 99 BaseType *mark_array_variable(BaseType *btp); 100 101 D4Dimension *slice_dimension(const std::string &id, const index &i); 102 push_index(const index & i)103 void push_index(const index &i) { d_indexes.push_back(i); } 104 push_basetype(BaseType * btp)105 void push_basetype(BaseType *btp) { d_basetype_stack.push(btp); } top_basetype()106 BaseType *top_basetype() const { return d_basetype_stack.empty() ? 0 : d_basetype_stack.top(); } 107 // throw on pop with an empty stack? pop_basetype()108 void pop_basetype() { d_basetype_stack.pop(); } 109 110 void throw_not_found(const std::string &id, const std::string &ident); 111 void throw_not_array(const std::string &id, const std::string &ident); 112 113 // Build FilterClauseList for filter clauses for a Sequence 114 void add_filter_clause(const std::string &op, const std::string &arg1, const std::string &arg2); 115 116 std::string &remove_quotes(std::string &src); 117 118 friend class D4CEParser; 119 120 public: D4ConstraintEvaluator()121 D4ConstraintEvaluator() : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(0) { } D4ConstraintEvaluator(DMR * dmr)122 D4ConstraintEvaluator(DMR *dmr) : d_trace_scanning(false), d_trace_parsing(false), d_result(false), d_expr(""), d_dmr(dmr) { } 123 ~D4ConstraintEvaluator()124 virtual ~D4ConstraintEvaluator() { } 125 126 bool parse(const std::string &expr); 127 trace_scanning()128 bool trace_scanning() const { return d_trace_scanning; } set_trace_scanning(bool ts)129 void set_trace_scanning(bool ts) { d_trace_scanning = ts; } 130 trace_parsing()131 bool trace_parsing() const { return d_trace_parsing; } set_trace_parsing(bool tp)132 void set_trace_parsing(bool tp) { d_trace_parsing = tp; } 133 result()134 bool result() const { return d_result; } set_result(bool r)135 void set_result(bool r) { d_result = r; } 136 dmr()137 DMR *dmr() const { return d_dmr; } set_dmr(DMR * dmr)138 void set_dmr(DMR *dmr) { d_dmr = dmr; } 139 140 void error(const libdap::location &l, const std::string &m); 141 }; 142 143 } /* namespace libdap */ 144 #endif /* D4CEDRIVER_H_ */ 145