TraceLab Component Library
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
DanishStemmer.cs
Go to the documentation of this file.
1 /*
2  * Port of Snowball stemmers on C#
3  * Original stemmers can be found on http://snowball.tartarus.org
4  * Licence still BSD: http://snowball.tartarus.org/license.php
5  *
6  * Most of stemmers are ported from Java by Iveonik Systems ltd. (www.iveonik.com)
7  */
8 using System;
9 using System.Collections.Generic;
10 using System.Text;
11 
12 namespace TraceLab.Components.DevelopmentKit.Preprocessors.Stemmers.Snowball.Languages
13 {
18  {
19  private readonly static DanishStemmer methodObject = new DanishStemmer();
20 
21 
22  private readonly static Among[] a_0 =
23  {
24  new Among ( "hed", -1, 1, null ),
25  new Among ( "ethed", 0, 1, null ),
26  new Among ( "ered", -1, 1, null ),
27  new Among ( "e", -1, 1, null ),
28  new Among ( "erede", 3, 1, null ),
29  new Among ( "ende", 3, 1, null ),
30  new Among ( "erende", 5, 1, null ),
31  new Among ( "ene", 3, 1, null ),
32  new Among ( "erne", 3, 1, null ),
33  new Among ( "ere", 3, 1, null ),
34  new Among ( "en", -1, 1, null ),
35  new Among ( "heden", 10, 1, null ),
36  new Among ( "eren", 10, 1, null ),
37  new Among ( "er", -1, 1, null ),
38  new Among ( "heder", 13, 1, null ),
39  new Among ( "erer", 13, 1, null ),
40  new Among ( "s", -1, 2, null ),
41  new Among ( "heds", 16, 1, null ),
42  new Among ( "es", 16, 1, null ),
43  new Among ( "endes", 18, 1, null ),
44  new Among ( "erendes", 19, 1, null ),
45  new Among ( "enes", 18, 1, null ),
46  new Among ( "ernes", 18, 1, null ),
47  new Among ( "eres", 18, 1, null ),
48  new Among ( "ens", 16, 1, null ),
49  new Among ( "hedens", 24, 1, null ),
50  new Among ( "erens", 24, 1, null ),
51  new Among ( "ers", 16, 1, null ),
52  new Among ( "ets", 16, 1, null ),
53  new Among ( "erets", 28, 1, null ),
54  new Among ( "et", -1, 1, null ),
55  new Among ( "eret", 30, 1, null )
56  };
57 
58 
59 
60 
61  private readonly static Among[] a_1 =
62  {
63  new Among ( "gd", -1, -1, null ),
64  new Among ( "dt", -1, -1, null ),
65  new Among ( "gt", -1, -1, null ),
66  new Among ( "kt", -1, -1, null )
67  };
68 
69 
70  private readonly static Among[] a_2 =
71  {
72  new Among ( "ig", -1, 1, null ),
73  new Among ( "lig", 0, 1, null ),
74  new Among ( "elig", 1, 1, null ),
75  new Among ( "els", -1, 1, null ),
76  new Among ( "l\u00F8st", -1, 2, null )
77  };
78 
79 
80  private static readonly char[] g_v = {(char)17, (char)65, (char)16, (char)1, (char)0, (char)0, (char)0,
81  (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
82  (char)0, (char)0, (char)48,(char)0, (char)128 };
83 
84  private static readonly char[] g_s_ending = { (char)239, (char)254, (char)42, (char)3, (char)0, (char)0,
85  (char)0, (char)0, (char)0, (char)0, (char)0, (char)0,
86  (char)0, (char)0, (char)0, (char)0, (char)16 };
87 
88  private int I_x;
89  private int I_p1;
90 
91  private StringBuilder S_ch = new StringBuilder();
92 
93 
94  private void copy_from(DanishStemmer other)
95  {
96  I_x = other.I_x;
97  I_p1 = other.I_p1;
98  S_ch = other.S_ch;
99  base.copy_from(other);
100  }
101 
102 
103  private bool r_mark_regions()
104  {
105  bool subroot = false;
106  int v_1;
107  int v_2;
108  // (, line 29
109  I_p1 = limit;
110  // test, line 33
111  v_1 = cursor;
112  // (, line 33
113  // hop, line 33
114  {
115  int c = cursor + 3;
116  if (0 > c || c > limit)
117  {
118  return false;
119  }
120  cursor = c;
121  }
122  // setmark x, line 33
123  I_x = cursor;
124  cursor = v_1;
125  // goto, line 34
126  while (true)
127  {
128  v_2 = cursor;
129  do
130  {
131  if (!(in_grouping(g_v, 97, 248)))
132  {
133  break;
134  }
135  cursor = v_2;
136  subroot = true;
137  if (subroot) break;
138  } while (false);
139  if (subroot) { subroot = false; break; }
140  cursor = v_2;
141  if (cursor >= limit)
142  {
143  return false;
144  }
145  cursor++;
146  }
147  // gopast, line 34
148  while (true)
149  {
150  do
151  {
152  if (!(out_grouping(g_v, 97, 248)))
153  {
154  break;
155  }
156  subroot = true;
157  if (subroot) break;
158  } while (false);
159  if (subroot) { subroot = false; break; }
160  if (cursor >= limit)
161  {
162  return false;
163  }
164  cursor++;
165  }
166  // setmark p1, line 34
167  I_p1 = cursor;
168  // try, line 35
169  do
170  {
171  // (, line 35
172  if (!(I_p1 < I_x))
173  {
174  break;
175  }
176  I_p1 = I_x;
177  } while (false);
178  return true;
179  }
180 
181 
182  private bool r_main_suffix()
183  {
184  int among_var;
185  int v_1;
186  int v_2;
187  // (, line 40
188  // setlimit, line 41
189  v_1 = limit - cursor;
190  // tomark, line 41
191  if (cursor < I_p1)
192  {
193  return false;
194  }
195  cursor = I_p1;
196  v_2 = limit_backward;
197  limit_backward = cursor;
198  cursor = limit - v_1;
199  // (, line 41
200  // [, line 41
201  ket = cursor;
202  // substring, line 41
203  among_var = find_among_b(a_0, 32);
204  if (among_var == 0)
205  {
206  limit_backward = v_2;
207  return false;
208  }
209  // ], line 41
210  bra = cursor;
211  limit_backward = v_2;
212  switch (among_var)
213  {
214  case 0:
215  return false;
216  case 1:
217  // (, line 48
218  // delete, line 48
219  slice_del();
220  break;
221  case 2:
222  // (, line 50
223  if (!(in_grouping_b(g_s_ending, 97, 229)))
224  {
225  return false;
226  }
227  // delete, line 50
228  slice_del();
229  break;
230  }
231  return true;
232  }
233 
234 
235  private bool r_consonant_pair()
236  {
237  int v_1;
238  int v_2;
239  int v_3;
240  // (, line 54
241  // test, line 55
242  v_1 = limit - cursor;
243  // (, line 55
244  // setlimit, line 56
245  v_2 = limit - cursor;
246  // tomark, line 56
247  if (cursor < I_p1)
248  {
249  return false;
250  }
251  cursor = I_p1;
252  v_3 = limit_backward;
253  limit_backward = cursor;
254  cursor = limit - v_2;
255  // (, line 56
256  // [, line 56
257  ket = cursor;
258  // substring, line 56
259  if (find_among_b(a_1, 4) == 0)
260  {
261  limit_backward = v_3;
262  return false;
263  }
264  // ], line 56
265  bra = cursor;
266  limit_backward = v_3;
267  cursor = limit - v_1;
268  // next, line 62
269  if (cursor <= limit_backward)
270  {
271  return false;
272  }
273  cursor--;
274  // ], line 62
275  bra = cursor;
276  // delete, line 62
277  slice_del();
278  return true;
279  }
280 
281 
282  private bool r_other_suffix()
283  {
284  int among_var;
285  int v_1;
286  int v_2;
287  int v_3;
288  int v_4;
289  // (, line 65
290  // do, line 66
291  v_1 = limit - cursor;
292  do
293  {
294  // (, line 66
295  // [, line 66
296  ket = cursor;
297  // literal, line 66
298  if (!(eq_s_b(2, "st")))
299  {
300  break;
301  }
302  // ], line 66
303  bra = cursor;
304  // literal, line 66
305  if (!(eq_s_b(2, "ig")))
306  {
307  break;
308  }
309  // delete, line 66
310  slice_del();
311  } while (false);
312  cursor = limit - v_1;
313  // setlimit, line 67
314  v_2 = limit - cursor;
315  // tomark, line 67
316  if (cursor < I_p1)
317  {
318  return false;
319  }
320  cursor = I_p1;
321  v_3 = limit_backward;
322  limit_backward = cursor;
323  cursor = limit - v_2;
324  // (, line 67
325  // [, line 67
326  ket = cursor;
327  // substring, line 67
328  among_var = find_among_b(a_2, 5);
329  if (among_var == 0)
330  {
331  limit_backward = v_3;
332  return false;
333  }
334  // ], line 67
335  bra = cursor;
336  limit_backward = v_3;
337  switch (among_var)
338  {
339  case 0:
340  return false;
341  case 1:
342  // (, line 70
343  // delete, line 70
344  slice_del();
345  // do, line 70
346  v_4 = limit - cursor;
347  do
348  {
349  // call consonant_pair, line 70
350  if (!r_consonant_pair())
351  {
352  break;
353  }
354  } while (false);
355  cursor = limit - v_4;
356  break;
357  case 2:
358  // (, line 72
359  // <-, line 72
360  slice_from("l\u00F8s");
361  break;
362  }
363  return true;
364  }
365 
366 
367  private bool r_undouble()
368  {
369  int v_1;
370  int v_2;
371  // (, line 75
372  // setlimit, line 76
373  v_1 = limit - cursor;
374  // tomark, line 76
375  if (cursor < I_p1)
376  {
377  return false;
378  }
379  cursor = I_p1;
380  v_2 = limit_backward;
381  limit_backward = cursor;
382  cursor = limit - v_1;
383  // (, line 76
384  // [, line 76
385  ket = cursor;
386  if (!(out_grouping_b(g_v, 97, 248)))
387  {
388  limit_backward = v_2;
389  return false;
390  }
391  // ], line 76
392  bra = cursor;
393  // -> ch, line 76
394  S_ch = slice_to(S_ch);
395  limit_backward = v_2;
396  // name ch, line 77
397  if (!(eq_v_b(S_ch)))
398  {
399  return false;
400  }
401  // delete, line 78
402  slice_del();
403  return true;
404  }
405 
406 
407  private bool CanStem()
408  {
409  int v_1;
410  int v_2;
411  int v_3;
412  int v_4;
413  int v_5;
414  // (, line 82
415  // do, line 84
416  v_1 = cursor;
417  do
418  {
419  // call mark_regions, line 84
420  if (!r_mark_regions())
421  {
422  break;
423  }
424  } while (false);
425  cursor = v_1;
426  // backwards, line 85
427  limit_backward = cursor; cursor = limit;
428  // (, line 85
429  // do, line 86
430  v_2 = limit - cursor;
431  do
432  {
433  // call main_suffix, line 86
434  if (!r_main_suffix())
435  {
436  break;
437  }
438  } while (false);
439  cursor = limit - v_2;
440  // do, line 87
441  v_3 = limit - cursor;
442  do
443  {
444  // call consonant_pair, line 87
445  if (!r_consonant_pair())
446  {
447  break;
448  }
449  } while (false);
450  cursor = limit - v_3;
451  // do, line 88
452  v_4 = limit - cursor;
453  do
454  {
455  // call other_suffix, line 88
456  if (!r_other_suffix())
457  {
458  break;
459  }
460  } while (false);
461  cursor = limit - v_4;
462  // do, line 89
463  v_5 = limit - cursor;
464  do
465  {
466  // call undouble, line 89
467  if (!r_undouble())
468  {
469  break;
470  }
471  } while (false);
472  cursor = limit - v_5;
473  cursor = limit_backward;
474  return true;
475  }
476 
482  public string Stem(string s)
483  {
484  this.setCurrent(s.ToLowerInvariant());
485  this.CanStem();
486  return this.getCurrent();
487  }
488  }
489 }