head 1.13; access; symbols; locks; strict; comment @ * @; 1.13 date 94.03.12.00.24.45; author paul; state Exp; branches; next 1.12; 1.12 date 92.07.30.03.54.29; author paul; state Exp; branches; next 1.11; 1.11 date 92.07.29.04.41.04; author paul; state Exp; branches; next 1.10; 1.10 date 92.07.29.03.37.36; author paul; state Exp; branches; next 1.9; 1.9 date 92.07.27.16.00.08; author paul; state Exp; branches; next 1.8; 1.8 date 92.07.27.15.47.15; author paul; state Exp; branches; next 1.7; 1.7 date 90.12.18.08.41.38; author dorner; state Exp; branches; next 1.6; 1.6 date 89.03.20.15.14.56; author dorner; state Exp; branches; next 1.5; 1.5 date 88.12.02.14.45.35; author dorner; state Exp; branches; next 1.4; 1.4 date 88.11.15.13.35.33; author dorner; state Exp; branches; next 1.3; 1.3 date 88.04.19.08.11.50; author dorner; state Exp; branches; next 1.2; 1.2 date 88.04.04.15.16.13; author dorner; state Exp; branches; next 1.1; 1.1 date 88.04.04.14.40.37; author dorner; state Exp; branches; next ; desc @@ 1.13 log @Added new copyright statement. @ text @/* * Copyright (c) 1985 Corporation for Research and Educational Networking * Copyright (c) 1988 University of Illinois Board of Trustees, Steven * Dorner, and Paul Pomes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Corporation for * Research and Educational Networking (CREN), the University of * Illinois at Urbana, and their contributors. * 4. Neither the name of CREN, the University nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char RcsId[] = "@@(#)$Id$"; #endif #include "protos.h" /* * English to Phoneme translation. * * Rules are made up of four parts: * * The left context. * The text to match. * The right context. * The phonemes to substitute for the matched text. * * Procedure: * * Seperate each block of letters (apostrophes included) * and add a space on each side. For each unmatched * letter in the word, look through the rules where the * text to match starts with the letter in the word. If * the text to match is found and the right and left * context patterns also match, output the phonemes for * that rule and skip to the next unmatched letter. * * * Special Context Symbols: * * # One or more vowels * : Zero or more consonants * ^ One consonant. * . One of B, D, V, G, J, L, M, N, R, W or Z (voiced * consonants) * % One of ER, E, ES, ED, ING, ELY (a suffix) * (Right context only) * + One of E, I or Y (a "front" vowel) */ #ifndef TRUE #define FALSE (0) #define TRUE (!0) #endif typedef char *Rule[4]; /* A rule is four character pointers */ extern Rule *rules[]; /* An array of pointers to rules */ static char *xlate_word __P((char *)); static int find_rule __P((char *, int, Rule *, char **)); static int leftmatch __P((char *, char *)); static int rightmatch __P((char *, char *)); #define isvowel(chr) \ (chr=='A' || chr=='E' || chr=='I' || chr=='Y' || chr=='O' || chr=='U') #define isconsonant(chr) (islower(chr) && !isvowel(chr)) char * phonemify(word) char *word; { char scratch[80]; register char *cp; *scratch = ' '; for (cp = scratch + 1; *word; word++) { if (isupper(*word)) *word = tolower(*word); if (!isconsonant(*word) || *word != *(cp - 1)) *cp++ = *word; } *cp++ = ' '; *cp = '\0'; return (xlate_word(scratch)); } static char * xlate_word(word) char word[]; { int indx; /* Current position in word */ int type; /* First letter of match part */ static char phonetics[1024]; char *phoneme; phonetics[0] = 0; indx = 1; /* Skip the initial blank */ do { if (islower(word[indx])) type = word[indx] - 'a' + 1; else type = 0; indx = find_rule(word, indx, rules[type], &phoneme); if (phoneme) (void) strcat(phonetics, phoneme); } while (word[indx] != '\0'); return (phonetics); } static int find_rule(word, indx, rules, phoneme) char word[]; int indx; Rule *rules; char **phoneme; { Rule *rule; char *left, *match, *right; int remainder; *phoneme = NULL; for (;;) /* Search for the rule */ { rule = rules++; match = (*rule)[1]; if (match == 0) /* bad symbol! */ { /* fprintf(stderr, */ /* * "Error: Can't find rule for: '%c' in \"%s\"\n", word[indx], * word); */ return indx + 1; /* Skip it! */ } for (remainder = indx; *match != '\0'; match++, remainder++) { if (*match != word[remainder]) break; } if (*match != '\0') /* found missmatch */ continue; /* * printf("\nWord: \"%s\", Index:%4d, Trying: \"%s/%s/%s\" = * \"%s\"\n", */ /* word, indx, (*rule)[0], (*rule)[1], (*rule)[2], (*rule)[3]); */ left = (*rule)[0]; right = (*rule)[2]; if (!leftmatch(left, &word[indx - 1])) continue; /* * printf("leftmatch(\"%s\",\"...%c\") succeded!\n", left, * word[indx-1]); */ if (!rightmatch(right, &word[remainder])) continue; /* * printf("rightmatch(\"%s\",\"%s\") succeded!\n", right, * &word[remainder]); */ *phoneme = (*rule)[3]; /* * printf("Success: "); */ /* outstring(output); */ return remainder; } } static int leftmatch(pattern, context) char *pattern, *context; { char *pat; char *text; int count; if (*pattern == '\0') /* null string matches any context */ { return TRUE; } /* point to last character in pattern string */ count = strlen(pattern); pat = pattern + (count - 1); text = context; for (; count > 0; pat--, count--) { /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text--; continue; } switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; text--; while (isvowel(*text)) text--; break; case ':': /* Zero or more consonants */ while (isconsonant(*text)) text--; break; case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text--; break; case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; text--; break; case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; text--; break; case '%': default: /* fprintf(stderr, "Bad char in left rule: '%c'\n", *pat); */ return FALSE; } } return TRUE; } static int rightmatch(pattern, context) char *pattern, *context; { char *pat; char *text; if (*pattern == '\0') /* null string matches any context */ return TRUE; pat = pattern; text = context; for (pat = pattern; *pat != '\0'; pat++) { /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text++; continue; } switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; text++; while (isvowel(*text)) text++; break; case ':': /* Zero or more consonants */ while (isconsonant(*text)) text++; break; case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text++; break; case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; text++; break; case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; text++; break; case '%': /* ER, E, ES, ED, ING, ELY (a suffix) */ if (*text == 'E') { text++; if (*text == 'L') { text++; if (*text == 'Y') { text++; break; } else { text--; /* Don't gobble L */ break; } } else if (*text == 'R' || *text == 'S' || *text == 'D') text++; break; } else if (*text == 'I') { text++; if (*text == 'N') { text++; if (*text == 'G') { text++; break; } } return FALSE; } else return FALSE; default: /* fprintf(stderr, "Bad char in right rule:'%c'\n", *pat); */ return FALSE; } } return TRUE; } @ 1.12 log @*** empty log message *** @ text @d1 40 @ 1.11 log @Revised #include file list. @ text @d36 1 d39 1 @ 1.10 log @Deleted #include in favor of one in qi.h. @ text @a0 2 #include #include a1 2 #include "conf.h" #include "qi.h" a2 3 #define FALSE (0) #define TRUE (!0) d4 1 a4 8 * * English to Phoneme translation. * * * rules are made up of four parts: * * * The left context. * The text to match. * The right context. * * The phonemes to substitute for the matched text. * * * Procedure: * d6 28 a33 14 * Seperate each block of letters (apostrophes included) * and add a * space on each side. For each unmatched * letter in the word, look * through the rules where the * text to match starts with the letter * in the word. If * the text to match is found and the right and left * * context patterns also match, output the phonemes for * that rule and * skip to the next unmatched letter. * * * * Special Context Symbols: * * * # One or more vowels * : Zero or more consonants * ^ * One consonant. * . One of B, D, V, G, J, L, M, N, R, W or Z (voiced * * consonants) * % One of ER, E, ES, ED, ING, ELY (a suffix) * * (Right context only) * + One of E, I or Y (a "front" vowel) d35 3 @ 1.9 log @*** empty log message *** @ text @d1 2 d5 1 a5 3 #include #include #include @ 1.8 log @Last Dorner changes. @ text @d36 1 a36 1 typedef char *Rule[4]; /* A rule is four character pointers */ d38 1 a38 1 extern Rule *rules[]; /* An array of pointers to rules */ d40 5 a48 4 char *xlate_word(char *word); int find_rule(char *word,int index,Rule *rules,char **phoneme); int leftmatch(char *pattern,char *context); int rightmatch(char *pattern,char *context); d50 3 a52 1 char *phonemify(char *word) d54 15 a68 16 char scratch[80]; register char *cp; char *xlate_word(); *scratch = ' '; for (cp = scratch + 1; *word; word++) { if (isupper(*word)) *word = tolower(*word); if (!isconsonant(*word) || *word != *(cp - 1)) *cp++ = *word; } *cp++ = ' '; *cp = '\0'; return (xlate_word(scratch)); d71 3 a73 1 char *xlate_word(char word[]) d75 20 a94 20 int index; /* Current position in word */ int type; /* First letter of match part */ static char phonetics[1024]; char *phoneme; phonetics[0] = 0; index = 1; /* Skip the initial blank */ do { if (islower(word[index])) type = word[index] - 'a' + 1; else type = 0; index = find_rule(word, index, rules[type], &phoneme); if (phoneme) strcat(phonetics, phoneme); } while (word[index] != '\0'); return (phonetics); d97 6 a102 1 int find_rule(char word[],int index,Rule *rules,char **phoneme) d104 55 a158 56 Rule *rule; char *left, *match, *right; int remainder; *phoneme = NULL; for (;;) /* Search for the rule */ { rule = rules++; match = (*rule)[1]; if (match == 0) /* bad symbol! */ { /* fprintf(stderr, */ /* * "Error: Can't find rule for: '%c' in \"%s\"\n", word[index], * word); */ return index + 1; /* Skip it! */ } for (remainder = index; *match != '\0'; match++, remainder++) { if (*match != word[remainder]) break; } if (*match != '\0') /* found missmatch */ continue; /* * printf("\nWord: \"%s\", Index:%4d, Trying: \"%s/%s/%s\" = * \"%s\"\n", */ /* word, index, (*rule)[0], (*rule)[1], (*rule)[2], (*rule)[3]); */ left = (*rule)[0]; right = (*rule)[2]; if (!leftmatch(left, &word[index - 1])) continue; /* * printf("leftmatch(\"%s\",\"...%c\") succeded!\n", left, * word[index-1]); */ if (!rightmatch(right, &word[remainder])) continue; /* * printf("rightmatch(\"%s\",\"%s\") succeded!\n", right, * &word[remainder]); */ *phoneme = (*rule)[3]; /* * printf("Success: "); */ /* outstring(output); */ return remainder; } d162 3 a164 1 int leftmatch(char *pattern,char *context) d166 13 a178 71 char *pat; char *text; int count; if (*pattern == '\0') /* null string matches any context */ { return TRUE; } /* point to last character in pattern string */ count = strlen(pattern); pat = pattern + (count - 1); text = context; for (; count > 0; pat--, count--) { /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text--; continue; } switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; text--; while (isvowel(*text)) text--; break; case ':': /* Zero or more consonants */ while (isconsonant(*text)) text--; break; case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text--; break; case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; text--; break; case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; text--; break; case '%': default: /* fprintf(stderr, "Bad char in left rule: '%c'\n", *pat); */ return FALSE; } } d180 57 a236 1 return TRUE; d240 3 a242 1 int rightmatch(char *pattern,char *context) d244 2 a245 2 char *pat; char *text; d247 2 a248 2 if (*pattern == '\0') /* null string matches any context */ return TRUE; d250 2 a251 2 pat = pattern; text = context; d253 1 a253 79 for (pat = pattern; *pat != '\0'; pat++) { /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text++; continue; } switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; text++; while (isvowel(*text)) text++; break; case ':': /* Zero or more consonants */ while (isconsonant(*text)) text++; break; case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text++; break; case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; text++; break; case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; text++; break; case '%': /* ER, E, ES, ED, ING, ELY (a suffix) */ if (*text == 'E') { text++; if (*text == 'L') { text++; if (*text == 'Y') { text++; break; } else { text--; /* Don't gobble L */ break; } } else if (*text == 'R' || *text == 'S' || *text == 'D') text++; break; } else if (*text == 'I') { text++; if (*text == 'N') d255 87 a341 6 text++; if (*text == 'G') { text++; break; } a342 10 return FALSE; } else return FALSE; default: /* fprintf(stderr, "Bad char in right rule:'%c'\n", *pat); */ return FALSE; } } d344 1 a344 1 return TRUE; @ 1.7 log @No help here. @ text @d2 1 @ 1.6 log @No help here. @ text @d1 1 d43 4 d48 1 a48 3 char * phonemify(word) register char *word; d68 1 a68 4 char * xlate_word(word) char word[]; d92 1 a92 6 find_rule(word, index, rules, phoneme) char word[]; int index; Rule *rules; char **phoneme; d153 1 a153 3 leftmatch(pattern, context) char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ d231 1 a231 3 rightmatch(pattern, context) char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ @ 1.5 log @No help here. @ text @a0 6 /*********************************************************************** * This software is Copyright (C) 1988 by Steven Dorner and the University * of Illinois Board of Trustees. No warranties expressed or implied, no * support provided. Please do not redistribute it in its present form. * Contact me for details (dorner@@garcon.cso.uiuc.edu). ***********************************************************************/ @ 1.4 log @No help here. @ text @d9 1 d19 1 a19 1 * The left context. * The text to match. * The right context. * d24 5 a28 5 * Seperate each block of letters (apostrophes included) * and add a * space on each side. For each unmatched * letter in the word, look * through the rules where the * text to match starts with the letter * in the word. If * the text to match is found and the right and left * * context patterns also match, output the phonemes for * that rule and d34 4 a37 4 * # One or more vowels * : Zero or more consonants * ^ * One consonant. * . One of B, D, V, G, J, L, M, N, R, W or Z (voiced * * consonants) * % One of ER, E, ES, ED, ING, ELY (a suffix) * * (Right context only) * + One of E, I or Y (a "front" vowel) d40 1 a40 1 typedef char *Rule[4]; /* A rule is four character pointers */ d42 1 a42 1 extern Rule *rules[]; /* An array of pointers to rules */ d44 2 a45 2 #define isvowel(chr) \ (chr=='A' || chr=='E' || chr=='I' || chr=='Y' || chr=='O' || chr=='U') d47 1 a47 1 #define isconsonant(chr) (islower(chr) && !isvowel(chr)) d53 3 a55 3 char scratch[80]; register char *cp; char *xlate_word(); d57 5 a61 5 *scratch = ' '; for (cp = scratch + 1; *word; word++) { if (isupper(*word)) *word = tolower(*word); d63 6 a68 6 if (!isconsonant(*word) || *word != *(cp - 1)) *cp++ = *word; } *cp++ = ' '; *cp = '\0'; return (xlate_word(scratch)); d73 1 a73 1 char word[]; d76 4 a79 4 int index; /* Current position in word */ int type; /* First letter of match part */ static char phonetics[1024]; char *phoneme; d81 8 a88 8 phonetics[0] = 0; index = 1; /* Skip the initial blank */ do { if (islower(word[index])) type = word[index] - 'a' + 1; else type = 0; d90 6 a95 6 index = find_rule(word, index, rules[type], &phoneme); if (phoneme) strcat(phonetics, phoneme); } while (word[index] != '\0'); return (phonetics); d99 2 a100 2 char word[]; int index; d105 3 a107 3 Rule *rule; char *left, *match, *right; int remainder; d109 1 a109 1 *phoneme = NULL; d111 6 a116 1 for (;;) /* Search for the rule */ d118 7 a124 2 rule = rules++; match = (*rule)[1]; d126 5 a130 9 if (match == 0) /* bad symbol! */ { /* fprintf(stderr, */ /* * "Error: Can't find rule for: '%c' in \"%s\"\n", word[index], * word); */ return index + 1; /* Skip it! */ } d132 9 a140 5 for (remainder = index; *match != '\0'; match++, remainder++) { if (*match != word[remainder]) break; } d142 19 a160 29 if (*match != '\0') /* found missmatch */ continue; /* * printf("\nWord: \"%s\", Index:%4d, Trying: \"%s/%s/%s\" = * \"%s\"\n", */ /* word, index, (*rule)[0], (*rule)[1], (*rule)[2], (*rule)[3]); */ left = (*rule)[0]; right = (*rule)[2]; if (!leftmatch(left, &word[index - 1])) continue; /* * printf("leftmatch(\"%s\",\"...%c\") succeded!\n", left, * word[index-1]); */ if (!rightmatch(right, &word[remainder])) continue; /* * printf("rightmatch(\"%s\",\"%s\") succeded!\n", right, * &word[remainder]); */ *phoneme = (*rule)[3]; /* * printf("Success: "); */ /* outstring(output); */ return remainder; } d165 2 a166 2 char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ d168 3 a170 3 char *pat; char *text; int count; d172 4 a175 4 if (*pattern == '\0') /* null string matches any context */ { return TRUE; } d177 3 a179 3 /* point to last character in pattern string */ count = strlen(pattern); pat = pattern + (count - 1); d181 1 a181 1 text = context; d183 13 a195 1 for (; count > 0; pat--, count--) d197 3 a199 9 /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text--; continue; } d201 1 a201 5 switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; d203 3 a205 1 text--; d207 4 a210 3 while (isvowel(*text)) text--; break; d212 5 a216 4 case ':': /* Zero or more consonants */ while (isconsonant(*text)) text--; break; d218 8 a225 5 case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text--; break; d227 5 a231 8 case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; text--; break; d233 4 a236 11 case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; text--; break; case '%': default: /* fprintf(stderr, "Bad char in left rule: '%c'\n", *pat); */ return FALSE; } d238 1 d240 1 a240 1 return TRUE; d245 2 a246 2 char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ d248 2 a249 2 char *pat; char *text; d251 2 a252 2 if (*pattern == '\0') /* null string matches any context */ return TRUE; d254 2 a255 2 pat = pattern; text = context; d257 13 a269 1 for (pat = pattern; *pat != '\0'; pat++) d271 3 a273 9 /* First check for simple text or space */ if (isalpha(*pat) || *pat == '\'' || *pat == ' ') if (*pat != *text) return FALSE; else { text++; continue; } d275 1 a275 5 switch (*pat) { case '#': /* One or more vowels */ if (!isvowel(*text)) return FALSE; d277 3 a279 1 text++; d281 4 a284 3 while (isvowel(*text)) text++; break; d286 5 a290 4 case ':': /* Zero or more consonants */ while (isconsonant(*text)) text++; break; d292 8 a299 5 case '^': /* One consonant */ if (!isconsonant(*text)) return FALSE; text++; break; d301 15 a315 6 case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ if (*text != 'B' && *text != 'D' && *text != 'V' && *text != 'G' && *text != 'J' && *text != 'L' && *text != 'M' && *text != 'N' && *text != 'R' && *text != 'W' && *text != 'Z') return FALSE; d318 22 a339 4 case '+': /* E, I or Y (front vowel) */ if (*text != 'E' && *text != 'I' && *text != 'Y') return FALSE; d342 6 d349 3 a351 46 case '%': /* ER, E, ES, ED, ING, ELY (a suffix) */ if (*text == 'E') { text++; if (*text == 'L') { text++; if (*text == 'Y') { text++; break; } else { text--; /* Don't gobble L */ break; } } else if (*text == 'R' || *text == 'S' || *text == 'D') text++; break; } else if (*text == 'I') { text++; if (*text == 'N') { text++; if (*text == 'G') { text++; break; } } return FALSE; } else return FALSE; default: /* fprintf(stderr, "Bad char in right rule:'%c'\n", *pat); */ return FALSE; } d353 1 d355 1 a355 1 return TRUE; @ 1.3 log @*** empty log message *** @ text @d1 6 @ 1.2 log @*** empty log message *** @ text @d8 24 a31 31 ** English to Phoneme translation. ** ** rules are made up of four parts: ** ** The left context. ** The text to match. ** The right context. ** The phonemes to substitute for the matched text. ** ** Procedure: ** ** Seperate each block of letters (apostrophes included) ** and add a space on each side. For each unmatched ** letter in the word, look through the rules where the ** text to match starts with the letter in the word. If ** the text to match is found and the right and left ** context patterns also match, output the phonemes for ** that rule and skip to the next unmatched letter. ** ** ** Special Context Symbols: ** ** # One or more vowels ** : Zero or more consonants ** ^ One consonant. ** . One of B, D, V, G, J, L, M, N, R, W or Z (voiced ** consonants) ** % One of ER, E, ES, ED, ING, ELY (a suffix) ** (Right context only) ** + One of E, I or Y (a "front" vowel) */ d33 1 a33 1 typedef char *Rule[4]; /* A rule is four character pointers */ d35 1 a35 1 extern Rule *rules[]; /* An array of pointers to rules */ d42 1 a42 1 char * d46 1 a46 1 char scratch[80]; d48 1 a48 1 char *xlate_word(); d50 2 a51 2 *scratch=' '; for (cp=scratch+1;*word;word++) d54 1 a54 1 *word=tolower(*word); d56 1 a56 1 if (!isconsonant(*word) || *word != *(cp-1)) d61 1 a61 1 return(xlate_word(scratch)); d64 1 a64 1 char * d66 2 a67 1 char word[]; d69 2 a70 2 int index; /* Current position in word */ int type; /* First letter of match part */ d72 1 a72 1 char **phoneme; d75 1 a75 1 index = 1; /* Skip the initial blank */ d77 1 a77 1 { d83 3 a85 2 index = find_rule(word, index, rules[type],&phoneme); if (phoneme) strcat(phonetics,phoneme); d88 1 a88 1 return(phonetics); d92 5 a96 4 char word[]; int index; Rule *rules; char **phoneme; d98 3 a100 3 Rule *rule; char *left, *match, *right, *output; int remainder; d104 1 a104 1 for (;;) /* Search for the rule */ d109 1 a109 1 if (match == 0) /* bad symbol! */ d111 6 a116 3 /*fprintf(stderr,*/ /*"Error: Can't find rule for: '%c' in \"%s\"\n", word[index], word);*/ return index+1; /* Skip it! */ d125 1 a125 1 if (*match != '\0') /* found missmatch */ d127 5 a131 2 /*printf("\nWord: \"%s\", Index:%4d, Trying: \"%s/%s/%s\" = \"%s\"\n",*/ /*word, index, (*rule)[0], (*rule)[1], (*rule)[2], (*rule)[3]);*/ d135 1 a135 1 if (!leftmatch(left, &word[index-1])) d138 3 a140 2 printf("leftmatch(\"%s\",\"...%c\") succeded!\n", left, word[index-1]); */ d144 3 a146 1 printf("rightmatch(\"%s\",\"%s\") succeded!\n", right, &word[remainder]); */ d149 3 a151 3 printf("Success: "); */ /*outstring(output);*/ d158 2 a159 2 char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ d161 3 a163 3 char *pat; char *text; int count; d165 1 a165 1 if (*pattern == '\0') /* null string matches any context */ d190 1 a190 1 case '#': /* One or more vowels */ d200 1 a200 1 case ':': /* Zero or more consonants */ d205 1 a205 1 case '^': /* One consonant */ d211 1 a211 1 case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ d220 1 a220 1 case '+': /* E, I or Y (front vowel) */ d226 3 a228 3 case '%': default: /*fprintf(stderr, "Bad char in left rule: '%c'\n", *pat);*/ d238 2 a239 2 char *pattern; /* first char of pattern to match in text */ char *context; /* last char of text to be matched */ d241 2 a242 2 char *pat; char *text; d244 1 a244 1 if (*pattern == '\0') /* null string matches any context */ d264 1 a264 1 case '#': /* One or more vowels */ d274 1 a274 1 case ':': /* Zero or more consonants */ d279 1 a279 1 case '^': /* One consonant */ d285 1 a285 1 case '.': /* B, D, V, G, J, L, M, N, R, W, Z */ d294 1 a294 1 case '+': /* E, I or Y (front vowel) */ d300 1 a300 1 case '%': /* ER, E, ES, ED, ING, ELY (a suffix) */ d314 1 a314 1 text--; /* Don't gobble L */ d319 1 a319 1 if (*text == 'R' || *text == 'S' d321 1 a321 1 text++; d325 4 a328 1 if (*text == 'I') d331 1 a331 1 if (*text == 'N') d334 1 a334 5 if (*text == 'G') { text++; break; } a335 1 return FALSE; d337 4 a340 2 else return FALSE; d342 2 a343 2 default: /*fprintf(stderr, "Bad char in right rule:'%c'\n", *pat);*/ a349 1 @ 1.1 log @Initial revision @ text @d10 1 a10 1 ** Rules are made up of four parts: d42 1 a42 1 extern Rule *Rules[]; /* An array of pointers to rules */ d47 1 a47 1 #define isconsonant(chr) (isupper(chr) && !isvowel(chr)) d60 2 a61 2 if (islower(*word)) *word=toupper(*word); d84 2 a85 2 if (isupper(word[index])) type = word[index] - 'A' + 1; d89 1 a89 1 index = find_rule(word, index, Rules[type],&phoneme); @