31 #include "D4CEScanner.h" 32 #include "D4ConstraintEvaluator.h" 33 #include "d4_ce_parser.tab.hh" 36 #include "D4Dimensions.h" 39 #include "Constructor.h" 46 bool D4ConstraintEvaluator::parse(
const std::string &expr)
50 std::istringstream iss(expr);
51 D4CEScanner scanner(iss);
52 D4CEParser parser(scanner, *
this );
54 if (trace_parsing()) {
55 parser.set_debug_level(1);
56 parser.set_debug_stream(std::cerr);
59 return parser.parse() == 0;
64 D4ConstraintEvaluator::set_array_slices(
const std::string &
id, Array *a)
67 if (d_indexes.size() != a->dimensions())
68 throw Error(malformed_expr,
"The index constraint for '" +
id +
"' does not match its rank.");
71 for (vector<index>::iterator i = d_indexes.begin(), e = d_indexes.end(); i != e; ++i) {
72 if ((*i).stride > (
unsigned long long)a->dimension_stop(d,
false))
73 throw Error(malformed_expr,
"For '" +
id +
"', the index stride value is greater than the number of elements in the Array");
74 if (!(*i).rest && ((*i).stop) > (
unsigned long long)a->dimension_stop(d,
false))
75 throw Error(malformed_expr,
"For '" +
id +
"', the index stop value is greater than the number of elements in the Array");
77 D4Dimension *dim = a->dimension_D4dim(d);
84 if (dim && (*i).empty) {
85 a->add_constraint(d, dim);
88 a->add_constraint(d, (*i).start, (*i).stride, (*i).rest ? -1 : (*i).stop);
99 D4ConstraintEvaluator::throw_not_found(
const string &
id,
const string &ident)
101 throw Error(no_such_variable, d_expr +
": The variable " +
id +
" was not found in the dataset (" + ident +
").");
105 D4ConstraintEvaluator::throw_not_array(
const string &
id,
const string &ident)
107 throw Error(no_such_variable, d_expr +
": The variable '" +
id +
"' is not an Array variable (" + ident +
").");
111 D4ConstraintEvaluator::search_for_and_mark_arrays(BaseType *btp)
113 DBG(cerr <<
"Entering D4ConstraintEvaluator::search_for_and_mark_arrays...(" << btp->name() <<
")" << endl);
115 assert(btp->is_constructor_type());
117 Constructor *ctor =
static_cast<Constructor*
>(btp);
118 for (Constructor::Vars_iter i = ctor->var_begin(), e = ctor->var_end(); i != e; ++i) {
119 switch ((*i)->type()) {
121 DBG(cerr <<
"Found an array: " << (*i)->name() << endl);
122 mark_array_variable(*i);
124 case dods_structure_c:
125 case dods_sequence_c:
126 DBG(cerr <<
"Found a ctor: " << (*i)->name() << endl);
127 search_for_and_mark_arrays(*i);
145 D4ConstraintEvaluator::mark_variable(BaseType *btp)
149 DBG(cerr <<
"In D4ConstraintEvaluator::mark_variable... (" << btp->name() <<
"; " << btp->type_name() <<
")" << endl);
151 btp->set_send_p(
true);
153 if (btp->type() == dods_array_c ) {
154 mark_array_variable(btp);
158 if (btp->is_constructor_type()) {
159 search_for_and_mark_arrays(btp);
161 else if (btp->type() == dods_array_c && btp->var() && btp->var()->is_constructor_type()) {
162 search_for_and_mark_arrays(btp->var());
166 BaseType *parent = btp->get_parent();
168 parent->BaseType::set_send_p(
true);
169 parent = parent->get_parent();
188 D4ConstraintEvaluator::mark_array_variable(BaseType *btp)
190 assert(btp->type() == dods_array_c);
192 Array *a =
static_cast<Array*
>(btp);
197 if (d_indexes.empty()) {
198 for (
Array::Dim_iter d = a->dim_begin(), de = a->dim_end(); d != de; ++d) {
199 D4Dimension *dim = a->dimension_D4dim(d);
201 a->add_constraint(d, dim);
207 if (d_indexes.size() != a->dimensions())
208 throw Error(malformed_expr,
"The index constraint for '" + btp->name() +
"' does not match its rank.");
211 for (vector<index>::iterator i = d_indexes.begin(), e = d_indexes.end(); i != e; ++i) {
212 if ((*i).stride > (
unsigned long long) (a->dimension_stop(d,
false) - a->dimension_start(d,
false)) + 1)
213 throw Error(malformed_expr,
"For '" + btp->name() +
"', the index stride value is greater than the number of elements in the Array");
214 if (!(*i).rest && ((*i).stop) > (
unsigned long long) (a->dimension_stop(d,
false) - a->dimension_start(d,
false)) + 1)
215 throw Error(malformed_expr,
"For '" + btp->name() +
"', the index stop value is greater than the number of elements in the Array");
217 D4Dimension *dim = a->dimension_D4dim(d);
224 if (dim && (*i).empty) {
225 a->add_constraint(d, dim);
228 a->add_constraint(d, (*i).start, (*i).stride, (*i).rest ? -1 : (*i).stop);
249 D4ConstraintEvaluator::slice_dimension(
const std::string &
id,
const index &i)
253 if (i.stride > dim->size())
254 throw Error(malformed_expr,
"For '" +
id +
"', the index stride value is greater than the size of the dimension");
255 if (!i.rest && (i.stop > dim->size() - 1))
256 throw Error(malformed_expr,
"For '" +
id +
"', the index stop value is greater than the size of the dimension");
258 dim->set_constraint(i.start, i.stride, i.rest ? dim->size() - 1: i.stop);
263 D4ConstraintEvaluator::index
264 D4ConstraintEvaluator::make_index(
const std::string &i)
266 unsigned long long v = get_ull(i.c_str());
267 return index(v, 1, v,
false,
false );
270 D4ConstraintEvaluator::index
271 D4ConstraintEvaluator::make_index(
const std::string &i,
const std::string &s,
const std::string &e)
273 return index(get_ull(i.c_str()), get_ull(s.c_str()), get_ull(e.c_str()),
false,
false );
276 D4ConstraintEvaluator::index
277 D4ConstraintEvaluator::make_index(
const std::string &i,
unsigned long long s,
const std::string &e)
279 return index(get_ull(i.c_str()), s, get_ull(e.c_str()),
false,
false );
282 D4ConstraintEvaluator::index
283 D4ConstraintEvaluator::make_index(
const std::string &i,
const std::string &s)
285 return index(get_ull(i.c_str()), get_ull(s.c_str()), 0,
true,
false );
288 D4ConstraintEvaluator::index
289 D4ConstraintEvaluator::make_index(
const std::string &i,
unsigned long long s)
291 return index(get_ull(i.c_str()), s, 0,
true,
false );
298 D4ConstraintEvaluator::error(
const libdap::location &l,
const std::string &m)
301 oss << l <<
": " << m << ends;
302 throw Error(malformed_expr, oss.str());
D4Dimension * find_dim(const string &path)
Find the dimension using a path. Using the DAP4 name syntax, lookup a dimension. The dimension must b...
std::vector< dimension >::iterator Dim_iter