lingo 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/COPYING +663 -0
- data/ChangeLog +754 -0
- data/README +322 -0
- data/Rakefile +100 -0
- data/TODO +28 -0
- data/bin/lingo +5 -0
- data/bin/lingoctl +6 -0
- data/de.lang +121 -0
- data/de/lingo-abk.txt +74 -0
- data/de/lingo-dic.txt +56822 -0
- data/de/lingo-mul.txt +3209 -0
- data/de/lingo-syn.txt +14841 -0
- data/de/test_dic.txt +24 -0
- data/de/test_mul.txt +17 -0
- data/de/test_mul2.txt +2 -0
- data/de/test_singleword.txt +2 -0
- data/de/test_syn.txt +4 -0
- data/de/test_syn2.txt +1 -0
- data/de/user-dic.txt +10 -0
- data/en.lang +113 -0
- data/en/lingo-dic.txt +55434 -0
- data/en/lingo-mul.txt +456 -0
- data/en/user-dic.txt +5 -0
- data/info/Objekte.png +0 -0
- data/info/Typen.png +0 -0
- data/info/database.png +0 -0
- data/info/db_small.png +0 -0
- data/info/download.png +0 -0
- data/info/gpl-hdr.txt +27 -0
- data/info/kerze.png +0 -0
- data/info/language.png +0 -0
- data/info/lingo.png +0 -0
- data/info/logo.png +0 -0
- data/info/meeting.png +0 -0
- data/info/types.png +0 -0
- data/lib/lingo.rb +321 -0
- data/lib/lingo/attendee/abbreviator.rb +119 -0
- data/lib/lingo/attendee/debugger.rb +111 -0
- data/lib/lingo/attendee/decomposer.rb +101 -0
- data/lib/lingo/attendee/dehyphenizer.rb +167 -0
- data/lib/lingo/attendee/multiworder.rb +301 -0
- data/lib/lingo/attendee/noneword_filter.rb +103 -0
- data/lib/lingo/attendee/objectfilter.rb +86 -0
- data/lib/lingo/attendee/sequencer.rb +190 -0
- data/lib/lingo/attendee/synonymer.rb +105 -0
- data/lib/lingo/attendee/textreader.rb +237 -0
- data/lib/lingo/attendee/textwriter.rb +196 -0
- data/lib/lingo/attendee/tokenizer.rb +218 -0
- data/lib/lingo/attendee/variator.rb +185 -0
- data/lib/lingo/attendee/vector_filter.rb +158 -0
- data/lib/lingo/attendee/wordsearcher.rb +96 -0
- data/lib/lingo/attendees.rb +289 -0
- data/lib/lingo/cli.rb +62 -0
- data/lib/lingo/config.rb +104 -0
- data/lib/lingo/const.rb +131 -0
- data/lib/lingo/ctl.rb +173 -0
- data/lib/lingo/database.rb +587 -0
- data/lib/lingo/language.rb +530 -0
- data/lib/lingo/modules.rb +98 -0
- data/lib/lingo/types.rb +285 -0
- data/lib/lingo/utilities.rb +40 -0
- data/lib/lingo/version.rb +27 -0
- data/lingo-all.cfg +85 -0
- data/lingo-call.cfg +15 -0
- data/lingo.cfg +78 -0
- data/lingo.rb +3 -0
- data/lir.cfg +72 -0
- data/porter/stem.cfg +311 -0
- data/porter/stem.rb +150 -0
- data/spec/spec_helper.rb +0 -0
- data/test.cfg +79 -0
- data/test/attendee/ts_abbreviator.rb +35 -0
- data/test/attendee/ts_decomposer.rb +31 -0
- data/test/attendee/ts_multiworder.rb +390 -0
- data/test/attendee/ts_noneword_filter.rb +19 -0
- data/test/attendee/ts_objectfilter.rb +19 -0
- data/test/attendee/ts_sequencer.rb +43 -0
- data/test/attendee/ts_synonymer.rb +33 -0
- data/test/attendee/ts_textreader.rb +58 -0
- data/test/attendee/ts_textwriter.rb +98 -0
- data/test/attendee/ts_tokenizer.rb +32 -0
- data/test/attendee/ts_variator.rb +24 -0
- data/test/attendee/ts_vector_filter.rb +62 -0
- data/test/attendee/ts_wordsearcher.rb +119 -0
- data/test/lir.csv +3 -0
- data/test/lir.txt +12 -0
- data/test/lir2.txt +12 -0
- data/test/mul.txt +1 -0
- data/test/ref/artikel.mul +1 -0
- data/test/ref/artikel.non +159 -0
- data/test/ref/artikel.seq +270 -0
- data/test/ref/artikel.syn +16 -0
- data/test/ref/artikel.vec +928 -0
- data/test/ref/artikel.ven +928 -0
- data/test/ref/artikel.ver +928 -0
- data/test/ref/lir.csv +328 -0
- data/test/ref/lir.mul +1 -0
- data/test/ref/lir.non +274 -0
- data/test/ref/lir.seq +249 -0
- data/test/ref/lir.syn +94 -0
- data/test/test_helper.rb +113 -0
- data/test/ts_database.rb +269 -0
- data/test/ts_language.rb +396 -0
- data/txt/artikel-en.txt +157 -0
- data/txt/artikel.txt +170 -0
- data/txt/lir.txt +1317 -0
- 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
|