struct pnode * PP_mknnode(double number) { struct pnode *p; struct dvec *v; /* We don't use printnum because it screws up PP_mkfnode above. We have * to be careful to deal properly with node numbers that are quite * large... */ v = dvec_alloc(number < MAXPOSINT ? tprintf("%d", (int) number) : tprintf("%G", number), SV_NOTYPE, VF_REAL, 1, NULL); v->v_realdata[0] = number; vec_new(v); p = alloc_pnode(); p->pn_value = v; return (p); }
struct pnode * PP_mkbnode(int opnum, struct pnode *arg1, struct pnode *arg2) { struct op *o; struct pnode *p; for (o = &ops[0]; o->op_name; o++) if (o->op_num == opnum) break; if (!o->op_name) fprintf(cp_err, "PP_mkbnode: Internal Error: no such op num %d\n", opnum); p = alloc_pnode(); p->pn_op = o; p->pn_left = arg1; if (p->pn_left) p->pn_left->pn_use++; p->pn_right = arg2; if (p->pn_right) p->pn_right->pn_use++; return (p); }
struct pnode * PP_mkfnode(const char *func, struct pnode *arg) { struct func *f; struct pnode *p, *q; struct dvec *d; char buf[BSIZE_SP]; (void) strcpy(buf, func); strtolower(buf); /* Make sure the case is ok. */ for (f = &ft_funcs[0]; f->fu_name; f++) if (eq(f->fu_name, buf)) break; if (f->fu_name == NULL) { /* Give the user-defined functions a try. */ q = ft_substdef(func, arg); if (q) return (q); } if ((f->fu_name == NULL) && arg->pn_value) { /* Kludge -- maybe it is really a variable name. */ (void) sprintf(buf, "%s(%s)", func, arg->pn_value->v_name); free_pnode(arg); d = vec_get(buf); if (d == NULL) { /* Well, too bad. */ fprintf(cp_err, "Error: no such function as %s.\n", func); return (NULL); } /* (void) strcpy(buf, d->v_name); XXX */ return (PP_mksnode(buf)); } else if (f->fu_name == NULL) { fprintf(cp_err, "Error: no function as %s with that arity.\n", func); free_pnode(arg); return (NULL); } if (!f->fu_func && arg->pn_op && arg->pn_op->op_num == PT_OP_COMMA) { p = PP_mkbnode(PT_OP_MINUS, PP_mkfnode(func, arg->pn_left), PP_mkfnode(func, arg->pn_right)); free_pnode(arg); return p; } p = alloc_pnode(); p->pn_func = f; p->pn_left = arg; if (p->pn_left) p->pn_left->pn_use++; return (p); }
struct pnode * PP_mksnode(const char *string) { struct dvec *v, *nv, *vs, *newv = NULL, *end = NULL; struct pnode *p; p = alloc_pnode(); v = vec_get(string); if (v == NULL) { nv = dvec_alloc(copy(string), SV_NOTYPE, 0, 0, NULL); p->pn_value = nv; return (p); } /* It's not obvious that we should be doing this, but... */ for (vs = v; vs; vs = vs->v_link2) { nv = vec_copy(vs); vec_new(nv); if (end) end->v_link2 = nv; else newv = end = nv; end = nv; } p->pn_value = newv; /* va: tfree v in case of @xxx[par], because vec_get created a new vec and nobody will free it elsewhere */ /*if (v && v->v_name && *v->v_name == '@' && isreal(v) && v->v_realdata) { vec_free(v); } */ /* The two lines above have been commented out to prevent deletion of @xxx[par] after execution of only a single command like plot @xxx[par] or write. We need to monitor if this will lead to excessive memory usage. h_vogt 090221 */ return (p); }
struct pnode * PP_mkunode(int op, struct pnode *arg) { struct pnode *p; struct op *o; p = alloc_pnode(); for (o = uops; o->op_name; o++) if (o->op_num == op) break; if (!o->op_name) fprintf(cp_err, "PP_mkunode: Internal Error: no such op num %d\n", op); p->pn_op = o; p->pn_left = arg; if (p->pn_left) p->pn_left->pn_use++; return (p); }
/* * Create phone-level HMM for a single word and append to partial sentence HMM. * Replicate HMM nodes as needed to account for all possible left and right context * phones. * Return a list of the final HMM nodes for the single word appended. */ static pnode_t *append_word (s3wid_t w, pnode_t *prev_end, s3cipid_t *pred_ci, s3cipid_t *succ_ci) { int32 i, M, N, m, n, pronlen, pron; pnode_t *node, *nodelist, *p; plink_t *l, *new_end; for (i = 0; IS_CIPID(pred_ci[i]); i++); M = (i > 0) ? i : 1; /* #predecessor CI phones */ for (i = 0; IS_CIPID(succ_ci[i]); i++); N = (i > 0) ? i : 1; /* #successor CI phones */ if ((pronlen = dict->word[w].pronlen) == 1) { /* Single phone case; replicated MxN times for all possible contexts */ nodelist = NULL; for (m = 0; m < M; m++) { for (n = 0; n < N; n++) { node = alloc_pnode (w, 0, dict->word[w].ciphone[0], pred_ci[m], succ_ci[n], WORD_POSN_SINGLE); /* Link to all predecessor nodes matching context requirements */ for (p = prev_end; p; p = p->next) { if ((p->ci == node->lc) && ((NOT_CIPID(p->rc)) || (p->rc == node->ci))) { link_pnodes (p, node); } } node->next = nodelist; nodelist = node; } } return nodelist; } /* Multi-phone case. First phone, replicated M times */ nodelist = NULL; for (m = 0; m < M; m++) { node = alloc_pnode (w, 0, dict->word[w].ciphone[0], pred_ci[m], dict->word[w].ciphone[1], WORD_POSN_BEGIN); /* Link to predecessor node(s) matching context requirements */ for (p = prev_end; p; p = p->next) { if ((p->ci == node->lc) && ((NOT_CIPID(p->rc)) || (p->rc == node->ci))) { link_pnodes (p, node); } } node->next = nodelist; nodelist = node; } /* Intermediate phones */ for (pron = 1; pron < pronlen-1; pron++) { node = alloc_pnode (w, pron, dict->word[w].ciphone[pron], dict->word[w].ciphone[pron-1], dict->word[w].ciphone[pron+1], WORD_POSN_INTERNAL); for (p = nodelist; p; p = p->next) link_pnodes (p, node); nodelist = node; } /* Final phone, replicated N times */ prev_end = nodelist; nodelist = NULL; for (n = 0; n < N; n++) { node = alloc_pnode (w, pron, dict->word[w].ciphone[pron], dict->word[w].ciphone[pron-1], succ_ci[n], WORD_POSN_END); for (p = prev_end; p; p = p->next) link_pnodes (p, node); node->next = nodelist; nodelist = node; } return nodelist; }