Merge branch 'master' of git://git.postgresql.org/git/postgresql
[pgsql-fdw.git] / contrib / cube / cubeparse.y
blobe67df856f20bac6c05bb6cf0608d7bfda67e45dc
1 %{
2 /* NdBox = [(lowerleft),(upperright)] */
3 /* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
5 /* $PostgreSQL$ */
7 #define YYPARSE_PARAM result /* need this to pass a pointer (void *) to yyparse */
8 #define YYSTYPE char *
9 #define YYDEBUG 1
11 #include "postgres.h"
13 #include "cubedata.h"
16 * Bison doesn't allocate anything that needs to live across parser calls,
17 * so we can easily have it use palloc instead of malloc. This prevents
18 * memory leaks if we error out during parsing. Note this only works with
19 * bison >= 2.0. However, in bison 1.875 the default is to use alloca()
20 * if possible, so there's not really much problem anyhow, at least if
21 * you're building with gcc.
23 #define YYMALLOC palloc
24 #define YYFREE pfree
26 extern int cube_yylex(void);
28 static char *scanbuf;
29 static int scanbuflen;
31 void cube_yyerror(const char *message);
32 int cube_yyparse(void *result);
34 static int delim_count(char *s, char delim);
35 static NDBOX * write_box(unsigned int dim, char *str1, char *str2);
36 static NDBOX * write_point_as_box(char *s, int dim);
40 /* BISON Declarations */
41 %expect 0
42 %name-prefix="cube_yy"
44 %token CUBEFLOAT O_PAREN C_PAREN O_BRACKET C_BRACKET COMMA
45 %start box
47 /* Grammar follows */
50 box:
51 O_BRACKET paren_list COMMA paren_list C_BRACKET {
53 int dim;
55 dim = delim_count($2, ',') + 1;
56 if ( (delim_count($4, ',') + 1) != dim ) {
57 ereport(ERROR,
58 (errcode(ERRCODE_SYNTAX_ERROR),
59 errmsg("bad cube representation"),
60 errdetail("Different point dimensions in (%s) and (%s).",
61 $2, $4)));
62 YYABORT;
64 if (dim > CUBE_MAX_DIM) {
65 ereport(ERROR,
66 (errcode(ERRCODE_SYNTAX_ERROR),
67 errmsg("bad cube representation"),
68 errdetail("A cube cannot have more than %d dimensions.",
69 CUBE_MAX_DIM)));
70 YYABORT;
73 *((void **)result) = write_box( dim, $2, $4 );
77 paren_list COMMA paren_list {
78 int dim;
80 dim = delim_count($1, ',') + 1;
82 if ( (delim_count($3, ',') + 1) != dim ) {
83 ereport(ERROR,
84 (errcode(ERRCODE_SYNTAX_ERROR),
85 errmsg("bad cube representation"),
86 errdetail("Different point dimensions in (%s) and (%s).",
87 $1, $3)));
88 YYABORT;
90 if (dim > CUBE_MAX_DIM) {
91 ereport(ERROR,
92 (errcode(ERRCODE_SYNTAX_ERROR),
93 errmsg("bad cube representation"),
94 errdetail("A cube cannot have more than %d dimensions.",
95 CUBE_MAX_DIM)));
96 YYABORT;
99 *((void **)result) = write_box( dim, $1, $3 );
103 paren_list {
104 int dim;
106 dim = delim_count($1, ',') + 1;
107 if (dim > CUBE_MAX_DIM) {
108 ereport(ERROR,
109 (errcode(ERRCODE_SYNTAX_ERROR),
110 errmsg("bad cube representation"),
111 errdetail("A cube cannot have more than %d dimensions.",
112 CUBE_MAX_DIM)));
113 YYABORT;
116 *((void **)result) = write_point_as_box($1, dim);
121 list {
122 int dim;
124 dim = delim_count($1, ',') + 1;
125 if (dim > CUBE_MAX_DIM) {
126 ereport(ERROR,
127 (errcode(ERRCODE_SYNTAX_ERROR),
128 errmsg("bad cube representation"),
129 errdetail("A cube cannot have more than %d dimensions.",
130 CUBE_MAX_DIM)));
131 YYABORT;
133 *((void **)result) = write_point_as_box($1, dim);
137 paren_list:
138 O_PAREN list C_PAREN {
139 $$ = $2;
143 list:
144 CUBEFLOAT {
145 /* alloc enough space to be sure whole list will fit */
146 $$ = palloc(scanbuflen + 1);
147 strcpy($$, $1);
150 list COMMA CUBEFLOAT {
151 $$ = $1;
152 strcat($$, ",");
153 strcat($$, $3);
159 static int
160 delim_count(char *s, char delim)
162 int ndelim = 0;
164 while ((s = strchr(s, delim)) != NULL)
166 ndelim++;
167 s++;
169 return (ndelim);
172 static NDBOX *
173 write_box(unsigned int dim, char *str1, char *str2)
175 NDBOX * bp;
176 char * s;
177 int i;
178 int size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
180 bp = palloc0(size);
181 SET_VARSIZE(bp, size);
182 bp->dim = dim;
184 s = str1;
185 bp->x[i=0] = strtod(s, NULL);
186 while ((s = strchr(s, ',')) != NULL) {
187 s++; i++;
188 bp->x[i] = strtod(s, NULL);
191 s = str2;
192 bp->x[i=dim] = strtod(s, NULL);
193 while ((s = strchr(s, ',')) != NULL) {
194 s++; i++;
195 bp->x[i] = strtod(s, NULL);
198 return(bp);
202 static NDBOX *
203 write_point_as_box(char *str, int dim)
205 NDBOX * bp;
206 int i, size;
207 double x;
208 char * s = str;
210 size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
212 bp = palloc0(size);
213 SET_VARSIZE(bp, size);
214 bp->dim = dim;
216 i = 0;
217 x = strtod(s, NULL);
218 bp->x[0] = x;
219 bp->x[dim] = x;
220 while ((s = strchr(s, ',')) != NULL) {
221 s++; i++;
222 x = strtod(s, NULL);
223 bp->x[i] = x;
224 bp->x[i+dim] = x;
227 return(bp);
230 #include "cubescan.c"