diff --git a/src/phon.c b/src/phon.c index 32e0840..26f2d6b 100644 --- a/src/phon.c +++ b/src/phon.c @@ -33,7 +33,277 @@ static int p_match(const char* buffer, const char* target, long buffer_length) { return 1; } -#define FLAT +#define M(X) p_match(buffer + i, (X), length - i) +#define DEF(X) static int X(unsigned char* ph, int i, const char* buffer, long length, int first, int last, char b_c) + +DEF(p_gen_4) { + if(M("tion")) { + ph[i * MAX_PPL + 0] = P_SH; + ph[i * MAX_PPL + 1] = P_AH; + ph[i * MAX_PPL + 2] = P_N; + return 3; + } else if(M("sion")) { + ph[i * MAX_PPL + 0] = P_ZH; + ph[i * MAX_PPL + 1] = P_AH; + ph[i * MAX_PPL + 2] = P_N; + return 3; + } + + return -1; +} + +DEF(p_silent_e) { + if(M("a_e")) { + ph[i * MAX_PPL + 0] = P_EY; + + return 0; + } else if(M("i_e")) { + ph[i * MAX_PPL + 0] = P_AY; + + return 0; + } else if(M("o_e")) { + ph[i * MAX_PPL + 0] = P_OW; + + return 0; + } else if(M("u_e")) { + ph[i * MAX_PPL + 0] = P_Y; + ph[i * MAX_PPL + 1] = P_UW; + + return 0; + } + + return -1; +} + +DEF(p_special_2) { + if(M("ly") && last) { + ph[i * MAX_PPL + 0] = P_L; + ph[i * MAX_PPL + 1] = P_IY; + + return 1; + } else if(M("le") && last) { + ph[i * MAX_PPL + 0] = P_L; + ph[i * MAX_PPL + 1] = P_EH; + + return 1; + } + + return -1; +} + +DEF(p_gen_2) { + if(M("ll")) { + ph[i * MAX_PPL + 0] = P_L; + + return 1; + } else if(M("sh")) { + ph[i * MAX_PPL + 0] = P_SH; + + return 1; + } else if(M("ch")) { + ph[i * MAX_PPL + 0] = P_CH; + + return 1; + } else if(M("th")) { + ph[i * MAX_PPL + 0] = P_TH; + i++; + + return 1; + } else if(M("ph")) { + ph[i * MAX_PPL + 0] = P_F; + + return 1; + } else if(M("ng")) { + ph[i * MAX_PPL + 0] = P_NG; + + return 1; + } else if(M("wr")) { + ph[i * MAX_PPL + 0] = P_R; + + return 1; + } else if(M("kn") || M("gn")) { + ph[i * MAX_PPL + 0] = P_N; + + return 1; + } else if(M("ck")) { + ph[i * MAX_PPL + 0] = P_K; + + return 1; + } else if(M("wa")) { + ph[i * MAX_PPL + 0] = P_W; + ph[i * MAX_PPL + 1] = P_AE; + + return 1; + } else if(M("te")) { + ph[i * MAX_PPL + 0] = P_T; + ph[i * MAX_PPL + 1] = P_EH; + + return 1; + } else if(M("tt")) { + ph[i * MAX_PPL + 0] = P_T; + + return 1; + } + + return -1; +} + +DEF(p_vowel_2) { + if(M("ee") || M("ea")) { + ph[i * MAX_PPL + 0] = P_EY; + + return 1; + } else if(M("oo")) { + ph[i * MAX_PPL + 0] = P_UW; /* FIXME: could be P_UH */ + + return 1; + } else if(M("ou")) { + ph[i * MAX_PPL + 0] = P_AW; + + return 1; + } else if(M("ow")) { + ph[i * MAX_PPL + 0] = P_OW; + + return 1; + } else if(M("oi") || M("oy")) { + ph[i * MAX_PPL + 0] = P_OY; + + return 1; + } else if(M("ar")) { + ph[i * MAX_PPL + 0] = P_AA; + ph[i * MAX_PPL + 1] = P_R; + + return 1; + } else if(M("er") || M("ir") || M("ur")) { + ph[i * MAX_PPL + 0] = P_ER; + + return 1; + } else if(M("or")) { + ph[i * MAX_PPL + 0] = P_AO; + ph[i * MAX_PPL + 1] = P_R; + + return 1; + } + + return -1; +} + +DEF(p_soft) { + if(M("c")) { + if(b_c == 'e' || b_c == 'i' || b_c == 'y') { + ph[i * MAX_PPL + 0] = P_S; + } else { + ph[i * MAX_PPL + 0] = P_K; + } + + return 0; + } else if(M("g")) { + if(b_c == 'e' || b_c == 'i' || b_c == 'y') { + ph[i * MAX_PPL + 0] = P_JH; + } else { + ph[i * MAX_PPL + 0] = P_G; + } + + return 0; + } + + return -1; +} + +DEF(p_special_1) { + if(M("e") && last) { + return 0; + } else if(M("y") && first) { + ph[i * MAX_PPL + 0] = P_Y; + + return 0; + } else if(M("y") && last) { + ph[i * MAX_PPL + 0] = P_IY; + + return 0; + } else if(M("n") && last) { + ph[i * MAX_PPL + 0] = P_N; + + return 0; + } else if(M("k") && last) { + ph[i * MAX_PPL + 0] = P_K; + + return 0; + } + + return -1; +} + +DEF(p_gen_1) { + if(M("s")) { + ph[i * MAX_PPL + 0] = P_S; + + return 0; + } else if(M("f")) { + ph[i * MAX_PPL + 0] = P_F; + + return 0; + } else if(M("t")) { + ph[i * MAX_PPL + 0] = P_T; + + return 0; + } else if(M("p")) { + ph[i * MAX_PPL + 0] = P_P; + + return 0; + } else if(M("l")) { + ph[i * MAX_PPL + 0] = P_L; + + return 0; + } else if(M("m")) { + ph[i * MAX_PPL + 0] = P_M; + + return 0; + } else if(M("n")) { + ph[i * MAX_PPL + 0] = P_N; + + return 0; + } else if(M("d")) { + ph[i * MAX_PPL + 0] = P_D; + + return 0; + } else if(M("h")) { + ph[i * MAX_PPL + 0] = P_HH; + + return 0; + } + + return -1; +} + +DEF(p_vowel_1) { + if(M("a")) { + ph[i * MAX_PPL + 0] = P_AE; + + return 0; + } else if(M("e")) { + ph[i * MAX_PPL + 0] = P_EH; + + return 0; + } else if(M("i")) { + ph[i * MAX_PPL + 0] = P_IH; + + return 0; + } else if(M("o")) { + ph[i * MAX_PPL + 0] = P_AA; + + return 0; + } else if(M("u")) { + ph[i * MAX_PPL + 0] = P_AH; + + return 0; + } + + return -1; +} + +#undef DEF +#undef M void ft_phon_main(FT_HANDLE handle, const char* buffer, long length) { unsigned char* ph = malloc(length * MAX_PPL); @@ -45,6 +315,7 @@ void ft_phon_main(FT_HANDLE handle, const char* buffer, long length) { int first = 0; int last = 0; char b_c = (i > 0) ? buffer[i - 1] : 0; + int n; b_c = tolower(b_c); @@ -53,168 +324,20 @@ void ft_phon_main(FT_HANDLE handle, const char* buffer, long length) { if(ph[i * MAX_PPL]) continue; -#define M(X) p_match(buffer + i, (X), length - i) if(FT_IS_SKIPPABLE(buffer[i])) { ph[i * MAX_PPL + 0] = P_DOT; - } else if(M("tion")) { - /*** 4 letters ***/ - ph[i * MAX_PPL + 0] = P_SH; - ph[i * MAX_PPL + 1] = P_AH; - ph[i * MAX_PPL + 2] = P_N; - i += 3; - } else if(M("sion")) { - ph[i * MAX_PPL + 0] = P_ZH; - ph[i * MAX_PPL + 1] = P_AH; - ph[i * MAX_PPL + 2] = P_N; - i += 3; - /*** Silent-E ***/ - } else if(M("a_e")) { - ph[i * MAX_PPL + 0] = P_EY; - } else if(M("i_e")) { - ph[i * MAX_PPL + 0] = P_AY; - } else if(M("o_e")) { - ph[i * MAX_PPL + 0] = P_OW; - } else if(M("u_e")) { - ph[i * MAX_PPL + 0] = P_Y; - ph[i * MAX_PPL + 1] = P_UW; - /*** SH / CH / TH / PH / NG ***/ - } else if(M("sh")) { - ph[i * MAX_PPL + 0] = P_SH; - i++; - } else if(M("ch")) { - ph[i * MAX_PPL + 0] = P_CH; - i++; - } else if(M("th")) { - ph[i * MAX_PPL + 0] = P_TH; - i++; - } else if(M("ph")) { - ph[i * MAX_PPL + 0] = P_F; - i++; - } else if(M("ng")) { - ph[i * MAX_PPL + 0] = P_NG; - i++; - /*** WR / KN / GN ***/ - } else if(M("wr")) { - ph[i * MAX_PPL + 0] = P_R; - i++; - } else if(M("kn") || M("gn")) { - ph[i * MAX_PPL + 0] = P_N; - i++; - /*** CK ***/ - } else if(M("ck")) { - ph[i * MAX_PPL + 0] = P_K; - i++; - /*** EE/EA ***/ - } else if(M("ee") || M("ea")) { - ph[i * MAX_PPL + 0] = P_EY; - i++; - /*** OO ***/ - } else if(M("oo")) { - ph[i * MAX_PPL + 0] = P_UW; /* FIXME: could be P_UH */ - i++; - /*** OU/OW ***/ - } else if(M("ou")) { - ph[i * MAX_PPL + 0] = P_AW; - i++; - } else if(M("ow")) { - ph[i * MAX_PPL + 0] = P_OW; - i++; - /*** OI/OY ***/ - } else if(M("oi") || M("oy")) { - ph[i * MAX_PPL + 0] = P_OY; - i++; - /*** R-controlled vowels ***/ - } else if(M("ar")) { - ph[i * MAX_PPL + 0] = P_AA; - ph[i * MAX_PPL + 1] = P_R; - i++; - } else if(M("er") || M("ir") || M("ur")) { - ph[i * MAX_PPL + 0] = P_ER; - i++; - } else if(M("or")) { - ph[i * MAX_PPL + 0] = P_AO; - ph[i * MAX_PPL + 1] = P_R; - i++; - /*** Misc ***/ - } else if(M("wa")) { - ph[i * MAX_PPL + 0] = P_W; - ph[i * MAX_PPL + 1] = P_AE; - i++; - } else if(M("te")) { - ph[i * MAX_PPL + 0] = P_T; - ph[i * MAX_PPL + 1] = P_EH; - i++; - } else if(M("tt")) { - ph[i * MAX_PPL + 0] = P_T; - i++; - /*** Soft C ***/ - } else if(M("c")) { - if(b_c == 'e' || b_c == 'i' || b_c == 'y') { - ph[i * MAX_PPL + 0] = P_S; - } else { - ph[i * MAX_PPL + 0] = P_K; - } - /*** Soft G ***/ - } else if(M("g")) { - if(b_c == 'e' || b_c == 'i' || b_c == 'y') { - ph[i * MAX_PPL + 0] = P_JH; - } else { - ph[i * MAX_PPL + 0] = P_G; - } - /*** Misc ***/ - } else if(M("ly") && last) { - ph[i * MAX_PPL + 0] = P_L; - ph[i * MAX_PPL + 1] = P_IY; - i++; - } else if(M("le") && last) { - ph[i * MAX_PPL + 0] = P_L; - ph[i * MAX_PPL + 1] = P_EH; - i++; - /*** Final silent E ***/ - } else if(M("e") && last) { - /*** Y ***/ - } else if(M("y") && first) { - ph[i * MAX_PPL + 0] = P_Y; - } else if(M("y") && last) { - ph[i * MAX_PPL + 0] = P_IY; - /*** Misc ***/ - } else if(M("n") && last) { - ph[i * MAX_PPL + 0] = P_N; - } else if(M("k") && last) { - ph[i * MAX_PPL + 0] = P_K; - /*** Short vowels ***/ - } else if(M("a")) { - ph[i * MAX_PPL + 0] = P_AE; - } else if(M("e")) { - ph[i * MAX_PPL + 0] = P_EH; - } else if(M("i")) { - ph[i * MAX_PPL + 0] = P_IH; - } else if(M("o")) { - ph[i * MAX_PPL + 0] = P_AA; - } else if(M("u")) { - ph[i * MAX_PPL + 0] = P_AH; - /*** S voicing ***/ - } else if(M("s")) { - ph[i * MAX_PPL + 0] = P_S; - /*** Misc ***/ - } else if(M("f")) { - ph[i * MAX_PPL + 0] = P_F; - } else if(M("t")) { - ph[i * MAX_PPL + 0] = P_T; - } else if(M("p")) { - ph[i * MAX_PPL + 0] = P_P; - } else if(M("l")) { - ph[i * MAX_PPL + 0] = P_L; - } else if(M("m")) { - ph[i * MAX_PPL + 0] = P_M; - } else if(M("n")) { - ph[i * MAX_PPL + 0] = P_N; - } else if(M("d")) { - ph[i * MAX_PPL + 0] = P_D; - } else if(M("h")) { - ph[i * MAX_PPL + 0] = P_HH; + } else if((n = p_gen_4(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_silent_e(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_special_2(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_gen_2(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_vowel_2(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_soft(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_special_1(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_gen_1(ph, i, buffer, length, first, last, b_c)) != -1) { + } else if((n = p_vowel_1(ph, i, buffer, length, first, last, b_c)) != -1) { } -#undef M + + if(n != -1) i += n; } fprintf(stderr, "phoneme of \"");