dceparse.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc.
  2. See the COPYRIGHT file for more information. */
  3. /* Parser actions for constraint expressions */
  4. /* Since oc does not use the constraint parser,
  5. they functions all just abort if called.
  6. */
  7. #include "config.h"
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <assert.h>
  12. #include "netcdf.h"
  13. #include "nclist.h"
  14. #include "ncbytes.h"
  15. #include "dceconstraints.h"
  16. #include "dceparselex.h"
  17. static Object collectlist(Object list0, Object decl);
  18. void
  19. projections(DCEparsestate* state, Object list0)
  20. {
  21. NClist* list = (NClist*)list0;
  22. if(list != NULL) {
  23. nclistfree(state->constraint->projections);
  24. state->constraint->projections = list;
  25. }
  26. #ifdef DEBUG
  27. fprintf(stderr," ce.projections: %s\n",
  28. dcetostring((DCEnode*)state->constraint->projections));
  29. #endif
  30. }
  31. void
  32. selections(DCEparsestate* state, Object list0)
  33. {
  34. NClist* list = (NClist*)list0;
  35. if(list != NULL) {
  36. nclistfree(state->constraint->selections);
  37. state->constraint->selections = list;
  38. }
  39. #ifdef DEBUG
  40. fprintf(stderr," ce.selections: %s\n",
  41. dcetostring((DCEnode*)state->constraint->selections));
  42. #endif
  43. }
  44. Object
  45. projectionlist(DCEparsestate* state, Object list0, Object decl)
  46. {
  47. return collectlist(list0,decl);
  48. }
  49. Object
  50. projection(DCEparsestate* state, Object varorfcn)
  51. {
  52. DCEprojection* p = (DCEprojection*)dcecreate(CES_PROJECT);
  53. CEsort tag = *(CEsort*)varorfcn;
  54. if(tag == CES_FCN)
  55. p->fcn = varorfcn;
  56. else
  57. p->var = varorfcn;
  58. p->discrim = tag;
  59. #ifdef DEBUG
  60. fprintf(stderr," ce.projection: %s\n",
  61. dcetostring((DCEnode*)p));
  62. #endif
  63. return p;
  64. }
  65. Object
  66. segmentlist(DCEparsestate* state, Object var0, Object decl)
  67. {
  68. /* watch out: this is non-standard */
  69. NClist* list;
  70. DCEvar* v = (DCEvar*)var0;
  71. if(v==NULL) v = (DCEvar*)dcecreate(CES_VAR);
  72. list = v->segments;
  73. if(list == NULL) list = nclistnew();
  74. nclistpush(list,(ncelem)decl);
  75. v->segments = list;
  76. return v;
  77. }
  78. Object
  79. segment(DCEparsestate* state, Object name, Object slices0)
  80. {
  81. int i;
  82. DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT);
  83. NClist* slices = (NClist*)slices0;
  84. segment->name = strdup((char*)name);
  85. if(slices != NULL && nclistlength(slices) > 0) {
  86. segment->rank = nclistlength(slices);
  87. segment->slicesdefined = 1; /* but not declsizes */
  88. for(i=0;i<nclistlength(slices);i++) {
  89. DCEslice* slice = (DCEslice*)nclistget(slices,i);
  90. segment->slices[i] = *slice;
  91. free(slice);
  92. }
  93. nclistfree(slices);
  94. } else
  95. segment->slicesdefined = 0;
  96. #ifdef DEBUG
  97. fprintf(stderr," ce.segment: %s\n",
  98. dumpsegment(segment));
  99. #endif
  100. return segment;
  101. }
  102. Object
  103. rangelist(DCEparsestate* state, Object list0, Object decl)
  104. {
  105. return collectlist(list0,decl);
  106. }
  107. Object
  108. range(DCEparsestate* state, Object sfirst, Object sstride, Object slast)
  109. {
  110. DCEslice* slice = (DCEslice*)dcecreate(CES_SLICE);
  111. unsigned long first,stride,last;
  112. /* Note: that incoming arguments are strings; we must convert to size_t;
  113. but we do know they are legal integers or NULL */
  114. sscanf((char*)sfirst,"%lu",&first); /* always defined */
  115. if(slast != NULL)
  116. sscanf((char*)slast,"%lu",&last);
  117. else
  118. last = first;
  119. if(sstride != NULL)
  120. sscanf((char*)sstride,"%lu",&stride);
  121. else
  122. stride = 1; /* default */
  123. if(stride == 0)
  124. dceerror(state,"Illegal index for range stride");
  125. if(last < first)
  126. dceerror(state,"Illegal index for range last index");
  127. slice->first = first;
  128. slice->stride = stride;
  129. slice->stop = last + 1;
  130. slice->length = slice->stop - slice->first;
  131. slice->count = slice->length / slice->stride;
  132. #ifdef DEBUG
  133. fprintf(stderr," ce.slice: %s\n",
  134. dumpslice(slice));
  135. #endif
  136. return slice;
  137. }
  138. Object
  139. range1(DCEparsestate* state, Object rangenumber)
  140. {
  141. int range = -1;
  142. sscanf((char*)rangenumber,"%u",&range);
  143. if(range < 0) {
  144. dceerror(state,"Illegal range index");
  145. }
  146. return rangenumber;
  147. }
  148. Object
  149. clauselist(DCEparsestate* state, Object list0, Object decl)
  150. {
  151. return collectlist(list0,decl);
  152. }
  153. Object
  154. sel_clause(DCEparsestate* state, int selcase,
  155. Object lhs, Object relop0, Object values)
  156. {
  157. DCEselection* sel = (DCEselection*)dcecreate(CES_SELECT);
  158. sel->operator = (CEsort)relop0;
  159. sel->lhs = (DCEvalue*)lhs;
  160. if(selcase == 2) {/*singleton value*/
  161. sel->rhs = nclistnew();
  162. nclistpush(sel->rhs,(ncelem)values);
  163. } else
  164. sel->rhs = (NClist*)values;
  165. return sel;
  166. }
  167. Object
  168. indexpath(DCEparsestate* state, Object list0, Object index)
  169. {
  170. return collectlist(list0,index);
  171. }
  172. Object
  173. array_indices(DCEparsestate* state, Object list0, Object indexno)
  174. {
  175. DCEslice* slice;
  176. long long start = -1;
  177. NClist* list = (NClist*)list0;
  178. if(list == NULL) list = nclistnew();
  179. sscanf((char*)indexno,"%lld",&start);
  180. if(start < 0) {
  181. dceerror(state,"Illegal array index");
  182. start = 1;
  183. }
  184. slice = (DCEslice*)dcecreate(CES_SLICE);
  185. slice->first = start;
  186. slice->stride = 1;
  187. slice->count = 1;
  188. slice->length = 1;
  189. slice->stop = start+1;
  190. nclistpush(list,(ncelem)slice);
  191. return list;
  192. }
  193. Object
  194. indexer(DCEparsestate* state, Object name, Object indices)
  195. {
  196. int i;
  197. NClist* list = (NClist*)indices;
  198. DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT);
  199. seg->name = strdup((char*)name);
  200. for(i=0;i<nclistlength(list);i++) {
  201. DCEslice* slice = (DCEslice*)nclistget(list,i);
  202. seg->slices[i] = *slice;
  203. free(slice);
  204. }
  205. nclistfree(indices);
  206. return seg;
  207. }
  208. Object
  209. function(DCEparsestate* state, Object fcnname, Object args)
  210. {
  211. DCEfcn* fcn = (DCEfcn*)dcecreate(CES_FCN);
  212. fcn->name = nulldup((char*)fcnname);
  213. fcn->args = args;
  214. return fcn;
  215. }
  216. Object
  217. arg_list(DCEparsestate* state, Object list0, Object decl)
  218. {
  219. return collectlist(list0,decl);
  220. }
  221. Object
  222. value_list(DCEparsestate* state, Object list0, Object decl)
  223. {
  224. return collectlist(list0,decl);
  225. }
  226. Object
  227. value(DCEparsestate* state, Object val)
  228. {
  229. DCEvalue* ncvalue = (DCEvalue*)dcecreate(CES_VALUE);
  230. CEsort tag = *(CEsort*)val;
  231. switch (tag) {
  232. case CES_VAR: ncvalue->var = (DCEvar*)val; break;
  233. case CES_FCN: ncvalue->fcn = (DCEfcn*)val; break;
  234. case CES_CONST: ncvalue->constant = (DCEconstant*)val; break;
  235. default: abort(); break;
  236. }
  237. ncvalue->discrim = tag;
  238. return ncvalue;
  239. }
  240. Object
  241. var(DCEparsestate* state, Object indexpath)
  242. {
  243. DCEvar* v = (DCEvar*)dcecreate(CES_VAR);
  244. v->segments = (NClist*)indexpath;
  245. return v;
  246. }
  247. Object
  248. constant(DCEparsestate* state, Object val, int tag)
  249. {
  250. DCEconstant* con = (DCEconstant*)dcecreate(CES_CONST);
  251. char* text = (char*)val;
  252. char* endpoint = NULL;
  253. switch (tag) {
  254. case SCAN_STRINGCONST:
  255. con->discrim = CES_STR;
  256. con->text = nulldup(text);
  257. break;
  258. case SCAN_NUMBERCONST:
  259. con->intvalue = strtoll(text,&endpoint,10);
  260. if(*text != '\0' && *endpoint == '\0') {
  261. con->discrim = CES_INT;
  262. } else {
  263. con->floatvalue = strtod(text,&endpoint);
  264. if(*text != '\0' && *endpoint == '\0')
  265. con->discrim = CES_FLOAT;
  266. else abort();
  267. }
  268. break;
  269. default: abort(); break;
  270. }
  271. return con;
  272. }
  273. static Object
  274. collectlist(Object list0, Object decl)
  275. {
  276. NClist* list = (NClist*)list0;
  277. if(list == NULL) list = nclistnew();
  278. nclistpush(list,(ncelem)decl);
  279. return list;
  280. }
  281. Object
  282. makeselectiontag(CEsort tag)
  283. {
  284. return (Object) tag;
  285. }
  286. int
  287. dceerror(DCEparsestate* state, char* msg)
  288. {
  289. strcpy(state->errorbuf,msg);
  290. state->errorcode=1;
  291. return 0;
  292. }
  293. static void
  294. dce_parse_cleanup(DCEparsestate* state)
  295. {
  296. dcelexcleanup(&state->lexstate); /* will free */
  297. }
  298. static DCEparsestate*
  299. ce_parse_init(char* input, DCEconstraint* constraint)
  300. {
  301. DCEparsestate* state = NULL;
  302. if(input==NULL) {
  303. dceerror(state,"ce_parse_init: no input buffer");
  304. } else {
  305. state = (DCEparsestate*)calloc(1,sizeof(DCEparsestate));
  306. if(state==NULL) return (DCEparsestate*)NULL;
  307. state->errorbuf[0] = '\0';
  308. state->errorcode = 0;
  309. dcelexinit(input,&state->lexstate);
  310. state->constraint = constraint;
  311. }
  312. return state;
  313. }
  314. #ifdef PARSEDEBUG
  315. extern int dcedebug;
  316. #endif
  317. /* Wrapper for ceparse */
  318. int
  319. dapceparse(char* input, DCEconstraint* constraint, char** errmsgp)
  320. {
  321. DCEparsestate* state;
  322. int errcode = 0;
  323. #ifdef PARSEDEBUG
  324. dcedebug = 1;
  325. #endif
  326. if(input != NULL) {
  327. #ifdef DEBUG
  328. fprintf(stderr,"dceeparse: input=%s\n",input);
  329. #endif
  330. state = ce_parse_init(input,constraint);
  331. if(dceparse(state) == 0) {
  332. #ifdef DEBUG
  333. if(nclistlength(constraint->projections) > 0)
  334. fprintf(stderr,"dceeparse: projections=%s\n",
  335. dcetostring((DCEnode*)constraint->projections));
  336. #endif
  337. #ifdef DEBUG
  338. if(nclistlength(constraint->selections) > 0)
  339. fprintf(stderr,"dceeparse: selections=%s\n",
  340. dumpselections(constraint->selections));
  341. #endif
  342. } else {
  343. if(errmsgp) *errmsgp = nulldup(state->errorbuf);
  344. }
  345. errcode = state->errorcode;
  346. dce_parse_cleanup(state);
  347. }
  348. return errcode;
  349. }
  350. #ifdef PARSEDEBUG
  351. Object
  352. debugobject(Object o)
  353. {
  354. return o;
  355. }
  356. #endif