OSDN Git Service

Bumped version 2.4.4.
[chasen-legacy/chasen.git] / lib / grammar.c
1 /*
2  * Copyright (c) 2003 Nara Institute of Science and Technology
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name Nara Institute of Science and Technology may not be used to
15  *    endorse or promote products derived from this software without
16  *    specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Nara Institute of Science and Technology 
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
21  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE Nara Institute
22  * of Science and Technology BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
26  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $Id: grammar.c,v 1.1.1.1 2007/03/13 07:40:10 masayu-a Exp $
31  */
32
33 #include "chadic.h"
34 #include "literal.h"
35
36 hinsi_t Cha_hinsi[HINSI_MAX];
37
38 /*
39  * make_hinsi
40  */
41 static int
42 make_hinsi(chasen_cell_t * cell, int mother, int idx)
43 {
44     char *name, *s;
45     int depth, i, d;
46     short *path;
47
48     if (idx >= HINSI_MAX)
49         cha_exit_file(1, "too many (over %d) parts of speech", HINSI_MAX);
50
51     /*
52      * path 
53      */
54     depth = Cha_hinsi[mother].depth + 1;
55     path = cha_malloc(sizeof(short) * (depth + 1));
56     memcpy(path, Cha_hinsi[mother].path, sizeof(short) * depth);
57     path[depth - 1] = idx;
58     path[depth] = 0;
59     Cha_hinsi[idx].depth = depth;
60     Cha_hinsi[idx].path = path;
61
62     /*
63      * hinsi name and katsuyou 
64      */
65     name = cha_s_atom(cha_car(cell));
66 #if 0
67     printf("%2d:%*s%s\n", depth, depth * 2, "", name);
68     fflush(stdout);
69 #endif
70     /*
71      * ÉÊ»ì¤ÎÆó½ÅÅÐÏ¿¤Î¥Á¥§¥Ã¥¯ ¤¢¤Þ¤ê¤­¤ì¤¤¤ÊÊýË¡¤Ç¤Ï¤Ê¤¤ 
72      */
73     for (i = 0; Cha_hinsi[mother].daughter[i + 1]; i++) {
74         if (!strcmp(Cha_hinsi[Cha_hinsi[mother].daughter[i]].name, name))
75             cha_exit_file(1, "hinsi `%s' is already defined", name);
76     }
77
78     s = name + strlen(name) - 1;
79     if (Cha_hinsi[mother].kt == 1 || *s == '%') {
80         Cha_hinsi[idx].kt = 1;
81         if (*s == '%')
82             *s = '\0';
83     }
84
85     if (*name == '\0')
86         cha_exit_file(1, "an empty string for hinsi name");
87
88     Cha_hinsi[idx].name = cha_strdup(name);
89 #if 0
90     cha_s_print(stdout, cha_car(cell));
91     printf("[%d,%d,%s]\n", mother, idx, name);
92     fflush(stdout);
93 #endif
94
95     cell = cha_cdr(cell);
96     if (nullp(cell)) {
97         static short daughter0 = 0;
98         Cha_hinsi[idx++].daughter = &daughter0;
99     } else {
100         short daughter[256];
101         int ndaughter = 0;
102         d = idx + 1;
103         /*
104          * ÉÊ»ì¤ÎÆó½ÅÅÐÏ¿¤Î¥Á¥§¥Ã¥¯¤Î¤¿¤á°ì»þŪ¤Ë daughter ¤òÂåÆþ 
105          */
106         Cha_hinsi[idx].daughter = daughter;
107         for (; !nullp(cell); cell = cha_cdr(cell)) {
108             daughter[ndaughter++] = d;
109             daughter[ndaughter] = 0;
110             d = make_hinsi(cha_car(cell), idx, d);
111         }
112         daughter[ndaughter++] = 0;
113         Cha_hinsi[idx].daughter = cha_malloc(sizeof(short) * ndaughter);
114         memcpy(Cha_hinsi[idx].daughter, daughter,
115                sizeof(short) * ndaughter);
116         idx = d;
117     }
118
119     return idx;
120 }
121
122 /*
123  * cha_read_class
124  */
125 void
126 cha_read_class(FILE * fp)
127 {
128     static short path0 = 0;
129     chasen_cell_t *cell1;
130     short daughter[256];
131     int idx, ndaughter;
132
133     /*
134      * root node 
135      */
136     Cha_hinsi[0].path = &path0;
137     Cha_hinsi[0].depth = 0;
138     Cha_hinsi[0].kt = 0;
139     Cha_hinsi[0].name = CHA_LIT(STR_BOS_EOS);
140
141     idx = 1;
142     ndaughter = 0;
143     /*
144      * ÉÊ»ì¤ÎÆó½ÅÅÐÏ¿¤Î¥Á¥§¥Ã¥¯¤Î¤¿¤á°ì»þŪ¤Ë daughter ¤òÂåÆþ 
145      */
146     Cha_hinsi[0].daughter = daughter;
147     while (!cha_s_feof(fp)) {
148         if (!nullp(cell1 = cha_s_read(fp))) {
149             daughter[ndaughter++] = idx;
150             daughter[ndaughter] = 0;
151             idx = make_hinsi(cell1, 0, idx);
152         }
153     }
154
155     daughter[ndaughter++] = 0;
156     Cha_hinsi[0].daughter = cha_malloc(sizeof(short) * ndaughter);
157     memcpy(Cha_hinsi[0].daughter, daughter, sizeof(short) * ndaughter);
158
159     /*
160      * last node 
161      */
162     Cha_hinsi[idx].name = NULL;
163 }
164
165 /*
166  * cha_match_nhinsi - cell¤Îwildcardɽ¸½¤¬hinsi¤È¥Þ¥Ã¥Á¤·¤Æ¤¤¤ë¤«¤É¤¦¤«
167  */
168 int
169 cha_match_nhinsi(chasen_cell_t * cell, int hinsi)
170 {
171     char *name;
172     short *path;
173
174     for (path = Cha_hinsi[hinsi].path; !nullp(cell);
175          path++, cell = cha_cdr(cell)) {
176         name = cha_s_atom(cha_car(cell));
177         if (!*path) {
178             /*
179              * cell ¤ÎÊý¤¬Ä¹¤¤¤È¤­¤Ï¡¢ºÇ¸å¤ÎϢ³¤·¤¿ "*" ¤Ï̵»ë¤¹¤ë
180              * ¤³¤ì¤Ë¤è¤ê cell:(Éû»ì *) ¤È hinsi:Éû»ì ¤¬¥Þ¥Ã¥Á¤¹¤ë
181              * chasenrc ¤ÎÉʻ쥳¥¹¥È¤Î»ØÄê¤Ç (Éû»ì *) ¤Ê¤É¤¬»È¤ï¤ì¤Æ¤¤¤ë
182              * connect.cha ¤Ç¤â»È¤ï¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë
183              */
184             if (strcmp(name, "*"))
185                 return 0;
186             /*
187              * ¤³¤ì°Ê¹ß¤Ï *path ¤ÎÃͤ¬ 0 ¤Ë¤Ê¤ë¤è¤¦¤Ë¤¹¤ë 
188              */
189             path--;
190         } else {
191             if (strcmp(name, "*") && strcmp(name, Cha_hinsi[*path].name))
192                 return 0;
193         }
194     }
195     /*
196      * cell ¤¬ hinsi ¤è¤ê¤âÁƤ¤Ê¬Îà¤Ê¤é¥Þ¥Ã¥Á 
197      */
198     return 1;
199 }
200
201 /*
202  * cha_read_grammar - read GRAMMAR_FILE and set Class[][]
203  *
204  * inputs:
205  *      dir - 0: read from current directory
206  *            1: read from grammar directory
207  *            2: read from current directory or grammar directory
208  */
209 void
210 cha_read_grammar(FILE * fp_out, int ret, int dir)
211 {
212     FILE *fp;
213     char *filepath;
214
215     fp = cha_fopen_grammar(GRAMMAR_FILE, "r", ret, dir, &filepath);
216     if (fp_out != NULL)
217         fprintf(fp_out, "parsing %s\n", filepath);
218
219     cha_read_class(fp);
220
221     fclose(fp);
222 }