Inflectible.php
1 month ago
InflectorFactory.php
1 month ago
Rules.php
1 month ago
Uninflected.php
1 month ago
Inflectible.php
96 lines
| 1 | <?php |
| 2 | |
| 3 | declare (strict_types=1); |
| 4 | namespace IAWPSCOPED\Doctrine\Inflector\Rules\Italian; |
| 5 | |
| 6 | use IAWPSCOPED\Doctrine\Inflector\Rules\Pattern; |
| 7 | use IAWPSCOPED\Doctrine\Inflector\Rules\Substitution; |
| 8 | use IAWPSCOPED\Doctrine\Inflector\Rules\Transformation; |
| 9 | use IAWPSCOPED\Doctrine\Inflector\Rules\Word; |
| 10 | /** @internal */ |
| 11 | class Inflectible |
| 12 | { |
| 13 | /** @return iterable<Transformation> */ |
| 14 | public static function getSingular() : iterable |
| 15 | { |
| 16 | // Reverse of -sce → -scia (fasce → fascia) |
| 17 | (yield new Transformation(new Pattern('([aeiou])sce$'), '\\1scia')); |
| 18 | // Reverse of -cie → -cia (farmacia → farmacie) |
| 19 | (yield new Transformation(new Pattern('cie$'), 'cia')); |
| 20 | // Reverse of -gie → -gia (bugia → bugie) |
| 21 | (yield new Transformation(new Pattern('gie$'), 'gia')); |
| 22 | // Reverse of -ce → -cia (arance → arancia) |
| 23 | (yield new Transformation(new Pattern('([^aeiou])ce$'), '\\1cia')); |
| 24 | // Reverse of -ge → -gia (valige → valigia) |
| 25 | (yield new Transformation(new Pattern('([^aeiou])ge$'), '\\1gia')); |
| 26 | // Reverse of -chi → -co (bachi → baco) |
| 27 | (yield new Transformation(new Pattern('([bcdfghjklmnpqrstvwxyz][aeiou])chi$'), '\\1co')); |
| 28 | // Reverse of -ghi → -go (laghi → lago) |
| 29 | (yield new Transformation(new Pattern('([bcdfghjklmnpqrstvwxyz][aeiou])ghi$'), '\\1go')); |
| 30 | // Reverse of -ci → -co (medici → medico) |
| 31 | (yield new Transformation(new Pattern('([aeiou][bcdfghjklmnpqrstvwxyz])ci$'), '\\1co')); |
| 32 | // Reverse of -gi → -go (psicologi → psicologo) |
| 33 | (yield new Transformation(new Pattern('([aeiou][bcdfghjklmnpqrstvwxyz])gi$'), '\\1go')); |
| 34 | // Reverse of -i → -io (zii → zio, negozi → negozio) |
| 35 | // This is more complex due to Italian's stress patterns, but we'll handle the basic case |
| 36 | (yield new Transformation(new Pattern('([^aeiou])i$'), '\\1io')); |
| 37 | // Handle words that end with -i but should go to -co/-go (amici → amico, not amice) |
| 38 | (yield new Transformation(new Pattern('([^aeiou])ci$'), '\\1co')); |
| 39 | (yield new Transformation(new Pattern('([^aeiou])gi$'), '\\1go')); |
| 40 | // Reverse of -a → -e |
| 41 | (yield new Transformation(new Pattern('e$'), 'a')); |
| 42 | // Reverse of -e → -i |
| 43 | (yield new Transformation(new Pattern('i$'), 'e')); |
| 44 | // Reverse of -o → -i |
| 45 | (yield new Transformation(new Pattern('i$'), 'o')); |
| 46 | } |
| 47 | /** @return iterable<Transformation> */ |
| 48 | public static function getPlural() : iterable |
| 49 | { |
| 50 | // Words ending in -scia without stress on 'i' become -sce (e.g. fascia → fasce) |
| 51 | (yield new Transformation(new Pattern('([aeiou])scia$'), '\\1sce')); |
| 52 | // Words ending in -cia/gia with stress on 'i' keep the 'i' in plural |
| 53 | (yield new Transformation(new Pattern('cia$'), 'cie')); |
| 54 | // e.g. farmacia → farmacie |
| 55 | (yield new Transformation(new Pattern('gia$'), 'gie')); |
| 56 | // e.g. bugia → bugie |
| 57 | // Words ending in -cia/gia without stress on 'i' lose the 'i' in plural |
| 58 | (yield new Transformation(new Pattern('([^aeiou])cia$'), '\\1ce')); |
| 59 | // e.g. arancia → arance |
| 60 | (yield new Transformation(new Pattern('([^aeiou])gia$'), '\\1ge')); |
| 61 | // e.g. valigia → valige |
| 62 | // Words ending in -co/-go with stress on 'o' become -chi/-ghi |
| 63 | (yield new Transformation(new Pattern('([bcdfghjklmnpqrstvwxyz][aeiou])co$'), '\\1chi')); |
| 64 | // e.g. baco → bachi |
| 65 | (yield new Transformation(new Pattern('([bcdfghjklmnpqrstvwxyz][aeiou])go$'), '\\1ghi')); |
| 66 | // e.g. lago → laghi |
| 67 | // Words ending in -co/-go with stress on the penultimate syllable become -ci/-gi |
| 68 | (yield new Transformation(new Pattern('([aeiou][bcdfghjklmnpqrstvwxyz])co$'), '\\1ci')); |
| 69 | // e.g. medico → medici |
| 70 | (yield new Transformation(new Pattern('([aeiou][bcdfghjklmnpqrstvwxyz])go$'), '\\1gi')); |
| 71 | // e.g. psicologo → psicologi |
| 72 | // Words ending in -io with stress on 'i' keep the 'i' in plural |
| 73 | (yield new Transformation(new Pattern('([^aeiou])io$'), '\\1i')); |
| 74 | // e.g. zio → zii |
| 75 | // Words ending in -io with stress on 'o' lose the 'i' in plural |
| 76 | (yield new Transformation(new Pattern('([aeiou])io$'), '\\1i')); |
| 77 | // e.g. negozio → negozi |
| 78 | // Standard ending rules |
| 79 | (yield new Transformation(new Pattern('a$'), 'e')); |
| 80 | // -a → -e |
| 81 | (yield new Transformation(new Pattern('e$'), 'i')); |
| 82 | // -e → -i |
| 83 | (yield new Transformation(new Pattern('o$'), 'i')); |
| 84 | // -o → -i |
| 85 | } |
| 86 | /** @return iterable<Substitution> */ |
| 87 | public static function getIrregular() : iterable |
| 88 | { |
| 89 | // Irregular substitutions (singular => plural) |
| 90 | $irregulars = ['ala' => 'ali', 'albergo' => 'alberghi', 'amica' => 'amiche', 'amico' => 'amici', 'ampio' => 'ampi', 'arancia' => 'arance', 'arma' => 'armi', 'asparago' => 'asparagi', 'banca' => 'banche', 'belga' => 'belgi', 'braccio' => 'braccia', 'budello' => 'budella', 'bue' => 'buoi', 'caccia' => 'cacce', 'calcagno' => 'calcagna', 'camicia' => 'camicie', 'cane' => 'cani', 'capitale' => 'capitali', 'carcere' => 'carceri', 'casa' => 'case', 'cavaliere' => 'cavalieri', 'centinaio' => 'centinaia', 'cerchio' => 'cerchia', 'cervello' => 'cervella', 'chiave' => 'chiavi', 'chirurgo' => 'chirurgi', 'ciglio' => 'ciglia', 'città' => 'città', 'corno' => 'corna', 'corpo' => 'corpi', 'crisi' => 'crisi', 'dente' => 'denti', 'dio' => 'dei', 'dito' => 'dita', 'dottore' => 'dottori', 'fiore' => 'fiori', 'fratello' => 'fratelli', 'fuoco' => 'fuochi', 'gamba' => 'gambe', 'ginocchio' => 'ginocchia', 'gioco' => 'giochi', 'giornale' => 'giornali', 'giraffa' => 'giraffe', 'labbro' => 'labbra', 'lenzuolo' => 'lenzuola', 'libro' => 'libri', 'madre' => 'madri', 'maestro' => 'maestri', 'magico' => 'magici', 'mago' => 'maghi', 'maniaco' => 'maniaci', 'manico' => 'manici', 'mano' => 'mani', 'medico' => 'medici', 'membro' => 'membri', 'metropoli' => 'metropoli', 'migliaio' => 'migliaia', 'miglio' => 'miglia', 'mille' => 'mila', 'mio' => 'miei', 'moglie' => 'mogli', 'mosaico' => 'mosaici', 'muro' => 'muri', 'nemico' => 'nemici', 'nome' => 'nomi', 'occhio' => 'occhi', 'orecchio' => 'orecchi', 'osso' => 'ossa', 'paio' => 'paia', 'pane' => 'pani', 'papa' => 'papi', 'pasta' => 'paste', 'penna' => 'penne', 'pesce' => 'pesci', 'piede' => 'piedi', 'pittore' => 'pittori', 'poeta' => 'poeti', 'porco' => 'porci', 'porto' => 'porti', 'problema' => 'problemi', 'ragazzo' => 'ragazzi', 're' => 're', 'rene' => 'reni', 'riso' => 'risa', 'rosa' => 'rosa', 'sale' => 'sali', 'sarto' => 'sarti', 'scuola' => 'scuole', 'serie' => 'serie', 'serramento' => 'serramenta', 'sorella' => 'sorelle', 'specie' => 'specie', 'staio' => 'staia', 'stazione' => 'stazioni', 'strido' => 'strida', 'strillo' => 'strilla', 'studio' => 'studi', 'suo' => 'suoi', 'superficie' => 'superfici', 'tavolo' => 'tavoli', 'tempio' => 'templi', 'treno' => 'treni', 'tuo' => 'tuoi', 'uomo' => 'uomini', 'uovo' => 'uova', 'urlo' => 'urla', 'valigia' => 'valigie', 'vestigio' => 'vestigia', 'vino' => 'vini', 'viola' => 'viola', 'zio' => 'zii']; |
| 91 | foreach ($irregulars as $singular => $plural) { |
| 92 | (yield new Substitution(new Word($singular), new Word($plural))); |
| 93 | } |
| 94 | } |
| 95 | } |
| 96 |