Mercurial > freewnn
diff Wnn/jserver/jikouho_d.c @ 0:bbc77ca4def5
initial import
author | Yoshiki Yazawa <yaz@cc.rim.or.jp> |
---|---|
date | Thu, 13 Dec 2007 04:30:14 +0900 |
parents | |
children | b605a0e60f5b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wnn/jserver/jikouho_d.c Thu Dec 13 04:30:14 2007 +0900 @@ -0,0 +1,853 @@ +/* + * $Id: jikouho_d.c,v 1.6 2002/05/12 22:51:16 hiroo Exp $ + */ + +/* + * FreeWnn is a network-extensible Kana-to-Kanji conversion system. + * This file is part of FreeWnn. + * + * Copyright Kyoto University Research Institute for Mathematical Sciences + * 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999 + * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992 + * Copyright FreeWnn Project 1999, 2000, 2002 + * + * Maintainer: FreeWnn Project <freewnn@tomo.gr.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/************************************************ + * 大文節次候補取りだし * + ************************************************/ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> +#include <ctype.h> +#if STDC_HEADERS +# include <stdlib.h> +#else +# if HAVE_MALLOC_H +# include <malloc.h> +# endif +#endif /* STDC_HEADERS */ + +#include "commonhd.h" +#include "de_header.h" +#include "jdata.h" +#include "fzk.h" +#include "kaiseki.h" + +#ifdef CONVERT_from_TOP +static void sbn_set (), sons_set (); +#endif /* CONVERT_from_TOP */ + +static void dsd_hyouka (), cnt_sbn (), cnt_dbn (); +static int cmp_dsd_dbn (), jkt_dbn (), jkt_sbjunjo (), set_jkt_dai (), zen_sbn (), cnt_par (), cnt_son (); +static struct JKT_SBN *jkt_que_reorder (); + +static int yomi_sno_tmp; + +/* + * jkt_get_dai : 次候補 all 取りだし (大文節) + */ +int +#ifdef NO_FZK +jkt_get_dai (yomi_sno, yomi_eno, beginvect, endvect, endvect1, nmax, dsd_dbn) +#else +jkt_get_dai (yomi_sno, yomi_eno, beginvect, fzkchar, endvect, endvect1, nmax, dsd_dbn) +#endif /* NO_FZK */ + int yomi_sno; + int yomi_eno; + int beginvect; /* 前端ベクタ(-1:文節先頭、-2:なんでも)品詞No. */ +#ifndef NO_FZK + w_char *fzkchar; +#endif /* NO_FZK */ + int endvect; /* 終端ベクタ */ + int endvect1; /* 終端ベクタ */ + int nmax; /* 1大文節中の最大小文節数 */ + struct DSD_DBN **dsd_dbn; +{ + register int i; + register int cnt; + struct JKT_DBN *rjkt_dbn = 0; + register struct DSD_DBN *dbn; + int divid; + + if (c_env->fzk_fid == -1) + { + wnn_errorno = WNN_FZK_FILE_NO_LOAD; + return (-1); + } + ft = (struct FT *) files[c_env->fzk_fid].area; + if ((cnt = jkt_dbn (yomi_sno, yomi_eno, beginvect, +#ifndef NO_FZK + fzkchar, +#endif /* NO_FZK */ + endvect, endvect1, nmax, &rjkt_dbn)) < 0) + { + init_work_areas (); + return (-1); + } + if ((cnt = dbn_set (dsd_dbn, rjkt_dbn)) < 0) + { + init_work_areas (); + return (-1); + } + for (dbn = *dsd_dbn, i = cnt; i > 0; i--, dbn++) + { + dsd_hyouka (dbn); + if ((divid = get_jkt_status (dbn->sbn->kangovect, beginvect, +#ifndef NO_FZK + fzkchar, +#endif /* NO_FZK */ + &(dbn->sbn->status))) != 0) + dbn->v_jc = DIVID_HYOUKA (dbn->v_jc, divid); + } + /* SORT */ + qsort ((char *) *dsd_dbn, cnt, sizeof (struct DSD_DBN), cmp_dsd_dbn); + return (cnt); +} + +static int +cmp_dsd_dbn (dbn1, dbn2) + struct DSD_DBN *dbn1; + struct DSD_DBN *dbn2; +{ + return (dbn2->v_jc - dbn1->v_jc); +} + +static void +dsd_hyouka (dbn) + struct DSD_DBN *dbn; +{ + struct DSD_SBN *sbn; + int len; /* 大文節長 */ + int son_v = 0; + register int j_c; + register struct DSD_SBN *s_p; + int i; + + sbn = dbn->sbn; + j_c = sbn->bun_jc; + len = j_c - dbn->bun_m + 1; + + for (i = 0, s_p = sbn; i < dbn->sbncnt; s_p++, i++) + { + son_v += s_p->v_jc; + } + + dbn->v_jc = hyoka_dbn (son_v, dbn->sbncnt, len); +} + +/*******************/ + +static int +#ifdef NO_FZK +jkt_dbn (yomi_sno, yomi_eno, beginvect, endvect, endvect1, nmax, rjkt_dbn) +#else +jkt_dbn (yomi_sno, yomi_eno, beginvect, fzkchar, endvect, endvect1, nmax, rjkt_dbn) +#endif /* NO_FZK */ + int yomi_sno; + int yomi_eno; + int beginvect; /* 前端ベクタ(-1:文節先頭、-2:なんでも)品詞No. */ +#ifndef NO_FZK + w_char *fzkchar; +#endif /* NO_FZK */ + int endvect; /* 終端ベクタ */ + int endvect1; /* 終端ベクタ */ + register int nmax; /* 1大文節中の最大小文節数 */ + struct JKT_DBN **rjkt_dbn; /* 次候補解析結果 */ +{ + register struct JKT_SBN **sb_que_head; /* 小文節解析結果 */ + int tmp; /* 次候補ベクター数 */ + struct JKT_SBN *db_tmp; + register struct JKT_SBN *sb_one; + struct JKT_SBN *sbn_tmp; + register struct JKT_SBN **sb_que_newcomer; + struct JKT_DBN *jktdbn = 0; + int dbncnt = 0; +#ifndef NO_KANA + int gijiflag = 0; /* 疑似文節を作ったか:最初の小文節のみ */ +#endif /* NO_KANA */ + + yomi_sno_tmp = yomi_sno; + + sb_que_head = &db_tmp; + *sb_que_head = NULL; + + if ((tmp = zen_sbn (yomi_sno, yomi_eno, endvect, endvect1, sb_que_head, 1, (struct JKT_SBN *) 0 +#ifndef NO_KANA + , &gijiflag +#endif /* NO_KANA */ + )) <= 0) + return (tmp); + + while (*sb_que_head != NULL) + { + sb_one = *sb_que_head; + *sb_que_head = sb_one->lnk_br; + if (nmax > sb_one->kbcnt && yomi_eno > sb_one->j_c + 1) + { + sb_que_newcomer = &sbn_tmp; + *sb_que_newcomer = NULL; + tmp = zen_sbn (sb_one->j_c + 1, yomi_eno, sb_one->kangovect, WNN_VECT_NO, sb_que_newcomer, sb_one->kbcnt + 1, sb_one +#ifndef NO_KANA + , 0 +#endif /* NO_KANA */ + ); + if (tmp < 0) + { + return (-1); /* ERROR */ + } + else if (tmp > 0) + { + sb_one->reference += tmp; + if (*sb_que_head != 0) + *sb_que_head = jkt_que_reorder (*sb_que_head, *sb_que_newcomer); + else + *sb_que_head = *sb_que_newcomer; + } + else + { + freejktsbn (sb_one); + } + } + else if (yomi_eno == sb_one->j_c + 1) + { + if (set_jkt_dai (rjkt_dbn, &jktdbn, sb_one) < 0) + return (-1); + dbncnt++; + } + } +#ifndef NO_KANA +/* ひらがな候補 */ + if (gijiflag == 0) + { + if ((sb_one = get_hira_kouho (&db_tmp, yomi_sno, yomi_eno)) < (struct JKT_SBN *) 0) + return (-1); + + if (sb_one > (struct JKT_SBN *) 0) + { + sb_one->parent = 0; + sb_one->bend_m = yomi_sno; + sb_one->kbcnt = 1; + if (set_jkt_dai (rjkt_dbn, &jktdbn, sb_one) < 0) + return (-1); + dbncnt++; + } + } +#endif /* NO_KANA */ + + return (dbncnt); +} + +/* 前(beginvect,fzkchar)と接続できるか調べ、 + 接続できるとき 1 + 大文節の先頭の時 0 + 接続できないとき -1 + を返す + get_status 参照 +*/ + +int +#ifdef NO_FZK +get_jkt_status (kangovect, beginvect, status) +#else +get_jkt_status (kangovect, beginvect, fzkchar, status) +#endif /* NO_FZK */ + int kangovect; + int beginvect; +#ifndef NO_FZK + w_char *fzkchar; +#endif /* NO_FZK */ + short *status; +{ + extern int _status; + _status = 0; + return (get_status (kangovect, beginvect, +#ifndef NO_FZK + fzkchar, +#endif /* NO_FZK */ + status)); +} + +/* +int +get_dsd_status(kangovect, beginvect, fzkchar, status) +int kangovect; +int beginvect; +w_char *fzkchar; +int *status; +{ + if (zentan_able(kangovect, beginvect, fzkchar) == YES) { + if (beginvect == WNN_ALL_HINSI) { + if (kan_ckvt(sentou_no, kangovect) == WNN_CONNECT_BK) { + *status = WNN_SENTOU; + } else { + *status = WNN_NOT_CONNECT; + return (-1); + } + } else if (beginvect == WNN_BUN_SENTOU) { + *status = WNN_SENTOU; + } else { + if ((fzkchar == NULL || *fzkchar == NULL) && beginvect == sentou_no) + *status = WNN_SENTOU; + else + *status = WNN_CONNECT; + return (1); + } + } else if (kan_ckvt(sentou_no, kangovect) == WNN_CONNECT_BK) { + sb_one->status = WNN_SENTOU; + } else { + *status = WNN_NOT_CONNECT; + return (-1); + } + return(0); +} +*/ + +/* 小文節の並び替え 長さとベクタでソートする */ +/* que の先頭を返す */ +static struct JKT_SBN * +jkt_que_reorder (que, new) + register struct JKT_SBN *que, *new; +{ + struct JKT_SBN *que_sv; + register struct JKT_SBN *tmp; + register struct JKT_SBN *next; + + if (new == 0) + return (que); + if (jkt_sbjunjo (que, new) < 0) + { + que_sv = new; + } + else + que_sv = que; + + while (new != NULL) + { + next = new->lnk_br; + if (jkt_sbjunjo (que, new) < 0) + { + /* NEW が前 */ + tmp = que; + que = new; + que->lnk_br = tmp; + new = next; + continue; + } + /* QUE が前 */ + while ((jkt_sbjunjo (que, new) > 0) && que->lnk_br != NULL) + que = (que->lnk_br); + tmp = que->lnk_br; + /* QUE の後にNEW */ + que->lnk_br = new; + new->lnk_br = tmp; + new = next; + } + return (que_sv); +} + +/* que と new の順序 + 1: que が前 + 0: que の後に new + -1:new が前 +XXXXX -2:同一順位 */ +static int +jkt_sbjunjo (que, new) + struct JKT_SBN *que, *new; +{ + if (new == 0) + return (1); + if (que->j_c > new->j_c) + return (-1); + if (que->j_c < new->j_c) + { + if (que->lnk_br == 0) + return (0); + if (que->lnk_br->j_c > new->j_c) + return (0); + if (que->lnk_br->j_c < new->j_c) + return (1); + if (que->lnk_br->kangovect > new->kangovect) + return (0); + return (1); + } + if (que->kangovect == new->kangovect) + return (0); /* return (-2); */ + if (que->kangovect > new->kangovect) + return (-1); + if (que->lnk_br == 0) + return (0); + if (que->lnk_br->j_c > new->j_c) + return (0); + if (que->lnk_br->kangovect > new->kangovect) + return (0); + return (1); +} + + +/* 文節の先頭になれれば、大文節の候補をセットする */ +static int +set_jkt_dai (rjkt_dbn, jktdbn, sbn) + struct JKT_DBN **rjkt_dbn; + register struct JKT_DBN **jktdbn; + register struct JKT_SBN *sbn; +{ + struct JKT_DBN *getjktdbn (); + + if (*jktdbn != 0) + { + if (((*jktdbn)->lnk_br = getjktdbn ()) == 0) + return (-1); + (*jktdbn) = (*jktdbn)->lnk_br; + } + else + { + if ((*rjkt_dbn = *jktdbn = getjktdbn ()) == 0) + return (-1); + } + (*jktdbn)->j_c = sbn->j_c; + (*jktdbn)->sbn_cnt = sbn->kbcnt; + (*jktdbn)->lnk_br = 0; + (*jktdbn)->sbn = sbn; + (*jktdbn)->bend_m = yomi_sno_tmp; + return (0); +} + +static int +zen_sbn (yomi_sno, yomi_eno, endvect, endvect1, tjktsbn, bnst_num, parent +#ifndef NO_KANA + , gijiflagp +#endif /* NO_KANA */ + ) + int yomi_sno; + int yomi_eno; + int endvect; /* 終端ベクタ */ + int endvect1; /* 終端ベクタ */ + struct JKT_SBN **tjktsbn; /* 小文節解析結果 */ + int bnst_num; /* これまでに解析した小文節数 */ + struct JKT_SBN *parent; /* 親の幹語ノード */ +#ifndef NO_KANA + int *gijiflagp; +#endif /* NO_KANA */ +{ + register int fzkcnt, ii, jktcnt; + register int i, /* 幹語の終わりのインデックス */ + j; /* 文節始めのインデックス */ + struct JKT_SBN *jktsbn_top = 0; + struct ICHBNP *ichbnpbp; + struct JKT_SBN *gijisbn_top; + int get_giji_flg = -1; /* 擬似文節を作れたか */ + int cnt; +#ifndef NO_KANA + struct JKT_SBN *jktsbn; + int index_tmp; + struct fzkkouho *fzkptr; + int *vector1; +#endif + +#ifndef NO_KATA + struct JKT_SBN *get_kata_kouho (); +#endif + struct JKT_SBN *get_hira_kouho (); + struct SYO_BNSETSU *giji_sbn; + struct SYO_BNSETSU *getsbnsp (); + + if (yomi_sno == yomi_eno) + return (NOTHING); + + if (fzk_ckvt (endvect) == NO && fzk_ckvt (endvect1) == NO) + return (NOTHING); + fzkcnt = fzk_kai (&bun[yomi_sno], &bun[yomi_eno], endvect, endvect1, &ichbnpbp); + if (fzkcnt <= 0) + return (fzkcnt); /* ERROR */ + for (ii = 0; ii < fzkcnt; ii++) + getfzkoh (ichbnpbp, ii)->offset += yomi_sno; + + + for (ii = 0; ii < fzkcnt; ii++) + { + i = getfzkoh (ichbnpbp, ii)->offset; + if (jmtp[i] == (struct jdata **) UN_KNOWN) /* もう引いた? */ + jmt_set (i); /* 辞書引き */ + } + + j = j_max (ichbnpbp, fzkcnt); + j = (j >= yomi_eno) ? yomi_eno - 1 : j; + + jktcnt = 0; + +#if !defined(NO_KANA) && !defined(KOREAN) +/* カタカナ疑似文節を取り出します */ + if (gijiflagp != 0 && j < yomi_eno - 1) + { + for (ii = 0; ii < fzkcnt; ii++) + { /* 付属語 */ + fzkptr = getfzkoh (ichbnpbp, ii); + if (bnst_num == 1) + vector1 = getfzkoh1 (ichbnpbp, ii)->vector; + else + vector1 = fzkptr->vector; + index_tmp = fzkptr->offset; + if ((jktsbn = get_kata_kouho (&jktsbn_top, yomi_sno, yomi_eno, fzkptr->offset, fzkptr->vector, vector1, ii)) < (struct JKT_SBN *) 0) + + return (-1); + if (jktsbn > (struct JKT_SBN *) 0) + { + jktsbn->parent = parent; + jktsbn->bend_m = yomi_sno; + jktsbn->kbcnt = bnst_num; + jktcnt++; + } + } /* 付属語 */ + } +#endif /* !defined(NO_KANA) && !defined(KOREAN) */ + if ((giji_sbn = getsbnsp ()) == NO) + return (-1); + gijisbn_top = 0; + giji_sbn->bend_m = yomi_sno; + if (getgiji (yomi_sno, yomi_eno, giji_sbn, ichbnpbp, fzkcnt, bnst_num) >= 0) + { + if (giji_sbn->hinsi_fk != katakanago_no && giji_sbn->hinsi_fk != giji_no && giji_sbn->hinsi_fk != fuzokugo_no) + { + if (get_zen_giji (giji_sbn, &gijisbn_top) < 0) + return (-1); + gijisbn_top->parent = parent; + gijisbn_top->kbcnt = bnst_num; + get_giji_flg = giji_sbn->j_c; +#ifndef NO_KANA + if (gijiflagp != 0 && giji_sbn->j_c == yomi_eno - 1) + *gijiflagp = 1; +#endif /* NO_KANA */ + jktcnt++; + } + } + freesbn (giji_sbn); + + if (gijisbn_top != 0) + { + if (get_giji_flg > j) + { + gijisbn_top->lnk_br = jktsbn_top; + jktsbn_top = gijisbn_top; + get_giji_flg = -1; + } + } + + for (; j >= yomi_sno; j--) + { + /* 文節の長さ */ + if (get_giji_flg == j) + { + gijisbn_top->lnk_br = jktsbn_top; + jktsbn_top = gijisbn_top; + get_giji_flg = -1; + } + if ((cnt = jkt_sbn_one (yomi_sno, j + 1, &jktsbn_top, bnst_num, parent, ichbnpbp, fzkcnt)) < 0) + return (-1); + jktcnt += cnt; + + } + *tjktsbn = jktsbn_top; /* 短いものから並べる */ + freeibsp (ichbnpbp); + return (jktcnt); +} + +struct DSD_DBN * +get_dsd_dbn (cnt) + register int cnt; +{ + static struct DSD_DBN *m_dbn = 0; + static int md_cnt = 0; + + if (md_cnt < cnt) + { + /* どんどんふくれる Jserver */ + if (m_dbn) + free (m_dbn); + m_dbn = (struct DSD_DBN *) malloc (cnt * sizeof (struct DSD_DBN)); + if (m_dbn == NULL) + { + /* 大きくなって天まで届け! */ + wnn_errorno = WNN_JKTAREA_FULL; + error1 ("malloc err in dbn_set (at daibnsetsu jikouho).\n"); + md_cnt = 0; + return ((struct DSD_DBN *) -1); + } + else + md_cnt = cnt; + } + return (m_dbn); +} + +struct DSD_SBN * +get_dsd_sbn (cnt) + register int cnt; +{ + static struct DSD_SBN *m_sbn = 0; + static int ms_cnt = 0; + + if (ms_cnt < cnt) + { + if (m_sbn) + free (m_sbn); + m_sbn = (struct DSD_SBN *) malloc (cnt * sizeof (struct DSD_SBN)); + if (m_sbn == NULL) + { + wnn_errorno = WNN_JKTAREA_FULL; + error1 ("malloc err in dbn_set (at daibnsetsu jikouho).\n"); + ms_cnt = 0; + return ((struct DSD_SBN *) -1); + } + else + ms_cnt = cnt; + } + return (m_sbn); +} + +int +dbn_set (dsd_dbn, dbn) + struct DSD_DBN **dsd_dbn; + register struct JKT_DBN *dbn; +{ + register struct JKT_SBN *sbn; + register struct JKT_SONE *sone; + int i; +#ifndef CONVERT_from_TOP + int j, son, par; +#endif + struct JKT_DBN *next_dbn; + + int cnt; + int dbn_cnt; + int sbn_cnt; + struct DSD_DBN *d_dbn; + struct DSD_SBN *d_sbn; + register struct DSD_SBN *p_sbn; + struct DSD_SBN *sv_sbn; + + cnt_dbn (dbn, &cnt, &sbn_cnt); + + if ((d_dbn = *dsd_dbn = get_dsd_dbn (cnt)) <= (struct DSD_DBN *) 0) + return (-1); + if ((sv_sbn = d_sbn = get_dsd_sbn (sbn_cnt)) <= (struct DSD_SBN *) 0) + return (-1); + + while (dbn) + { + sbn = dbn->sbn; + cnt_sbn (sbn, &dbn_cnt, &sbn_cnt); + p_sbn = d_sbn = sv_sbn; + sv_sbn += sbn_cnt; + for (i = 0; i < dbn_cnt; i++) + { + d_dbn->bun_m = dbn->bend_m; + d_dbn->bun_jc = dbn->j_c; + d_dbn->sbncnt = dbn->sbn_cnt; + d_dbn->sbn = p_sbn; + p_sbn += dbn->sbn_cnt; + d_dbn++; + } +#ifdef CONVERT_from_TOP + sbn_set (dbn, &d_sbn, sone, dbn->sbn); + + next_dbn = dbn->lnk_br; + freejktdbn (dbn); + dbn = next_dbn; +#else /* CONVERT_from_TOP */ + for (sbn = dbn->sbn; sbn != 0; sbn = sbn->parent, d_sbn++) + { + son = cnt_son (dbn->sbn, sbn); + par = cnt_par (sbn); + p_sbn = d_sbn; + for (j = 0; j < son; j++) + { + for (sone = sbn->sbn; sone != 0; sone = sone->lnk_br) + { + for (i = 0; i < par; i++) + { + p_sbn->bun_m = sbn->bend_m; + p_sbn->bun_jc = sbn->j_c; + p_sbn->i_jc = sone->i_jc; + p_sbn->jentptr = sone->jentptr; + p_sbn->t_jc = sone->t_jc; + p_sbn->hinsi = sone->hinsi_fk; + p_sbn->kangovect = sbn->kangovect; + p_sbn->v_jc = sone->v_jc; + p_sbn->status_bkwd = sone->status_bkwd; + if (sbn->status == WNN_NOT_CONNECT && sone->jentptr == 0) + p_sbn->status = WNN_GIJI; + else + p_sbn->status = sbn->status; + p_sbn += dbn->sbn_cnt; + } + } + } + } + next_dbn = dbn->lnk_br; + freejktdbn (dbn); + dbn = next_dbn; +#endif /* CONVERT_from_TOP */ + } + return (cnt); +} + +#ifdef CONVERT_from_TOP +static void +sbn_set (dbn, pr_d_sbn, sone, sbn) + register struct JKT_DBN *dbn; + register struct DSD_SBN **pr_d_sbn; + register struct JKT_SONE *sone; + register struct JKT_SBN *sbn; +{ + int son, par; + register struct DSD_SBN *p_sbn; + if (sbn != 0) + { + sbn_set (dbn, pr_d_sbn, sone, sbn->parent); + + son = cnt_son (dbn->sbn, sbn); + par = cnt_par (sbn); + p_sbn = *pr_d_sbn; + sons_set (dbn, sone, sbn, p_sbn, son, par); + + (*pr_d_sbn)++; + } +} + +static void +sons_set (dbn, sone, sbn, p_sbn, son, par) + register struct JKT_DBN *dbn; + register struct JKT_SONE *sone; + register struct JKT_SBN *sbn; + register struct DSD_SBN *p_sbn; + register int son, par; +{ + register int i, j; + + for (j = 0; j < son; j++) + { + for (sone = sbn->sbn; sone != 0; sone = sone->lnk_br) + { + for (i = 0; i < par; i++) + { + p_sbn->bun_m = sbn->bend_m; + p_sbn->bun_jc = sbn->j_c; + p_sbn->i_jc = sone->i_jc; + p_sbn->jentptr = sone->jentptr; + p_sbn->t_jc = sone->t_jc; + p_sbn->hinsi = sone->hinsi_fk; + p_sbn->kangovect = sbn->kangovect; + p_sbn->v_jc = sone->v_jc; + p_sbn->status_bkwd = sone->status_bkwd; + if (sbn->status == WNN_NOT_CONNECT && sone->jentptr == 0) + p_sbn->status = WNN_GIJI; + else + p_sbn->status = sbn->status; + p_sbn += dbn->sbn_cnt; + } + } + } +} +#endif /* CONVERT_from_TOP */ + +/* 小文節の次候補の数 */ +int +cnt_sone (sone) + register struct JKT_SONE *sone; +{ + register int i = 0; + while (sone) + { + i++; + sone = sone->lnk_br; + } + return (i); +} + +/* その文節以後の総文節数 */ +static int +cnt_par (sbn) + register struct JKT_SBN *sbn; +{ + register int cnt; + cnt = 1; + while (sbn->parent) + { + sbn = sbn->parent; + cnt *= cnt_sone (sbn->sbn); + } + return (cnt); +} + +/* その文節以前の総文節数 */ +static int +cnt_son (son, sbn) + register struct JKT_SBN *son; + register struct JKT_SBN *sbn; +{ + register int cnt; + cnt = 1; + while (son != sbn) + { + cnt *= cnt_sone (son->sbn); + son = son->parent; + } + return (cnt); +} + +/* 1 大文節中の小文節の数 */ +static void +cnt_sbn (sbn, d_cnt, s_cnt) + register struct JKT_SBN *sbn; + register int *d_cnt; + register int *s_cnt; +{ + *s_cnt = 0; + *d_cnt = 1; + while (sbn) + { + *d_cnt *= cnt_sone (sbn->sbn); + (*s_cnt)++; + sbn = sbn->parent; + } + *s_cnt *= *d_cnt; +} + +/* 1 大文節の数 */ +static void +cnt_dbn (dbn, dbn_cnt, sbn_cnt) + register struct JKT_DBN *dbn; + register int *dbn_cnt; + register int *sbn_cnt; +{ + int dbn_cnt_tmp; + int sbn_cnt_tmp; + + *dbn_cnt = 0; + *sbn_cnt = 0; + while (dbn) + { + cnt_sbn (dbn->sbn, &dbn_cnt_tmp, &sbn_cnt_tmp); + *dbn_cnt += dbn_cnt_tmp; + *sbn_cnt += sbn_cnt_tmp; + dbn = dbn->lnk_br; + } +}