OSDN Git Service

MMFへのアクセスをアンマネージドポインタ経由として高速化
[nmecab/NMeCabRepo2.git] / src / LibNMeCab / MeCabTagger.cs
1 //  MeCab -- Yet Another Part-of-Speech and Morphological Analyzer\r
2 //\r
3 //  Copyright(C) 2001-2006 Taku Kudo <taku@chasen.org>\r
4 //  Copyright(C) 2004-2006 Nippon Telegraph and Telephone Corporation\r
5 using System;\r
6 using System.Collections.Generic;\r
7 using System.Text;\r
8 using NMeCab.Core;\r
9 \r
10 namespace NMeCab\r
11 {\r
12     public class MeCabTagger : IDisposable\r
13     {\r
14         private readonly Viterbi viterbi = new Viterbi();\r
15         private readonly Writer writer = new Writer();\r
16 \r
17         #region Mode\r
18 \r
19         /// <summary>\r
20         /// 部分解析モード\r
21         /// </summary>\r
22         public bool Partial\r
23         {\r
24             get { this.ThrowIfDisposed(); return this.viterbi.Partial; }\r
25             set { this.ThrowIfDisposed(); this.viterbi.Partial = value; }\r
26         }\r
27 \r
28         /// <summary>\r
29         /// ソフト分かち書きの温度パラメータ\r
30         /// </summary>\r
31         public float Theta\r
32         {\r
33             get { this.ThrowIfDisposed(); return this.viterbi.Theta; }\r
34             set { this.ThrowIfDisposed(); this.viterbi.Theta = value; }\r
35         }\r
36 \r
37         /// <summary>\r
38         /// ラティスレベル(どの程度のラティス情報を解析時に構築するか)\r
39         /// </summary>\r
40         /// <value>\r
41         /// 0: 最適解のみが出力可能なレベル (デフォルト, 高速) \r
42         /// 1: N-best 解が出力可能なレベル (中速) \r
43         /// 2: ソフトわかち書きが可能なレベル (低速) \r
44         /// </value>\r
45         public MeCabLatticeLevel LatticeLevel\r
46         {\r
47             get { this.ThrowIfDisposed(); return this.viterbi.LatticeLevel; }\r
48             set { this.ThrowIfDisposed(); this.viterbi.LatticeLevel = value; }\r
49         }\r
50 \r
51         /// <summary>\r
52         /// 全出力モード\r
53         /// </summary>\r
54         /// <value>\r
55         /// true: 全出力\r
56         /// false: ベスト解のみ\r
57         /// </value>\r
58         public bool AllMorphs\r
59         {\r
60             get { this.ThrowIfDisposed(); return this.viterbi.AllMorphs; }\r
61             set { this.ThrowIfDisposed(); this.viterbi.AllMorphs = value; }\r
62         }\r
63 \r
64         /// <summary>\r
65         /// 解析結果のフォーマット\r
66         /// </summary>\r
67         public string OutPutFormatType\r
68         {\r
69             get { this.ThrowIfDisposed(); return this.writer.OutputFormatType; }\r
70             set { this.ThrowIfDisposed(); this.writer.OutputFormatType = value; }\r
71         }\r
72 \r
73         #endregion\r
74 \r
75         #region Constractor\r
76 \r
77         /// <summary>\r
78         /// コンストラクタ\r
79         /// </summary>\r
80         private MeCabTagger()\r
81         {\r
82         }\r
83 \r
84         #endregion\r
85 \r
86         #region Open/Create\r
87 \r
88         /// <summary>\r
89         /// MeCabTaggerを開く\r
90         /// </summary>\r
91         /// <param name="param">初期化パラメーター</param>\r
92         private void Open(MeCabParam param)\r
93         {\r
94             this.viterbi.Open(param);\r
95 \r
96             this.writer.Open(param);\r
97         }\r
98 \r
99         /// <summary>\r
100         /// MeCabTaggerのインスタンスを生成する\r
101         /// </summary>\r
102         /// <returns>MeCabTaggerのインスタンス</returns>\r
103         public static MeCabTagger Create()\r
104         {\r
105             MeCabParam param = new MeCabParam();\r
106             param.LoadDicRC();\r
107             return MeCabTagger.Create(param);\r
108         }\r
109 \r
110         /// <summary>\r
111         /// MeCabTaggerのインスタンスを生成する\r
112         /// </summary>\r
113         /// <param name="param">初期化パラメーター</param>\r
114         /// <returns>MeCabTaggerのインスタンス</returns>\r
115         public static MeCabTagger Create(MeCabParam param)\r
116         {\r
117             MeCabTagger tagger = new MeCabTagger();\r
118             tagger.Open(param);\r
119             return tagger;\r
120         }\r
121 \r
122         #endregion\r
123 \r
124         #region Parse\r
125 \r
126         /// <summary>\r
127         /// 解析を行う\r
128         /// </summary>\r
129         /// <param name="str">解析対象の文字列</param>\r
130         /// <returns>解析結果の文字列</returns>\r
131         public unsafe string Parse(string str)\r
132         {\r
133             fixed (char* pStr = str)\r
134                 return this.Parse(pStr, str.Length);\r
135         }\r
136 \r
137         /// <summary>\r
138         /// 解析を行う\r
139         /// </summary>\r
140         /// <param name="str">解析対象の文字列へのポインタ</param>\r
141         /// <param name="len">解析対象の文字列の長さ</param>\r
142         /// <returns>解析結果の文字列</returns>\r
143         public unsafe string Parse(char* str, int len)\r
144         {\r
145             MeCabNode n = this.ParseToNode(str, len);\r
146             if (n == null) return null;\r
147             StringBuilder os = new StringBuilder();\r
148             this.writer.Write(os, n);\r
149             return os.ToString();\r
150         }\r
151 \r
152         /// <summary>\r
153         /// 解析を行う\r
154         /// </summary>\r
155         /// <param name="str">解析対象の文字列</param>\r
156         /// <returns>文頭の形態素</returns>\r
157         public unsafe MeCabNode ParseToNode(string str)\r
158         {\r
159             if (str == null) throw new ArgumentNullException("str");\r
160 \r
161             fixed (char* pStr = str)\r
162                 return this.ParseToNode(pStr, str.Length);\r
163         }\r
164 \r
165         /// <summary>\r
166         /// 解析を行う\r
167         /// </summary>\r
168         /// <param name="str">解析対象の文字列へのポインタ</param>\r
169         /// <param name="len">解析対象の文字列の長さ</param>\r
170         /// <returns>文頭の形態素</returns>\r
171         public unsafe MeCabNode ParseToNode(char* str, int len)\r
172         {\r
173             this.ThrowIfDisposed();\r
174             if (len < 0) throw new ArgumentOutOfRangeException("len", "Please set one or more to length of string.");\r
175 \r
176             return this.viterbi.Analyze(str, len);\r
177         }\r
178 \r
179         #endregion\r
180 \r
181         #region NBest\r
182 \r
183         /// <summary>\r
184         /// 解析を行い結果を確からしいものから順番に取得する\r
185         /// </summary>\r
186         /// <param name="str">解析対象の文字列</param>\r
187         /// <returns>文頭の形態素を、確からしい順に取得する列挙子</returns>\r
188         public unsafe IEnumerable<MeCabNode> ParseNBestToNode(string str)\r
189         {\r
190             fixed (char* pStr = str)\r
191                 return this.ParseNBestToNode(pStr, str.Length);\r
192         }\r
193 \r
194         /// <summary>\r
195         /// 解析を行い結果を確からしいものから順番に取得する\r
196         /// </summary>\r
197         /// <param name="str">解析対象の文字列へのポインタ</param>\r
198         /// <returns>文頭の形態素を、確からしい順に取得する列挙子</returns>\r
199         public unsafe IEnumerable<MeCabNode> ParseNBestToNode(char* str, int len)\r
200         {\r
201             if (this.LatticeLevel == 0)\r
202                 throw new InvalidOperationException("Please set one or more to LatticeLevel.");\r
203 \r
204             MeCabNode n = this.ParseToNode(str, len);\r
205             NBestGenerator nBest = new NBestGenerator();\r
206             nBest.Set(n);\r
207             return nBest.GetEnumerator();\r
208         }\r
209 \r
210         /// <summary>\r
211         /// ParseのN-Best解出力version\r
212         /// </summary>\r
213         /// <param name="n">必要な解析結果の個数</param>\r
214         /// <param name="str">解析対象の文字列</param>\r
215         /// <returns>解析結果の文字列</returns>\r
216         public unsafe string ParseNBest(int n, string str)\r
217         {\r
218             fixed (char* pStr = str)\r
219                 return this.ParseNBest(n, pStr, str.Length);\r
220         }\r
221 \r
222         /// <summary>\r
223         /// ParseのN-Best解出力version\r
224         /// </summary>\r
225         /// <param name="n">必要な解析結果の個数</param>\r
226         /// <param name="str">解析対象の文字列へのポインタ</param>\r
227         /// <param name="len">解析対象の文字列の長さ</param>\r
228         /// <returns>解析結果の文字列</returns>\r
229         public unsafe string ParseNBest(int n, char* str, int len)\r
230         {\r
231             if (n <= 0) throw new ArgumentOutOfRangeException("n", "");\r
232 \r
233             if (n == 1) return this.Parse(str, len);\r
234 \r
235             StringBuilder os = new StringBuilder();\r
236             foreach (MeCabNode node in this.ParseNBestToNode(str, len))\r
237             {\r
238                 this.writer.Write(os, node);\r
239                 if (--n == 0) break;\r
240             }\r
241             return os.ToString();\r
242         }\r
243 \r
244         #endregion\r
245 \r
246         #region Dispose\r
247 \r
248         private bool disposed;\r
249 \r
250         /// <summary>\r
251         /// 使用中のリソースを開放する\r
252         /// </summary>\r
253         public void Dispose()\r
254         {\r
255             this.Dispose(true);\r
256             GC.SuppressFinalize(this);\r
257         }\r
258 \r
259         protected virtual void Dispose(bool disposing)\r
260         {\r
261             if (disposed) return;\r
262 \r
263             if (disposing)\r
264             {\r
265                 this.viterbi.Dispose(); //Nullチェック不要\r
266             }\r
267 \r
268             this.disposed = true;\r
269         }\r
270 \r
271         ~MeCabTagger()\r
272         {\r
273             this.Dispose(false);\r
274         }\r
275 \r
276         private void ThrowIfDisposed()\r
277         {\r
278             if (this.disposed)\r
279                 throw new ObjectDisposedException(this.GetType().FullName);\r
280         }\r
281 \r
282         #endregion\r
283     }\r
284 }\r