0bcc9cbac5570b88729eb5156407705aeb369835
[yaz-moved-to-github.git] / cql / cql.y
1 /* $Id: cql.y,v 1.2 2003-01-11 03:18:53 adam Exp $
2    Copyright (C) 2002-2003
3    Index Data Aps
4
5 This file is part of the YAZ toolkit.
6
7 See the file LICENSE.
8
9  bison parser for CQL grammar.
10 */
11 %{
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <yaz/cql.h>
17     
18     typedef struct {
19         struct cql_node *rel;
20         struct cql_node *cql;
21         char buf[80];
22         size_t len;
23         size_t max;
24     } token;        
25
26     struct cql_parser {
27         int (*getbyte)(void *client_data);
28         void (*ungetbyte)(int b, void *client_data);
29         void *client_data;
30         int last_error;
31         int last_pos;
32         struct cql_node *top;
33     };
34
35 #define YYSTYPE token
36     
37 #define YYPARSE_PARAM parm
38 #define YYLEX_PARAM parm
39     
40     int yylex(YYSTYPE *lval, void *vp);
41     int yyerror(char *s);
42 %}
43
44 %pure_parser
45 %token TERM AND OR NOT PROX EXACT ALL ANY GE LE NE SCR
46 %expect 8
47
48 %%
49
50 top: { 
51     $$.rel = cql_node_mk_sc("srw.serverChoice", "scr", 0);
52     ((CQL_parser) parm)->top = 0;
53 } cqlQuery1 {
54     cql_node_destroy($$.rel);
55     ((CQL_parser) parm)->top = $2.cql; 
56 }
57 ;
58
59 cqlQuery1: cqlQuery
60 | cqlQuery error {
61     cql_node_destroy($1.cql);
62     $$.cql = 0;
63 }
64 ;
65
66 cqlQuery: 
67   searchClause
68 |
69   cqlQuery boolean { 
70       $$.rel = $0.rel; 
71   } searchClause {
72       struct cql_node *cn = cql_node_mk_boolean($2.buf);
73       
74       cn->u.bool.modifiers = $2.rel;
75       cn->u.bool.left = $1.cql;
76       cn->u.bool.right = $4.cql;
77
78       $$.cql = cn;
79   }
80 ;
81
82 searchClause: 
83   '(' { 
84       $$.rel = $0.rel;
85       
86   } cqlQuery ')' {
87       $$.cql = $3.cql;
88   }
89 |
90   searchTerm {
91       struct cql_node *st = cql_node_dup ($0.rel);
92       st->u.st.term = strdup($1.buf);
93       $$.cql = st;
94   }
95
96   index relation {
97       $$.rel = $2.rel;
98       $$.rel->u.st.index = strdup($1.buf);
99   } searchClause {
100       $$.cql = $4.cql;
101       cql_node_destroy($2.rel);
102   }
103 | '>' searchTerm '=' searchTerm {
104       $$.rel = $0.rel;
105   } cqlQuery {
106     $$.cql = cql_node_prefix($6.cql, $2.buf, $4.buf);
107   }
108 | '>' searchTerm {
109       $$.rel = $0.rel;
110   } cqlQuery {
111     $$.cql = cql_node_prefix($4.cql, 0, $2.buf);
112    }
113 ;
114
115 boolean: 
116   AND | OR | NOT | PROX proxqualifiers {
117       $$ = $1;
118       $$.rel = $2.rel;
119   }
120   ;
121
122 proxqualifiers: 
123   Prelation { 
124       $$.rel = cql_node_mk_proxargs ($1.buf, 0, 0, 0);
125   }
126 |
127   PrelationO Pdistance {
128       $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, 0, 0);
129   }
130 |
131   PrelationO PdistanceO Punit {
132       $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, $3.buf, 0);
133   }
134 |
135   PrelationO PdistanceO PunitO Pordering {
136       $$.rel = cql_node_mk_proxargs ($1.buf, $2.buf, $3.buf, $4.buf);
137   }
138 |
139 { $$.rel = 0; }
140 ;
141
142 Punit: '/' searchTerm { 
143       $$ = $2;
144    }
145 ;
146
147 PunitO: '/' searchTerm {
148       $$ = $2;
149    } 
150
151 '/' { $$.buf[0] = 0; }
152 ;
153 Prelation: '/' baseRelation {
154     $$ = $2;
155 }
156 ;
157 PrelationO: '/' baseRelation {
158     $$ = $2;
159 }
160 | '/' { $$.buf[0] = 0; }
161 ;
162 Pdistance: '/' searchTerm { 
163     $$ = $2;
164 }
165 ;
166
167 PdistanceO: '/' searchTerm {
168     $$ = $2;
169 }
170 | '/' { $$.buf[0] = 0; }
171 ;
172 Pordering: '/' searchTerm { 
173     $$ = $2;
174 }
175 ;
176
177 relation: baseRelation modifiers {
178     struct cql_node *st = cql_node_mk_sc(/* index */ 0, 
179                                          /* relation */ $1.buf, 
180                                          /* term */ 0);
181
182     st->u.st.modifiers = $2.cql;
183     $$.rel = st;
184 }
185 ;
186
187 modifiers: '/' searchTerm modifiers
188
189     struct cql_node *mod = cql_node_mk_mod(0, $2.buf);
190
191     mod->u.mod.next = $3.cql;
192     $$.cql = mod;
193 }
194 |  
195
196     $$.cql = 0;
197 }
198 ;
199
200 baseRelation: 
201   '=' 
202 | '>' 
203 | '<'
204 | GE
205 | LE
206 | NE
207 | EXACT 
208 | ALL
209 | ANY
210 | SCR
211 ;
212
213 index: 
214   searchTerm;
215
216 searchTerm:
217   TERM
218 | AND
219 | OR
220 | NOT
221 | EXACT
222 | ALL
223 | ANY
224 | PROX
225 ;
226
227 %%
228
229 int yyerror(char *s)
230 {
231     return 0;
232 }
233
234 #include "lexer.c"
235
236
237 int cql_parser_stream(CQL_parser cp,
238                       int (*getbyte)(void *client_data),
239                       void (*ungetbyte)(int b, void *client_data),
240                       void *client_data)
241 {
242     cp->getbyte = getbyte;
243     cp->ungetbyte = ungetbyte;
244     cp->client_data = client_data;
245     cql_parse(cp);
246     if (cp->top)
247         return 0;
248     return -1;
249 }
250
251 CQL_parser cql_parser_create(void)
252 {
253     CQL_parser cp = malloc (sizeof(*cp));
254
255     return cp;
256 }
257
258 void cql_parser_destroy(CQL_parser cp)
259 {
260     cql_node_destroy(cp->top);
261     free (cp);
262 }
263
264 struct cql_node *cql_parser_result(CQL_parser cp)
265 {
266     return cp->top;
267 }