📄 cclfind.c
字号:
return NULL; } lookahead = lookahead->next; if (lookahead->kind == CCL_TOK_COMMA) lookahead = lookahead->next; } } else { /* merge attributes from ALL fields - including inherited ones */ while (1) { struct ccl_rpn_node *node_sub; int found = 0; lookahead = look_start; for (i = 0; lookahead != la; i++) { ap[i] = ccl_qual_search (cclp, lookahead->name, lookahead->len, seq); if (ap[i]) found++; if (!ap[i] && seq > 0) ap[i] = ccl_qual_search (cclp, lookahead->name, lookahead->len, 0); if (!ap[i]) { cclp->look_token = lookahead; cclp->error_code = CCL_ERR_UNKNOWN_QUAL; xfree (ap); return NULL; } lookahead = lookahead->next; if (lookahead->kind == CCL_TOK_COMMA) lookahead = lookahead->next; } if (qa) { struct ccl_rpn_attr **qa0 = qa; while (*qa0) ap[i++] = *qa0++; } ap[i] = NULL; if (!found) break; cclp->look_token = lookahead; node_sub = qualifiers2(cclp, ap); if (!node_sub) { ccl_rpn_delete (node); break; } if (node) { struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); node_this->u.p[0] = node; node_this->u.p[1] = node_sub; node = node_this; } else node = node_sub; seq++; } } xfree (ap); return node;}/* * search_terms: Parse CCL search terms - including proximity. * cclp: CCL Parser * qa: Qualifier attributes already applied. * return: pointer to node(s); NULL on error. */static struct ccl_rpn_node *search_terms (CCL_parser cclp, struct ccl_rpn_attr **qa){ static int list[] = { CCL_TOK_TERM, CCL_TOK_COMMA,CCL_TOK_EQ, CCL_TOK_REL, CCL_TOK_SET, -1}; struct ccl_rpn_node *p1, *p2, *pn; p1 = search_term_x (cclp, qa, list, 1); if (!p1) return NULL; while (1) { if (KIND == CCL_TOK_PROX) { struct ccl_rpn_node *p_prox = 0; /* ! word order specified */ /* % word order not specified */ p_prox = mk_node(CCL_RPN_TERM); p_prox->u.t.term = (char *) xmalloc(cclp->look_token->len); memcpy(p_prox->u.t.term, cclp->look_token->name, cclp->look_token->len); p_prox->u.t.term[cclp->look_token->len] = 0; p_prox->u.t.attr_list = 0; ADVANCE; p2 = search_term_x (cclp, qa, list, 1); if (!p2) { ccl_rpn_delete (p1); return NULL; } pn = mk_node (CCL_RPN_PROX); pn->u.p[0] = p1; pn->u.p[1] = p2; pn->u.p[2] = p_prox; p1 = pn; } else if (is_term_ok(KIND, list)) { p2 = search_term_x (cclp, qa, list, 1); if (!p2) { ccl_rpn_delete (p1); return NULL; } pn = mk_node (CCL_RPN_PROX); pn->u.p[0] = p1; pn->u.p[1] = p2; pn->u.p[2] = 0; p1 = pn; } else break; } return p1;}/* * search_elements: Parse CCL search elements * cclp: CCL Parser * qa: Qualifier attributes already applied. * return: pointer to node(s); NULL on error. */static struct ccl_rpn_node *search_elements (CCL_parser cclp, struct ccl_rpn_attr **qa){ struct ccl_rpn_node *p1; struct ccl_token *lookahead; if (KIND == CCL_TOK_LP) { ADVANCE; p1 = find_spec (cclp, qa); if (!p1) return NULL; if (KIND != CCL_TOK_RP) { cclp->error_code = CCL_ERR_RP_EXPECTED; ccl_rpn_delete (p1); return NULL; } ADVANCE; return p1; } else if (KIND == CCL_TOK_SET) { ADVANCE; if (KIND == CCL_TOK_EQ) ADVANCE; if (KIND != CCL_TOK_TERM) { cclp->error_code = CCL_ERR_SETNAME_EXPECTED; return NULL; } p1 = mk_node (CCL_RPN_SET); p1->u.setname = copy_token_name (cclp->look_token); ADVANCE; return p1; } lookahead = cclp->look_token; while (lookahead->kind==CCL_TOK_TERM) { lookahead = lookahead->next; if (lookahead->kind == CCL_TOK_REL || lookahead->kind == CCL_TOK_EQ) return qualifiers1 (cclp, lookahead, qa); if (lookahead->kind != CCL_TOK_COMMA) break; lookahead = lookahead->next; } if (qa) return search_terms (cclp, qa); else { struct ccl_rpn_attr *qa[2]; struct ccl_rpn_node *node = 0; int seq; lookahead = cclp->look_token; qa[1] = 0; for(seq = 0; ;seq++) { struct ccl_rpn_node *node_sub; qa[0] = ccl_qual_search(cclp, "term", 4, seq); if (!qa[0]) break; cclp->look_token = lookahead; node_sub = search_terms (cclp, qa); if (!node_sub) { ccl_rpn_delete (node); return 0; } if (node) { struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR); node_this->u.p[0] = node; node_this->u.p[1] = node_sub; node_this->u.p[2] = 0; node = node_this; } else node = node_sub; } if (!node) node = search_terms (cclp, 0); return node; }}/* * find_spec: Parse CCL find specification * cclp: CCL Parser * qa: Qualifier attributes already applied. * return: pointer to node(s); NULL on error. */static struct ccl_rpn_node *find_spec (CCL_parser cclp, struct ccl_rpn_attr **qa){ struct ccl_rpn_node *p1, *p2, *pn; if (!(p1 = search_elements (cclp, qa))) return NULL; while (1) { switch (KIND) { case CCL_TOK_AND: ADVANCE; p2 = search_elements (cclp, qa); if (!p2) { ccl_rpn_delete (p1); return NULL; } pn = mk_node (CCL_RPN_AND); pn->u.p[0] = p1; pn->u.p[1] = p2; pn->u.p[2] = 0; p1 = pn; continue; case CCL_TOK_OR: ADVANCE; p2 = search_elements (cclp, qa); if (!p2) { ccl_rpn_delete (p1); return NULL; } pn = mk_node (CCL_RPN_OR); pn->u.p[0] = p1; pn->u.p[1] = p2; pn->u.p[2] = 0; p1 = pn; continue; case CCL_TOK_NOT: ADVANCE; p2 = search_elements (cclp, qa); if (!p2) { ccl_rpn_delete (p1); return NULL; } pn = mk_node (CCL_RPN_NOT); pn->u.p[0] = p1; pn->u.p[1] = p2; pn->u.p[2] = 0; p1 = pn; continue; } break; } return p1;}struct ccl_rpn_node *ccl_parser_find (CCL_parser cclp, struct ccl_token *list){ struct ccl_rpn_node *p; cclp->look_token = list; p = find_spec (cclp, NULL); if (p && KIND != CCL_TOK_EOL) { if (KIND == CCL_TOK_RP) cclp->error_code = CCL_ERR_BAD_RP; else cclp->error_code = CCL_ERR_OP_EXPECTED; ccl_rpn_delete (p); p = NULL; } cclp->error_pos = cclp->look_token->name; if (p) cclp->error_code = CCL_ERR_OK; else cclp->error_code = cclp->error_code; return p;}/* * ccl_find: Parse CCL find - token representation * bibset: Bibset to be used for the parsing * list: List of tokens * error: Pointer to integer. Holds error no. on completion. * pos: Pointer to char position. Holds approximate error position. * return: RPN tree on successful completion; NULL otherwise. */struct ccl_rpn_node *ccl_find (CCL_bibset bibset, struct ccl_token *list, int *error, const char **pos){ struct ccl_rpn_node *p; CCL_parser cclp = ccl_parser_create (); cclp->bibset = bibset; p = ccl_parser_find (cclp, list); *error = cclp->error_code; *pos = cclp->error_pos; ccl_parser_destroy (cclp); return p;}/* * ccl_find_str: Parse CCL find - string representation * bibset: Bibset to be used for the parsing * str: String to be parsed * error: Pointer to integer. Holds error no. on completion. * pos: Pointer to char position. Holds approximate error position. * return: RPN tree on successful completion; NULL otherwise. */struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str, int *error, int *pos){ CCL_parser cclp = ccl_parser_create (); struct ccl_token *list; struct ccl_rpn_node *p; cclp->bibset = bibset; list = ccl_parser_tokenize (cclp, str); p = ccl_parser_find (cclp, list); *error = cclp->error_code; if (*error) *pos = cclp->error_pos - str; ccl_parser_destroy (cclp); ccl_token_del (list); return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -