lingo 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/.rspec +1 -0
  2. data/COPYING +663 -0
  3. data/ChangeLog +754 -0
  4. data/README +322 -0
  5. data/Rakefile +100 -0
  6. data/TODO +28 -0
  7. data/bin/lingo +5 -0
  8. data/bin/lingoctl +6 -0
  9. data/de.lang +121 -0
  10. data/de/lingo-abk.txt +74 -0
  11. data/de/lingo-dic.txt +56822 -0
  12. data/de/lingo-mul.txt +3209 -0
  13. data/de/lingo-syn.txt +14841 -0
  14. data/de/test_dic.txt +24 -0
  15. data/de/test_mul.txt +17 -0
  16. data/de/test_mul2.txt +2 -0
  17. data/de/test_singleword.txt +2 -0
  18. data/de/test_syn.txt +4 -0
  19. data/de/test_syn2.txt +1 -0
  20. data/de/user-dic.txt +10 -0
  21. data/en.lang +113 -0
  22. data/en/lingo-dic.txt +55434 -0
  23. data/en/lingo-mul.txt +456 -0
  24. data/en/user-dic.txt +5 -0
  25. data/info/Objekte.png +0 -0
  26. data/info/Typen.png +0 -0
  27. data/info/database.png +0 -0
  28. data/info/db_small.png +0 -0
  29. data/info/download.png +0 -0
  30. data/info/gpl-hdr.txt +27 -0
  31. data/info/kerze.png +0 -0
  32. data/info/language.png +0 -0
  33. data/info/lingo.png +0 -0
  34. data/info/logo.png +0 -0
  35. data/info/meeting.png +0 -0
  36. data/info/types.png +0 -0
  37. data/lib/lingo.rb +321 -0
  38. data/lib/lingo/attendee/abbreviator.rb +119 -0
  39. data/lib/lingo/attendee/debugger.rb +111 -0
  40. data/lib/lingo/attendee/decomposer.rb +101 -0
  41. data/lib/lingo/attendee/dehyphenizer.rb +167 -0
  42. data/lib/lingo/attendee/multiworder.rb +301 -0
  43. data/lib/lingo/attendee/noneword_filter.rb +103 -0
  44. data/lib/lingo/attendee/objectfilter.rb +86 -0
  45. data/lib/lingo/attendee/sequencer.rb +190 -0
  46. data/lib/lingo/attendee/synonymer.rb +105 -0
  47. data/lib/lingo/attendee/textreader.rb +237 -0
  48. data/lib/lingo/attendee/textwriter.rb +196 -0
  49. data/lib/lingo/attendee/tokenizer.rb +218 -0
  50. data/lib/lingo/attendee/variator.rb +185 -0
  51. data/lib/lingo/attendee/vector_filter.rb +158 -0
  52. data/lib/lingo/attendee/wordsearcher.rb +96 -0
  53. data/lib/lingo/attendees.rb +289 -0
  54. data/lib/lingo/cli.rb +62 -0
  55. data/lib/lingo/config.rb +104 -0
  56. data/lib/lingo/const.rb +131 -0
  57. data/lib/lingo/ctl.rb +173 -0
  58. data/lib/lingo/database.rb +587 -0
  59. data/lib/lingo/language.rb +530 -0
  60. data/lib/lingo/modules.rb +98 -0
  61. data/lib/lingo/types.rb +285 -0
  62. data/lib/lingo/utilities.rb +40 -0
  63. data/lib/lingo/version.rb +27 -0
  64. data/lingo-all.cfg +85 -0
  65. data/lingo-call.cfg +15 -0
  66. data/lingo.cfg +78 -0
  67. data/lingo.rb +3 -0
  68. data/lir.cfg +72 -0
  69. data/porter/stem.cfg +311 -0
  70. data/porter/stem.rb +150 -0
  71. data/spec/spec_helper.rb +0 -0
  72. data/test.cfg +79 -0
  73. data/test/attendee/ts_abbreviator.rb +35 -0
  74. data/test/attendee/ts_decomposer.rb +31 -0
  75. data/test/attendee/ts_multiworder.rb +390 -0
  76. data/test/attendee/ts_noneword_filter.rb +19 -0
  77. data/test/attendee/ts_objectfilter.rb +19 -0
  78. data/test/attendee/ts_sequencer.rb +43 -0
  79. data/test/attendee/ts_synonymer.rb +33 -0
  80. data/test/attendee/ts_textreader.rb +58 -0
  81. data/test/attendee/ts_textwriter.rb +98 -0
  82. data/test/attendee/ts_tokenizer.rb +32 -0
  83. data/test/attendee/ts_variator.rb +24 -0
  84. data/test/attendee/ts_vector_filter.rb +62 -0
  85. data/test/attendee/ts_wordsearcher.rb +119 -0
  86. data/test/lir.csv +3 -0
  87. data/test/lir.txt +12 -0
  88. data/test/lir2.txt +12 -0
  89. data/test/mul.txt +1 -0
  90. data/test/ref/artikel.mul +1 -0
  91. data/test/ref/artikel.non +159 -0
  92. data/test/ref/artikel.seq +270 -0
  93. data/test/ref/artikel.syn +16 -0
  94. data/test/ref/artikel.vec +928 -0
  95. data/test/ref/artikel.ven +928 -0
  96. data/test/ref/artikel.ver +928 -0
  97. data/test/ref/lir.csv +328 -0
  98. data/test/ref/lir.mul +1 -0
  99. data/test/ref/lir.non +274 -0
  100. data/test/ref/lir.seq +249 -0
  101. data/test/ref/lir.syn +94 -0
  102. data/test/test_helper.rb +113 -0
  103. data/test/ts_database.rb +269 -0
  104. data/test/ts_language.rb +396 -0
  105. data/txt/artikel-en.txt +157 -0
  106. data/txt/artikel.txt +170 -0
  107. data/txt/lir.txt +1317 -0
  108. metadata +211 -0
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
+ # Mehrworterkennung und Relationierung.
6
+ #
7
+ # Copyright (C) 2005-2007 John Vorhauer
8
+ # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
+ #
10
+ # This program is free software; you can redistribute it and/or modify it under
11
+ # the terms of the GNU Affero General Public License as published by the Free
12
+ # Software Foundation; either version 3 of the License, or (at your option)
13
+ # any later version.
14
+ #
15
+ # This program is distributed in the hope that it will be useful, but WITHOUT
16
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
+ # details.
19
+ #
20
+ # You should have received a copy of the GNU Affero General Public License along
21
+ # with this program; if not, write to the Free Software Foundation, Inc.,
22
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
+ #
24
+ # For more information visit http://www.lex-lingo.de or contact me at
25
+ # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
+ #
27
+ # Lex Lingo rules from here on
28
+ #++
29
+
30
+ class Lingo
31
+
32
+ # Der Noneword_filter ermöglicht es, alle nicht erkannten Wörter aus dem Datenstrom zu
33
+ # selektieren und weiterzuleiten. Im Prinzip werden alle erkannten Wörter gefiltert.
34
+ # Bei einem Indexierungslauf können so alle nicht durch den Wordsearcher erkannten Wörter,
35
+ # also die, die im Wörterbuch nicht enthalten sind, separat ausgegeben werden und als Grundlage für
36
+ # die Wörterbuchpflege dienen.
37
+ # Der Noneword_filter ist in einer frühen Entwicklungsphase entstanden. Die gleiche Funktion
38
+ # kann auch mit dem universelleren Objectfilter mit dem Ausdruck 'obj.kind_of?(Word) && obj.attr==WA_UNKNOWN'
39
+ # durchgeführt werden, mit dem einzigen Unterschied, dass der Noneword_filter nur die Wortform weiterleitet.
40
+ # Der Noneword_filter verschluckt ebenfalls alle Kommandos, ausser dem Dateianfang (*FILE) und Ende (*EOF),
41
+ # sowie dem LIR-Format-Spezifikum (*RECORD).
42
+ #
43
+ # *Hinweis* Dieser Attendee sammelt die auszugebenden Daten so lange, bis ein Dateiwechsel oder Record-Wechsel
44
+ # angekündigt wird. Erst dann werden alle Daten auf einmal weitergeleitet.
45
+ #
46
+ # === Mögliche Verlinkung
47
+ # Erwartet:: Daten vom Typ *Word*, z.B. von Abbreviator, Wordsearcher, Decomposer, Synonymer, Multiworder, Sequencer
48
+ # Erzeugt:: Daten vom Typ *String*, z.B. für Textwriter
49
+ #
50
+ # === Parameter
51
+ # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
52
+ # Alle anderen Parameter müssen zwingend angegeben werden.
53
+ # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
54
+ # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
55
+ #
56
+ # === Beispiele
57
+ # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
58
+ # meeting:
59
+ # attendees:
60
+ # - textreader: { out: lines, files: '$(files)' }
61
+ # - tokenizer: { in: lines, out: token }
62
+ # - wordsearcher: { in: token, out: words, source: 'sys-dic' }
63
+ # - noneword_filter: { in: words, out: filtr }
64
+ # - debugger: { in: filtr, prompt: 'out>' }
65
+ # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
66
+ # out> *FILE('test.txt')
67
+ # out> "lingo"
68
+ # out> *EOF('test.txt')
69
+
70
+ class Attendee::Noneword_filter < Attendee
71
+
72
+ protected
73
+
74
+ def init
75
+ @nonewords = []
76
+ end
77
+
78
+ # Control behandelt die Kommandos zum Öffnen und Schließen einer Datei.
79
+ # Für jede Datei wird ein neuer Satz nicht erkannter Wörter registriert.
80
+ def control(cmd, par)
81
+ case cmd
82
+ when STR_CMD_FILE
83
+ @nonewords.clear
84
+ when STR_CMD_EOL
85
+ deleteCmd
86
+ when STR_CMD_RECORD, STR_CMD_EOF
87
+ nones = @nonewords.sort.uniq
88
+ nones.each { |nw| forward(nw) }
89
+ add('Objekte gefiltert', nones.size)
90
+ @nonewords.clear
91
+ end
92
+ end
93
+
94
+ def process(obj)
95
+ if obj.is_a?(Word) && obj.attr==WA_UNKNOWN
96
+ inc('Anzahl nicht erkannter Wörter')
97
+ @nonewords << obj.form.downcase
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
+ # Mehrworterkennung und Relationierung.
6
+ #
7
+ # Copyright (C) 2005-2007 John Vorhauer
8
+ # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
+ #
10
+ # This program is free software; you can redistribute it and/or modify it under
11
+ # the terms of the GNU Affero General Public License as published by the Free
12
+ # Software Foundation; either version 3 of the License, or (at your option)
13
+ # any later version.
14
+ #
15
+ # This program is distributed in the hope that it will be useful, but WITHOUT
16
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
+ # details.
19
+ #
20
+ # You should have received a copy of the GNU Affero General Public License along
21
+ # with this program; if not, write to the Free Software Foundation, Inc.,
22
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
+ #
24
+ # For more information visit http://www.lex-lingo.de or contact me at
25
+ # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
+ #
27
+ # Lex Lingo rules from here on
28
+ #++
29
+
30
+ class Lingo
31
+
32
+ # Der Objectfilter ermöglicht es, beliebige Objekte aus dem Datenstrom herauszufiltern.
33
+ # Um die gewünschten Objekte zu identifizieren, sind ein paar Ruby-Kenntnisse und das Wissen
34
+ # um die Lingo Klassen notwendig. Hier sollen kurz die häufigsten Fälle angesprochen werden:
35
+ #
36
+ # Filtern nach einem bestimmten Typ, z.B. Token oder Word wird beispielsweise durch den Ausdruck
37
+ # 'obj.kind_of?(Word)' ermöglicht. Token und Words haben jeweils ein Attribut +attr+.
38
+ # Bei Token gibt +attr+ an, mit welcher Tokenizer-Regel das Token erkannt wurde. So können z.B.
39
+ # alle numerischen Token mit dem Ausdruck 'obj.kind_of?(Token) && obj.attr=="NUMS"' identifiziert
40
+ # werden. Wie bereits gezeigt, können Bedingungen durch logisches UND (&&) oder ODER (||) verknüpft werden.
41
+ # Das Attribut +form+ kann genutzt werden, um auf den Text eines Objektes zuzugreifen, z.B.
42
+ # 'obj.form=="John"'.
43
+ #
44
+ # === Mögliche Verlinkung
45
+ # Erwartet:: Daten beliebigen Typs von allen Attendees
46
+ # Erzeugt:: Daten, die der als Parameter übergebenen Bedingung entsprechen
47
+ #
48
+ # === Parameter
49
+ # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
50
+ # Alle anderen Parameter müssen zwingend angegeben werden.
51
+ # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
52
+ # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
53
+ # <b><i>objects</i></b>:: (Standard: true) Gibt einen Ruby-Ausdruck an, der, wenn der Ausdruck
54
+ # als Wahr ausgewertet wird, das Objekt weiterleitet und ansonsten filtert.
55
+ #
56
+ # === Beispiele
57
+ # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
58
+ # meeting:
59
+ # attendees:
60
+ # - textreader: { out: lines, files: '$(files)' }
61
+ # - tokenizer: { in: lines, out: token }
62
+ # - wordsearcher: { in: token, out: words, source: 'sys-dic' }
63
+ # - objectfilter: { in: words, out: filtr, objects: 'obj.kind_of?(Word) && obj.lexicals.size>0 && obj.lexicals[0].attr==LA_SUBSTANTIV' }
64
+ # - debugger: { in: filtr, prompt: 'out>' }
65
+ # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
66
+ # out> *FILE('test.txt')
67
+ # out> <Indexierung = [(indexierung/s)]>
68
+ # out> <Indexierung = [(indexierung/s)]>
69
+ # out> *EOL('test.txt')
70
+ # out> *EOF('test.txt')
71
+
72
+ class Attendee::Objectfilter < Attendee
73
+
74
+ protected
75
+
76
+ def init
77
+ @obj_eval = get_key('objects', 'true')
78
+ end
79
+
80
+ def process(obj)
81
+ forward(obj) if eval(@obj_eval)
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,190 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
+ # Mehrworterkennung und Relationierung.
6
+ #
7
+ # Copyright (C) 2005-2007 John Vorhauer
8
+ # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
+ #
10
+ # This program is free software; you can redistribute it and/or modify it under
11
+ # the terms of the GNU Affero General Public License as published by the Free
12
+ # Software Foundation; either version 3 of the License, or (at your option)
13
+ # any later version.
14
+ #
15
+ # This program is distributed in the hope that it will be useful, but WITHOUT
16
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
+ # details.
19
+ #
20
+ # You should have received a copy of the GNU Affero General Public License along
21
+ # with this program; if not, write to the Free Software Foundation, Inc.,
22
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
+ #
24
+ # For more information visit http://www.lex-lingo.de or contact me at
25
+ # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
+ #
27
+ # Lex Lingo rules from here on
28
+ #++
29
+
30
+ class Lingo
31
+
32
+ class WordSequence
33
+
34
+ attr_reader :classes, :format, :string
35
+
36
+ def initialize(wordclasses, format)
37
+ @string = wordclasses.downcase
38
+ @classes = @string.split(//)
39
+ @format = format
40
+ end
41
+
42
+ def scan(sequence)
43
+ pos = 0
44
+
45
+ while pos = sequence.index(string, pos)
46
+ yield pos, format.dup, classes
47
+ pos += 1
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ # Der Sequencer ist von seiner Funktion her ähnlich dem Multiworder. Der Multiworder
54
+ # nutzt zur Erkennung von Mehrwortgruppen spezielle Wörterbücher, der Sequencer hingegen
55
+ # definierte Folgen von Wortklassen. Mit dem Sequencer können Indexterme generiert werden,
56
+ # die sich über mehrere Wörter erstrecken.
57
+ # Die Textfolge "automatische Indexierung und geniale Indexierung"
58
+ # wird bisher in die Indexterme "automatisch", "Indexierung" und "genial" zerlegt.
59
+ # Über die Konfiguration kann der Sequencer Mehrwortgruppen identifizieren, die
60
+ # z.B. aus einem Adjektiv und einem Substantiv bestehen. Mit der o.g. Textfolge würde
61
+ # dann auch "Indexierung, automatisch" und "Indexierung, genial" als Indexterm erzeugt
62
+ # werden. Welche Wortklassenfolgen erkannt werden sollen und wie die Ausgabe aussehen
63
+ # soll, wird dem Sequencer über seine Konfiguration mitgeteilt.
64
+ #
65
+ # === Mögliche Verlinkung
66
+ # Erwartet:: Daten vom Typ *Word* z.B. von Wordsearcher, Decomposer, Ocr_variator, Multiworder
67
+ # Erzeugt:: Daten vom Typ *Word* (mit Attribut WA_SEQUENCE). Je erkannter Mehrwortgruppe wird ein zusätzliches Word-Objekt in den Datenstrom eingefügt. Z.B. für Ocr_variator, Sequencer, Noneword_filter, Vector_filter
68
+ #
69
+ # === Parameter
70
+ # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
71
+ # Alle anderen Parameter müssen zwingend angegeben werden.
72
+ # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
73
+ # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
74
+ # <b><i>stopper</i></b>:: (Standard: TA_PUNCTUATION, TA_OTHER) Gibt die Begrenzungen an, zwischen
75
+ # denen der Sequencer suchen soll, i.d.R. Satzzeichen und Sonderzeichen,
76
+ # weil sie kaum in einer Mehrwortgruppen vorkommen.
77
+ #
78
+ # === Konfiguration
79
+ # Der Sequencer benötigt zur Identifikation von Mehrwortgruppen Regeln, nach denen er
80
+ # arbeiten soll. Die benötigten Regeln werden nicht als Parameter, sondern in der
81
+ # Sprachkonfiguration hinterlegt, die sich standardmäßig in der Datei
82
+ # <tt>de.lang</tt> befindet (YAML-Format).
83
+ # language:
84
+ # attendees:
85
+ # sequencer:
86
+ # sequences: [ [AS, "2, 1"], [AK, "2, 1"] ]
87
+ # Hiermit werden dem Sequencer zwei Regeln mitgeteilt: Er soll Adjektiv-Substantiv- (AS) und
88
+ # Adjektiv-Kompositum-Folgen (AK) erkennen. Zusätzlich ist angegeben, in welchem Format die
89
+ # dadurch ermittelte Wortfolge ausgegeben werden soll. In diesem Beispiel also zuerst das
90
+ # Substantiv und durch Komma getrennt das Adjektiv.
91
+ #
92
+ # === Beispiele
93
+ # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
94
+ # meeting:
95
+ # attendees:
96
+ # - textreader: { out: lines, files: '$(files)' }
97
+ # - tokenizer: { in: lines, out: token }
98
+ # - wordsearcher: { in: token, out: words, source: 'sys-dic' }
99
+ # - sequencer: { in: words, out: seque }
100
+ # - debugger: { in: seque, prompt: 'out>' }
101
+ # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
102
+ # out> *FILE('test.txt')
103
+ # out> <Lingo|?>
104
+ # out> <kann = [(koennen/v)]>
105
+ # out> <indexierung, automatisch|SEQ = [(indexierung, automatisch/q)]>
106
+ # out> <automatische = [(automatisch/a)]>
107
+ # out> <Indexierung = [(indexierung/s)]>
108
+ # out> <und = [(und/w)]>
109
+ # out> <indexierung, genial|SEQ = [(indexierung, genial/q)]>
110
+ # out> <geniale = [(genial/a), (genialisch/a)]>
111
+ # out> <Indexierung = [(indexierung/s)]>
112
+ # out> :./PUNC:
113
+ # out> *EOL('test.txt')
114
+ # out> *EOF('test.txt')
115
+
116
+ class Attendee::Sequencer < BufferedAttendee
117
+
118
+ protected
119
+
120
+ def init
121
+ # Parameter verwerten
122
+ @stopper = get_array('stopper', TA_PUNCTUATION + ',' + TA_OTHER).map { |s| s.upcase }
123
+ @seq_strings = get_key('sequences').map { |e| WordSequence.new(*e) }
124
+
125
+ forward(STR_CMD_ERR, 'Konfiguration ist leer') if @seq_strings.empty?
126
+ end
127
+
128
+ def control(cmd, par)
129
+ # Jedes Control-Object ist auch Auslöser der Verarbeitung
130
+ process_buffer if [STR_CMD_RECORD, STR_CMD_EOF].include?(cmd)
131
+ end
132
+
133
+ def process_buffer?
134
+ # start buffer processing when stopper token are found or at unknown words
135
+ item = @buffer.last
136
+ (item.is_a?(StringA) && @stopper.include?(item.attr.upcase)) ||
137
+ (item.is_a?(Word) && item.unknown?)
138
+ end
139
+
140
+ def process_buffer
141
+ return if @buffer.empty?
142
+
143
+ unless @buffer.size < 2
144
+ matches = Hash.new { |h, k| h[k] = [] }
145
+
146
+ sequences(@buffer.map { |obj|
147
+ obj.is_a?(Word) && !obj.unknown? ? obj.attrs(false) : ['#']
148
+ }).uniq.each { |sequence|
149
+ @seq_strings.each { |wordseq|
150
+ wordseq.scan(sequence) { |pos, form, classes|
151
+ inc('Anzahl erkannter Sequenzen')
152
+
153
+ classes.each_with_index { |wc, index|
154
+ @buffer[pos + index].lexicals.find { |lex|
155
+ form.gsub!(index.succ.to_s, lex.form) if lex.attr == wc
156
+ } or break
157
+ } or next
158
+
159
+ matches[pos] << form
160
+ }
161
+ }
162
+ }
163
+
164
+ matches.sort.each { |pos, forms|
165
+ forms.uniq.each { |form|
166
+ deferred_insert(pos, Word.new_lexical(form, WA_SEQUENCE, LA_SEQUENCE))
167
+ }
168
+ }
169
+ end
170
+
171
+ forward_buffer
172
+ end
173
+
174
+ private
175
+
176
+ def sequences(map)
177
+ res = map.shift
178
+
179
+ map.each { |classes|
180
+ temp = []
181
+ res.each { |wc1| classes.each { |wc2| temp << (wc1 + wc2) } }
182
+ res = temp
183
+ }
184
+
185
+ res
186
+ end
187
+
188
+ end
189
+
190
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ #--
4
+ # LINGO ist ein Indexierungssystem mit Grundformreduktion, Kompositumzerlegung,
5
+ # Mehrworterkennung und Relationierung.
6
+ #
7
+ # Copyright (C) 2005-2007 John Vorhauer
8
+ # Copyright (C) 2007-2011 John Vorhauer, Jens Wille
9
+ #
10
+ # This program is free software; you can redistribute it and/or modify it under
11
+ # the terms of the GNU Affero General Public License as published by the Free
12
+ # Software Foundation; either version 3 of the License, or (at your option)
13
+ # any later version.
14
+ #
15
+ # This program is distributed in the hope that it will be useful, but WITHOUT
16
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17
+ # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18
+ # details.
19
+ #
20
+ # You should have received a copy of the GNU Affero General Public License along
21
+ # with this program; if not, write to the Free Software Foundation, Inc.,
22
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
23
+ #
24
+ # For more information visit http://www.lex-lingo.de or contact me at
25
+ # welcomeATlex-lingoDOTde near 50°55'N+6°55'E.
26
+ #
27
+ # Lex Lingo rules from here on
28
+ #++
29
+
30
+ class Lingo
31
+
32
+ # Der Synonymer untersucht die von anderen Attendees ermittelten Grundformen eines Wortes
33
+ # und sucht in den angegebenen Wörterbüchern nach Relationen zu anderen Grundformen.
34
+ # Gefundene Relationen erweitern die Liste des Word-Objektes und werden zur späteren
35
+ # Identifizierung mit der Wortklasse 'y' gekennzeichnet.
36
+ #
37
+ # === Mögliche Verlinkung
38
+ # Erwartet:: Daten vom Typ *Word* z.B. von Wordsearcher, Decomposer, Ocr_variator, Multiworder
39
+ # Erzeugt:: Daten vom Typ *Word* (ggf. um Relationen ergänzt) z.B. für Decomposer, Ocr_variator, Multiworder, Sequencer, Noneword_filter, Vector_filter
40
+ #
41
+ # === Parameter
42
+ # Kursiv dargestellte Parameter sind optional (ggf. mit Angabe der Voreinstellung).
43
+ # Alle anderen Parameter müssen zwingend angegeben werden.
44
+ # <b>in</b>:: siehe allgemeine Beschreibung des Attendee
45
+ # <b>out</b>:: siehe allgemeine Beschreibung des Attendee
46
+ # <b>source</b>:: siehe allgemeine Beschreibung des Dictionary
47
+ # <b><i>mode</i></b>:: (Standard: all) siehe allgemeine Beschreibung des Dictionary
48
+ # <b><i>skip</i></b>:: (Standard: WA_UNKNOWN [siehe strings.rb]) Veranlasst den Synonymer
49
+ # Wörter mit diesem Attribut zu überspringen.
50
+ #
51
+ # === Beispiele
52
+ # Bei der Verarbeitung einer normalen Textdatei mit der Ablaufkonfiguration <tt>t1.cfg</tt>
53
+ # meeting:
54
+ # attendees:
55
+ # - textreader: { out: lines, files: '$(files)' }
56
+ # - tokenizer: { in: lines, out: token }
57
+ # - abbreviator: { in: token, out: abbrev, source: 'sys-abk' }
58
+ # - wordsearcher: { in: abbrev, out: words, source: 'sys-dic' }
59
+ # - synonymer: { in: words, out: synos, source: 'sys-syn' }
60
+ # - debugger: { in: words, prompt: 'out>' }
61
+ # ergibt die Ausgabe über den Debugger: <tt>lingo -c t1 test.txt</tt>
62
+ # out> *FILE('test.txt')
63
+ # out> <Dies = [(dies/w), (das/y), (dies/y)]>
64
+ # out> <ist = [(sein/v), ((sich) befinden/y), (dasein/y), (existenz/y), (sein/y), (vorhandensein/y)]>
65
+ # out> <ggf. = [(gegebenenfalls/w), (bei bedarf/y), (gegebenenfalls/y), (ggf./y), (notfalls/y)]>
66
+ # out> <eine = [(einen/v), (ein/w)]>
67
+ # out> <Abk³rzung = [(abk³rzung/s), (abbreviation/y), (abbreviatur/y), (abk³rzung/y), (akronym/y), (kurzbezeichnung/y)]>
68
+ # out> :./PUNC:
69
+ # out> *EOL('test.txt')
70
+ # out> *EOF('test.txt')
71
+
72
+ class Attendee::Synonymer < Attendee
73
+
74
+ protected
75
+
76
+ def init
77
+ # Wörterbuch bereitstellen
78
+ src = get_array('source')
79
+ mod = get_key('mode', 'all')
80
+ @dic = Dictionary.new({'source'=>src, 'mode'=>mod}, @lingo)
81
+
82
+ @skip = get_array('skip', WA_UNKNOWN).collect {|s| s.upcase }
83
+ end
84
+
85
+ def control(cmd, par)
86
+ @dic.report.each_pair { |k, v| set( k, v ) } if cmd == STR_CMD_STATUS
87
+ end
88
+
89
+ def process(obj)
90
+ if obj.is_a?(Word) && @skip.index(obj.attr).nil?
91
+ inc('Anzahl gesuchter Wörter')
92
+
93
+ # finde die Synonyme für alle Lexicals des Wortes
94
+ synos = @dic.find_synonyms(obj)
95
+ obj.lexicals += synos.sort.uniq
96
+
97
+ inc('Anzahl erweiteter Wörter') if synos.size>0
98
+ add('Anzahl gefundener Synonyme', synos.size)
99
+ end
100
+ forward(obj)
101
+ end
102
+
103
+ end
104
+
105
+ end