/*
* $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;
}
}
syntax highlighted by Code2HTML, v. 0.9.1