/* Department of Computational Linguistics, Ruprecht-Karls-University of Heidelberg Marina Stegarescu: mstegare@hotmail.com Doina Gliga: doina_gliga@yahoo.co.uk Erwin Glockner: eglockner@hotmail.com 2006.07.15 RoStemmer mit Snowball -> ein Stemmer anhand der Snowball Sprache fürs Rumänische */ /* die später definierten Funktionen und benutzten Data-Types deklarieren*/ routines ( mark_regions R1 R2 morhological_suffixes deriv_suffixes1 deriv_suffixes2 exception1 verb_suffix residual_suffix ) externals ( stem ) integers (p1 p2 ) groupings ( v ) /* ă -> ab , â -> a^ , î -> i^, ş -> s, , ţ -> t, ; die Diaktritika der rumänischen Sprache definieren */ stringescapes {} stringdef a^ hex 'E2' // â stringdef ab hex '103' // ă stringdef i^ hex 'EE' // î stringdef t, hex '163' // ţ stringdef s, hex '15F' // ş define v 'aeiouy{a^}{ab}{i^}' //alle Vokalen der rumänischen Sprache /*die nicht-stemmbare Grenze eines Wortes festlegen; die später definierten Funktionen dürfen nur in einer bestimmten Sequenz eines Wortes operieren*/ define mark_regions as ( $p1 = limit //integer p1 $p2 = limit //integer p2 do( /*Wörter, die nicht gestemmt werden müssen; sie enden mit einer Sequenz, die in der Suffixliste zu finden ist; so vermeiden wir miss-stemming*/ among ( 'coral' 'moral' 'social' 'canal' 'final' 'papagal' 'special' 'tractor' 'abator' 'marar' 'declar' 'suf{ab}r' 'polonic' 'voinic' 'paravan' 'simultan' 'decan' 'decal' 'tiran' 'caracter' 'tiner' 'acoper' 'descoper' 'sufer' 'numer' 'orator' 'autor' 'exprim' 'prim' 'ultim' 'optim' 'victim' 'antonim' 'sinonim' 'adjectiv' 'conjunctiv' 'subjonctiv' 'substantiv' 'pozitiv' 'recidiv' 'infinitiv' 'complet' 'absolut' 'debut' 'debit' 'miros' 'dantel' 'nuvel' 'tutel' 'model' 'cercel' 'savant' 'ambulant' 'aparat' 'ar{ab}t' 'specific' 'critic' 'oribil' 'probabil' 'bine' 'feroce' 'atroce' // ... extensions possible here ... ) or (gopast v gopast non-v) setmark p1 /*p1 wird nach dem ersten Konsonanten, dem ein Vokal folgt festgelet */ gopast v gopast non-v setmark p2 /*nach dem ersten in r1 eines Vokals folgenden Konsonanten*/ ) ) /* die Ausnahmenliste, die entweder mit der Funktion, den Verb-Endungen oder den Nomen-Endungen konfligiert; die meisten Wörter sind allerdings stopp-wörter */ define exception1 as ( [substring] atlimit among ( 'cea' (<-'ce') 'cel' (<- 'ce') 'cei' (<- 'ce') 'celui'(<- 'ce') 'celei' (<- 'ce') 'celor' (<- 'ce') 'destul' 'astfel' 'altfel' 'asupra' 'deasupra' 'asemenea' 'afar{ab}' 'mai' 'nici' 'aici' 'apoi' 'musai' 'baremi' 'uneori' 'altminteri' 'deseori' 'numai'// adverbe cu forma invariabila '{i^}nt{a^}i' 'p{a^}n{ab}' 'dup{ab}' 'noi' 'voi' 'imi' 'i{t,}i' 'i{s,}i' 'cine' 'care' 'cui' 'ori' //pronumele cu mai mult de doua litere 'acest' 'pentru' 'sau' 'c{ab}tre' 'despre' 'spre' 'dinspre' 'dintre' 'printre' '{i^}ntre' 'devreme' 'aproape' 'departe' 'bine' 'feroce' 'atroce' 'exprim' 'prim' 'ultim' 'optim' 'victim' 'antonim' 'sinonim' 'fonem' 'extrem' 'poem' 'suprem' ) ) backwardmode ( define R1 as $p1 <= cursor //R1 stemmbare Zone des Wortes definieren define R2 as $p2 <= cursor //R2 stemmbare Zone des Wortes definieren /*Bestimmter-Artikel-Schema, nach Hristoiu: (-u-l), (-u-lui),-i-i, -i-lor -e-le, -e-lui, -e, -uri, -i, -u, -a -uri-le, uri-lor, -i-le, e-a, -e-i */ define morhological_suffixes as ( [substring] among ( 'ului' 'uri' 'urile' 'urilor' 'ul' (delete) 'le' ( ('a' or 'o' <- 'l') or delete) /*ein Wort oale(Töpfe) wird so nicht zum oa falsch gestemmt*/ 'lui' 'lor' 'elor' 'ilor' 'ele' 'ile' 'ei' 'i' 'ii' 'e' 'a' '{ab}' ( delete ) ) ) /* die Behandlung von Suffixe wird in zwei Schritten gemacht. Die erste Funktion enthält die Suffixe, die vor anderen erscheinen können. Zum Beispiel, -al kommt nie nach -ism, sondern umgekehrt- (internationalism) , usw. */ define deriv_suffixes1 as ( /* suche nach der längsten der folgenden Sequenzen, und wenn unter den gegebenen Bedingungen vorhanden, führe die Operation durch */ [substring] among ( 'ism' 'ist' 'i{s,}t' (R2 or R1 non-v delete) /*wenn in R1 oder R2 und vor einem Konsonanten */ 'iz' 'ant' '{ab}r' 'ar' /*wenn in R2 und vor einem Konsonanten */ (R2 non-v delete) 'tor' 'toar' 'abil' 'ibil' (R1 or R2 delete) /*wenn in R1 oder R2*/ 'ime' 'esc' ( delete) 'n{t,}' (R2 <- 'nt') /*wenn in R2 mit nt umsetzen*/ ) ) define deriv_suffixes2 as ( /* suche nach der längsten der folgenden Sequenzen, und wenn unter den gegebenen Bedingungen vorhanden, führe die Operation durch */ [substring] among ( '{ab}r' 'ar' (R1 or R2 non-v delete) /*wenn in R1 oder R2 und vor einem Konsonanten */ 'anie' 'icel' 'giu' 'eal' '{ab}tat' (R2 non-v delete) /*wenn in R2 und vor einem Konsonanten */ 'ulte{t,}' 'u{t,}' 'uc' 'u{s,}' 'el' 'oi' ( R1 delete) /*wenn in R1*/ 'ir' 'im' 'i{s,}' 'iz' 'iv' 'aj' 'an' 'ac' ( R1 or R2 non-v delete) /*wenn in R1 oder R2 und vor einem Konsonanten */ 'ic' (R2 or R1 delete) /*wenn in R1 oder R2*/ 'er' (R1 or R2 non-v or 'i' delete) /*wenn in R1 oder R2 und vor einem Konsonanten oder vor i */ 'os' 'o{s,}' 'oas' (('u' or 'i' or 'j' or 'r' or 'p') R1 delete) /*wenn vor u oder i oder j oder r oder p die sich in R1 befinden*/ 'ant' 'ean' 'liv' 'al' ( R1 or R2 delete) /*wenn in R1 oder R2*/ '{s,}or' '{s,}oar' (R1 or R2 v delete) /*wenn in R1 oder R2 und vor einem Vokal*/ ) ) /*die verb-spezifischen morphologischen Suffixe werden hier entfernt*/ define verb_suffix as ( [substring] among ( /*suche nach der längsten der folgenden Sequenzen, und wenn unter den gegebenen Bedingungen vorhanden, führe die Operation durch*/ 'eaz{ab}' 'eaza' 'ezi' 'ez' 'z{ab}' (R1 or R2 delete) 'esc' 'easc{ab}' 'e{s,}ti' 'e{s,}te' 'im' 'i{t,}i' (R1 or R2 delete) 'ai' 'a{s,}i' 'i{s,}i' 'am' '{ab}m' 'em' 'au' 'r{ab}m' 'ea' 'u' (R1 or R2 delete) '{t,}i' (R1 'a' 'e' 'i' 'u' delete) 'se' 'sei' 'se{s,}i' 'ser{ab}m' 'ser{ab}{t,}i' 'ser{ab}' 'r{ab}' (R1 or R2 delete) 'ind' '{i^}nd' '{a^}nd' (R1 or R2 delete) ) ) /*als letzter Schritt werden die Vokale entfernt, die im Derivationsprozess vorkommen können, z.B. munci vs. muncitor; oder der Partizipfall wird hier behandelt; die beiden Operationen schliessen sich gegenseitig aus, deswegen werden sie in eine Funktion gepackt; */ define residual_suffix as ( [substring] among ( 'a' '{ab}' 'e' 'u' 'i' (R1 or R2 non-v delete) /*wenn in R1 or R2 und vor einem Konsonant */ 'at' 'a{t,}' 'it' 'i{t,}' 'ut' 'u{t,}' (R2 or R1 delete) /*wenn in R1 or R2 */ ) ) ) /*die main-funktion*/ define stem as ( exception1 or /*wenn das Wort nicht in der Ausnahmeliste und vorkommt ...(siehe nächster Kommentar)*/ not hop 3 or ( /* länger als 2 Buchstaben ist*/ do mark_regions /*lege die nicht-stemmbare Region im Wort fest und...*/ backwards ( /*fange umgekehrt an, vom Ende des Wortes zum Anfang, die gegebenen Funktionen auszuführen*/ /*wenn das Wort ein Verb ist, dann entferne den entsprechenden Suffix, wie in der Funktion beschrieben; wenn keine Operation in verb_suffix zum Ausführen gefunden wird, führe morhological_suffixes wie definiert aus; */ do (verb_suffix or morhological_suffixes) do deriv_suffixes1 //führe die erste Funktion aus, die die Derivation behandelt do deriv_suffixes2 //führe die zweite Funktion aus, die die Derivation behandelt residual_suffix //führe residual_suffix aus ) ) )