UNPKG

taipa

Version:

Taiwanese morphological parsing library

292 lines 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TonalSoundChangingMorphemeMaker = exports.TonalCombiningMorphemeMaker = exports.TonalSoundChangingMorpheme = exports.TonalCombiningMorpheme = void 0; const unit_1 = require("../unit"); const maker_1 = require("../maker"); const morpheme_1 = require("../unchange/morpheme"); const unit_2 = require("../unchange/unit"); const tonalres_1 = require("../tonal/tonalres"); const unit_3 = require("../unit"); const collections_1 = require("../tonal/collections"); /** A syllable and its combining forms. */ class TonalCombiningMorpheme extends unit_1.Morpheme { syllable; allomorph; // required to populate stems metaplasm; sounds; forms; constructor(syllable, sounds, metaplasm) { super(); this.syllable = syllable; this.metaplasm = metaplasm; // assign allomorph for each syllable this.allomorph = this.assignAllomorph(this.syllable); this.sounds = sounds; this.forms = this.metaplasm.apply(this.sounds, this.allomorph); } getForms() { return this.forms; } isAy() { if (this.sounds[this.sounds.length - 1].toString() === tonalres_1.TonalLetterTags.y && this.sounds[this.sounds.length - 2].toString() === tonalres_1.TonalLetterTags.a) return true; return false; } assignAllomorph(syllable) { if (tonalres_1.uncombinedCheckedAllomorphs.has(syllable.lastLetter.literal)) { const am = tonalres_1.uncombinedCheckedAllomorphs.get(syllable.lastLetter.literal); if (am) return am; return new tonalres_1.Allomorph(); } if (tonalres_1.checkedToneLettersTonal.includes(syllable.lastLetter.literal) && (tonalres_1.uncombinedCheckedAllomorphs.has(syllable.lastSecondLetter.literal) || collections_1.finalConsonantsForBgjlsbbggjjllss.has(syllable.lastSecondLetter.literal))) { // in case of a final followed by a tonal const ams = tonalres_1.combinedCheckedAllomorphs.get(syllable.lastSecondLetter.literal + syllable.lastLetter.literal); if (ams && ams.length > 0) { const ret = ams.filter((it) => it.tonal.toString() === syllable.lastLetter.literal); return ret[0]; } return new tonalres_1.Allomorph(); } if (tonalres_1.combinedFreeAllomorphs.has(syllable.lastLetter.literal)) { const am = tonalres_1.combinedFreeAllomorphs.get(syllable.lastLetter.literal); if (am) return am; return new tonalres_1.Allomorph(); // return empty allomorph } return new tonalres_1.ZeroAllomorph(); } } exports.TonalCombiningMorpheme = TonalCombiningMorpheme; /** A syllable and its sound changing forms. */ class TonalSoundChangingMorpheme extends unit_1.Morpheme { syllable; sounds; constructor(syllable, sounds) { super(); this.syllable = syllable; this.sounds = sounds; } get lastSecondLetter() { return this.sounds[this.sounds.length - 2].toString(); } insertNasal(sound) { if (sound) { if (sound.name === tonalres_1.TonalSpellingTags.nasalFinalConsonant) { // insertion of nasals, both internal and external sandhi const ltrs = this.sounds; ltrs.splice(0, 0, sound); return [ new unit_2.TonalSyllable(ltrs.map((x) => new unit_3.AlphabeticLetter(x.characters))), ]; } } return []; } infect() { const n = tonalres_1.nasalizationsTonal.sounds[0]; if (n) { if (n.name === tonalres_1.TonalSpellingTags.nasalization) { const snds = this.sounds; if (snds[snds.length - 1].name === tonalres_1.TonalSpellingTags.freeTone) { snds.splice(snds.length - 1, 0, n); } else if (snds[snds.length - 1].name === tonalres_1.TonalSpellingTags.vowel) { snds.push(n); } return [ new unit_2.TonalSyllable(snds.map((x) => new unit_3.AlphabeticLetter(x.characters))), ]; } } return []; } /** Mutate initial consonants. */ mutateInitialConsonant(sound) { if (sound) { if (sound.name === tonalres_1.TonalSpellingTags.initialConsonant) { const snds = this.sounds; if (snds[0].toString() === sound.toString()) { const s = new unit_2.TonalSyllable(this.sounds.map((it) => new unit_3.AlphabeticLetter(it.characters))); s.replaceLetter(0, tonalres_1.lowerLettersTonal.get(tonalres_1.TonalLetterTags.l)); return [s]; } return [ new unit_2.TonalSyllable(snds.map((x) => new unit_3.AlphabeticLetter(x.characters))), ]; } } return []; } mutateFinalConsonant(sound) { if (sound) { const snds = this.sounds; const syl = new unit_2.TonalSyllable(this.sounds.map((i) => new unit_3.AlphabeticLetter(i.characters))); const idx = snds.findIndex((i) => i.name === tonalres_1.TonalSpellingTags.stopFinalConsonant); syl.replaceLetter(idx, tonalres_1.lowerLettersTonal.get(tonalres_1.TonalLetterTags.gg)); return [syl]; } return []; } changeFinalTTt(initial) { // absolute assimilation, except for t or tt followed by j. regressive if ((this.sounds[this.sounds.length - 2].toString() === tonalres_1.TonalLetterTags.tt && Object.values(collections_1.initialConsonantsForTT).includes(initial.toString())) || (this.sounds[this.sounds.length - 2].toString() === tonalres_1.TonalLetterTags.t && Object.values(collections_1.initialConsonantsForFinalT).includes(initial.toString()))) { const s = new unit_2.TonalSyllable(this.sounds.map((it) => new unit_3.AlphabeticLetter(it.characters))); let fnl = collections_1.ttInitialTInitialPairs.get(this.sounds[this.sounds.length - 2].toString() + initial.toString()); if (!fnl && initial.toString() === tonalres_1.TonalLetterTags.j) { // this block is dedicated to -tfj- and -twj-, since there is only -jfj- but not -jwj- fnl = collections_1.ttInitialTInitialPairs.get(this.sounds[this.sounds.length - 2].toString() + this.sounds[this.sounds.length - 1] + initial.toString()); } if (fnl) { s.replaceLetter(s.letters.length - 2, tonalres_1.lowerLettersTonal.get(fnl)); if (collections_1.nasalInitialConsonants.includes(initial.toString())) { s.insertLetter(s.letters.length - 2, new unit_3.AlphabeticLetter(initial.characters)); } return [s]; } } return []; } changeFinalHHh(initial) { // TODO: mutate consonants hh and h. return []; } changeFinalPPp(initial) { // TODO: neutrals. pp -> hh. p -> h. return []; } changeWithInitialMnng(initial) { if (initial.name === tonalres_1.TonalSpellingTags.initialConsonant && collections_1.nasalInitialConsonants.includes(initial.toString())) { return this.voicedFinal(); } return []; } changeWithMedial(medial) { if (medial.name === tonalres_1.TonalSpellingTags.vowel && tonalres_1.vowelsTonal.includes(medial.toString())) { return this.voicedFinal(); } return []; } changeWithInitialBghjl(initial) { if (initial.name === tonalres_1.TonalSpellingTags.initialConsonant && collections_1.initialConsonantsBghjl.includes(initial.toString())) { return this.voicedFinal(); } return []; } /** * Change a final with the beginning letter of the following syllable * @param beginning Beginning letter of the following syllable */ changeFinalPtkppttkk(beginning) { const sandhiTTt = this.changeFinalTTt(beginning); if (sandhiTTt.length > 0) return sandhiTTt; const sandhiHHh = this.changeFinalHHh(beginning); if (sandhiHHh.length > 0) return sandhiHHh; const sandhiPPp = this.changeFinalPPp(beginning); if (sandhiPPp.length > 0) return sandhiPPp; const voicedWithMnng = this.changeWithInitialMnng(beginning); if (voicedWithMnng.length > 0) return voicedWithMnng; const voicedWithMedial = this.changeWithMedial(beginning); if (voicedWithMedial.length > 0) return voicedWithMedial; const voicedWithBghjl = this.changeWithInitialBghjl(beginning); if (voicedWithBghjl.length > 0) return voicedWithBghjl; } changeFinalN(initial) { if (this.sounds[this.sounds.length - 2].name != tonalres_1.TonalSpellingTags.stopFinalConsonant && this.sounds[this.sounds.length - 2].name != tonalres_1.TonalSpellingTags.nasalFinalConsonant) { return []; } if (initial.toString() === tonalres_1.TonalLetterTags.b && this.sounds[this.sounds.length - 2].toString() === tonalres_1.TonalLetterTags.n) { // replace final n with final m const s = new unit_2.TonalSyllable(this.sounds.map((it) => new unit_3.AlphabeticLetter(it.characters))); s.replaceLetter(s.letters.length - 2, tonalres_1.lowerLettersTonal.get(tonalres_1.TonalLetterTags.m)); return [s]; } return []; } voicedFinal() { const fnl = collections_1.voicelessVoicedFinalConsonants.get(this.sounds[this.sounds.length - 2].toString()); if (fnl) { const s = new unit_2.TonalSyllable(this.sounds.map((it) => new unit_3.AlphabeticLetter(it.characters))); s.replaceLetter(s.letters.length - 2, tonalres_1.lowerLettersTonal.get(fnl)); return [s]; } return []; } } exports.TonalSoundChangingMorpheme = TonalSoundChangingMorpheme; class TonalCombiningMorphemeMaker extends maker_1.MorphemeMaker { metaplasm; constructor(metaplasm) { super(); this.metaplasm = metaplasm; } createArray() { return new Array(); } createMorpheme(matched) { const tcm = new TonalCombiningMorpheme(new unit_2.TonalSyllable(matched.letters), matched.pattern, this.metaplasm); return tcm; } postprocess(patterns) { let morphemes = this.createArray(); for (let i in patterns) { morphemes.push(this.createMorpheme(patterns[i])); } return morphemes; } makeMorphemes(graphemes) { const ltrs = graphemes.map((it) => it.letter); const ptrns = this.make(ltrs, morpheme_1.syllabifyTonal); const ms = this.postprocess(ptrns); return ms; } } exports.TonalCombiningMorphemeMaker = TonalCombiningMorphemeMaker; class TonalSoundChangingMorphemeMaker extends maker_1.MorphemeMaker { constructor() { super(); } createArray() { return new Array(); } createMorpheme(match) { const tcm = new TonalSoundChangingMorpheme(new unit_2.TonalSyllable(match.letters), match.pattern); return tcm; } postprocess(matches) { const morphemes = this.createArray(); for (let i in matches) { morphemes.push(this.createMorpheme(matches[i])); } return morphemes; } makeMorphemes(graphemes) { const ltrs = graphemes.map((it) => it.letter); const ptrns = this.make(ltrs, morpheme_1.syllabifyTonal); const ms = this.postprocess(ptrns); return ms; } } exports.TonalSoundChangingMorphemeMaker = TonalSoundChangingMorphemeMaker; //# sourceMappingURL=morpheme.js.map