1 /* CCL find (to rpn conversion)
5 * Revision 1.3 1995-09-29 17:11:59 quinn
8 * Revision 1.2 1995/09/27 15:02:44 quinn
9 * Modified function heads & prototypes.
11 * Revision 1.1 1995/04/10 10:28:19 quinn
14 * Revision 1.12 1995/03/20 15:27:43 adam
17 * Revision 1.11 1995/02/23 08:31:59 adam
20 * Revision 1.9 1995/02/16 13:20:06 adam
23 * Revision 1.8 1995/02/14 19:59:42 adam
24 * Removed a syntax error.
26 * Revision 1.7 1995/02/14 19:55:10 adam
27 * Header files ccl.h/cclp.h are gone! They have been merged an
28 * moved to ../include/ccl.h.
29 * Node kind(s) in ccl_rpn_node have changed names.
31 * Revision 1.6 1995/02/14 16:20:55 adam
32 * Qualifiers are read from a file now.
34 * Revision 1.5 1995/02/14 14:12:41 adam
35 * Ranges for ordered qualfiers implemented (e.g. pd=1980-1990).
37 * Revision 1.4 1995/02/14 13:16:29 adam
38 * Left and/or right truncation implemented.
40 * Revision 1.3 1995/02/14 10:25:56 adam
41 * The constructions 'qualifier rel term ...' implemented.
43 * Revision 1.2 1995/02/13 15:15:07 adam
44 * Added handling of qualifiers. Not finished yet.
46 * Revision 1.1 1995/02/13 12:35:20 adam
47 * First version of CCL. Qualifiers aren't handled yet.
58 static struct ccl_token *look_token;
60 static CCL_bibset bibset;
62 #define KIND (look_token->kind)
63 #define ADVANCE look_token = look_token->next
64 #define ADVX(x) x=(x)->next
66 static struct ccl_rpn_attr *qual_val (struct ccl_rpn_attr *list, int type)
70 if (list->type == type)
77 static int qual_val_type (struct ccl_rpn_attr *list, int type, int value)
81 if (list->type == type && list->value == value)
88 static void strxcat (char *n, const char *src, int len)
97 static char *copy_token_name (struct ccl_token *tp)
99 char *str = malloc (tp->len + 1);
101 memcpy (str, tp->name, tp->len);
106 static struct ccl_rpn_node *mk_node (enum rpn_node_kind kind)
108 struct ccl_rpn_node *p;
109 p = malloc (sizeof(*p));
115 void ccl_rpn_delete (struct ccl_rpn_node *rpn)
117 struct ccl_rpn_attr *attr, *attr1;
125 ccl_rpn_delete (rpn->u.p[0]);
126 ccl_rpn_delete (rpn->u.p[1]);
129 free (rpn->u.t.term);
130 for (attr = rpn->u.t.attr_list; attr; attr = attr1)
137 free (rpn->u.setname);
140 ccl_rpn_delete (rpn->u.p[0]);
141 ccl_rpn_delete (rpn->u.p[1]);
147 static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa);
148 static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa);
150 static void add_attr (struct ccl_rpn_node *p, int type, int value)
152 struct ccl_rpn_attr *n;
154 n = malloc (sizeof(*n));
158 n->next = p->u.t.attr_list;
159 p->u.t.attr_list = n;
162 static struct ccl_rpn_node *search_term (struct ccl_rpn_attr **qa)
164 struct ccl_rpn_node *p;
165 struct ccl_rpn_attr *attr;
166 struct ccl_token *lookahead = look_token;
173 if (KIND != CCL_TOK_TERM)
175 ccl_error = CCL_ERR_TERM_EXPECTED;
178 for (no = 0; lookahead->kind == CCL_TOK_TERM; no++)
180 for (i = 0; i<lookahead->len; i++)
181 if (lookahead->name[i] == '?')
183 if (no == 0 && i == 0 && lookahead->len >= 1)
185 else if (lookahead->next->kind != CCL_TOK_TERM &&
186 i == lookahead->len-1 && i >= 1)
191 len += 1+lookahead->len;
192 lookahead = lookahead->next;
194 p = mk_node (CCL_RPN_TERM);
195 p->u.t.term = malloc (len);
196 assert (p->u.t.term);
197 p->u.t.attr_list = NULL;
198 p->u.t.term[0] = '\0';
199 for (i = 0; i<no; i++)
201 const char *src_str = look_token->name;
202 int src_len = look_token->len;
204 if (i == 0 && left_trunc)
209 else if (i == no-1 && right_trunc)
212 strcat (p->u.t.term, " ");
213 strxcat (p->u.t.term, src_str, src_len);
219 for (i=0; qa[i]; i++)
221 struct ccl_rpn_attr *attr;
223 for (attr = qa[i]; attr; attr = attr->next)
225 add_attr (p, attr->type, attr->value);
230 attr = ccl_qual_search (bibset, "term", 4);
231 if (attr && qual_val_type (attr, CCL_BIB1_STR, CCL_BIB1_STR_WP))
234 add_attr (p, CCL_BIB1_STR, 2);
236 add_attr (p, CCL_BIB1_STR, 1);
238 if (left_trunc && right_trunc)
240 if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH))
242 ccl_error = CCL_ERR_TRUNC_NOT_BOTH;
248 add_attr (p, CCL_BIB1_TRU, 3);
250 else if (right_trunc)
252 if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT))
254 ccl_error = CCL_ERR_TRUNC_NOT_RIGHT;
260 add_attr (p, CCL_BIB1_TRU, 1);
264 if (attr && !qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT))
266 ccl_error = CCL_ERR_TRUNC_NOT_LEFT;
272 add_attr (p, CCL_BIB1_TRU, 2);
276 if (attr && qual_val_type (attr, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE))
277 add_attr (p, CCL_BIB1_TRU, 100);
282 static struct ccl_rpn_node *qualifiers (struct ccl_token *la,
283 struct ccl_rpn_attr **qa)
285 struct ccl_token *lookahead = look_token;
286 struct ccl_rpn_attr **ap;
289 struct ccl_rpn_attr *attr;
293 ccl_error = CCL_ERR_DOUBLE_QUAL;
296 for (lookahead = look_token; lookahead != la; lookahead=lookahead->next)
298 ap = malloc (no * sizeof(*ap));
300 for (i=0; look_token != la; i++)
302 ap[i] = ccl_qual_search (bibset, look_token->name, look_token->len);
305 ccl_error = CCL_ERR_UNKNOWN_QUAL;
310 if (KIND == CCL_TOK_COMMA)
314 if (! (attr = qual_val (ap[0], CCL_BIB1_REL)) ||
315 attr->value != CCL_BIB1_REL_ORDER)
317 /* unordered relation */
318 struct ccl_rpn_node *p;
319 if (KIND != CCL_TOK_EQ)
321 ccl_error = CCL_ERR_EQ_EXPECTED;
326 if (KIND == CCL_TOK_LP)
329 if (!(p = find_spec (ap)))
334 if (KIND != CCL_TOK_RP)
336 ccl_error = CCL_ERR_RP_EXPECTED;
344 p = search_terms (ap);
349 if (look_token->len == 1)
351 if (look_token->name[0] == '<')
353 else if (look_token->name[0] == '=')
355 else if (look_token->name[0] == '>')
358 else if (look_token->len == 2)
360 if (!memcmp (look_token->name, "<=", 2))
362 else if (!memcmp (look_token->name, ">=", 2))
364 else if (!memcmp (look_token->name, "<>", 2))
368 ccl_error = CCL_ERR_BAD_RELATION;
371 struct ccl_rpn_node *p;
373 ADVANCE; /* skip relation */
374 if (KIND == CCL_TOK_TERM)
376 struct ccl_rpn_node *p1;
377 p1 = search_term (ap);
378 if (KIND == CCL_TOK_MINUS)
380 ADVANCE; /* skip '-' */
381 if (KIND == CCL_TOK_TERM) /* = term - term ? */
383 struct ccl_rpn_node *p2;
385 p2 = search_term (ap);
386 p = mk_node (CCL_RPN_AND);
388 add_attr (p1, CCL_BIB1_REL, 4);
390 add_attr (p2, CCL_BIB1_REL, 2);
396 add_attr (p1, CCL_BIB1_REL, 4);
403 add_attr (p1, CCL_BIB1_REL, rel);
408 else if (KIND == CCL_TOK_MINUS) /* = - term ? */
411 p = search_term (ap);
412 add_attr (p, CCL_BIB1_REL, 2);
416 ccl_error = CCL_ERR_TERM_EXPECTED;
422 static struct ccl_rpn_node *search_terms (struct ccl_rpn_attr **qa)
424 struct ccl_rpn_node *p1, *p2, *pn;
425 p1 = search_term (qa);
430 if (KIND == CCL_TOK_PROX)
433 p2 = search_term (qa);
439 pn = mk_node (CCL_RPN_PROX);
444 else if (KIND == CCL_TOK_TERM)
446 p2 = search_term (qa);
452 pn = mk_node (CCL_RPN_PROX);
463 static struct ccl_rpn_node *search_elements (struct ccl_rpn_attr **qa)
465 struct ccl_rpn_node *p1;
466 struct ccl_token *lookahead;
467 if (KIND == CCL_TOK_LP)
473 if (KIND != CCL_TOK_RP)
475 ccl_error = CCL_ERR_RP_EXPECTED;
482 else if (KIND == CCL_TOK_SET)
485 if (KIND == CCL_TOK_EQ)
487 if (KIND != CCL_TOK_TERM)
489 ccl_error = CCL_ERR_SETNAME_EXPECTED;
492 p1 = mk_node (CCL_RPN_SET);
493 p1->u.setname = copy_token_name (look_token);
497 lookahead = look_token;
499 while (lookahead->kind==CCL_TOK_TERM || lookahead->kind==CCL_TOK_COMMA)
500 lookahead = lookahead->next;
501 if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ)
502 return qualifiers (lookahead, qa);
503 return search_terms (qa);
506 static struct ccl_rpn_node *find_spec (struct ccl_rpn_attr **qa)
508 struct ccl_rpn_node *p1, *p2, *pn;
509 if (!(p1 = search_elements (qa)))
517 p2 = search_elements (qa);
523 pn = mk_node (CCL_RPN_AND);
530 p2 = search_elements (qa);
536 pn = mk_node (CCL_RPN_OR);
543 p2 = search_elements (qa);
549 pn = mk_node (CCL_RPN_NOT);
560 struct ccl_rpn_node *ccl_find (CCL_bibset abibset, struct ccl_token *list,
561 int *error, const char **pos)
563 struct ccl_rpn_node *p;
567 p = find_spec (NULL);
568 if (p && KIND != CCL_TOK_EOL)
570 if (KIND == CCL_TOK_RP)
571 ccl_error = CCL_ERR_BAD_RP;
573 ccl_error = CCL_ERR_OP_EXPECTED;
577 *pos = look_token->name;
585 struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
586 int *error, int *pos)
588 struct ccl_token *list;
589 struct ccl_rpn_node *rpn;
590 const char *char_pos;
592 list = ccl_tokenize (str);
593 rpn = ccl_find (bibset, list, error, &char_pos);
595 *pos = char_pos - str;