📄 pronounce.c
字号:
* generate a random one. If we know it has to be a * vowel, we get one rather than looping through until * one shows up. */ if (/* We have only one letter left and need a vowel */ (length_left == 1 && vowel_count == 0) /* We have two consonants, next must be vowel */ || (unit_ptr >= 2 && !((rules[state->units[unit_ptr-2]].flags | rules[last_unit].flags) & VOWEL))) next_vowel = VOWEL; else next_vowel = NO_SPECIAL_RULE; unit = random_unit (next_vowel); new_length_left = length_left - (Int16) StrLen (rules[unit].unit_code); /* * Prevent having a word longer than expected. */ if (new_length_left < 0) goto retry_unit; /* Always check for illegal pairs, triple vocals and triple * consonants */ if (unit_ptr > 0 && (digram[last_unit][unit] & ILLEGAL_PAIR)) goto retry_unit; if (unit_ptr >= 2) { if ((rules[unit].flags & VOWEL) && (rules[last_unit].flags & VOWEL) && (rules[state->units[unit_ptr-2]].flags & (VOWEL | ALTERNATE_VOWEL)) == VOWEL) goto retry_unit; } /* Reject syllables ending with a single e and containing no * other syllables */ if (new_length_left == 0 && vowel_count == 0 && (rules[unit].flags & NO_FINAL_SPLIT)) goto retry_unit; /* * First unit of syllable. This is special because the * digram tests require 2 units and we don't have that * yet. Nevertheless, we can perform some checks. */ if (syll_length == 0) { /* * If the shouldn't begin a syllable, don't use it. */ if (rules[unit].flags & NOT_BEGIN_SYLLABLE) goto retry_unit; } else { /* * There are some digram tests that are universally * true. We test them out. */ flags = digram[last_unit][unit]; /* * Reject units that will be split between * syllables when the syllable has no vowels in * it. */ if ((flags & BREAK) && (vowel_count == 0)) goto retry_unit; /* * Reject a unit that will end a syllable when * no previous unit was a vowel and neither is * this one. */ if ((flags & END) && (vowel_count == 0) && !(rules[unit].flags & VOWEL)) goto retry_unit; /* * If this is the last unit of a word, we * should reject any digram that cannot end * a syllable. */ if (new_length_left == 0 && (flags & NOT_END)) goto retry_unit; if (syll_length == 1) { /* * Reject the unit if we are at the starting * digram of a syllable and it does not fit. */ if ((flags & NOT_BEGIN)) goto retry_unit; } else { /* * Do not allow syllables where the first letter * is y and the next pair can begin a syllable. * This may lead to splits where y is left alone * in a syllable. Also, the combination does * not sound to good even if not split. */ if (((syll_length == 2) && ((flags & BEGIN)) && (rules[state->units[0]].flags & ALTERNATE_VOWEL))) goto retry_unit; /* * Reject the unit if the digram it forms * wants to break the syllable, but the * resulting digram that would end the * syllable is not allowed to end a * syllable. */ if ((flags & BREAK) && (last_flags & NOT_END)) goto retry_unit; /* * Reject the unit if the digram it forms * expects a vowel preceding it and there is * none. */ if ((flags & PREFIX) && !(rules[state->units [unit_ptr - 2]].flags & VOWEL)) goto retry_unit; /* * The following checks occur when the current * unit is a vowel and we are not looking at a * word ending with an e. */ if ((vowel_count != 0) && (rules[unit].flags & VOWEL) && !(rules[last_unit].flags & VOWEL)) { /* * Check for the case of * vowels-consonants-vowel, which is only * legal if the last vowel is an e and we * are the end of the word (wich is not * happening here due to a previous check. */ if (new_length_left > 0 || !(rules[last_unit].flags & NO_FINAL_SPLIT)) { /* * Try to save the vowel for the next * syllable, but if the syllable left * here is not proper (i.e. the * resulting last digram cannot * legally end it), just discard it * and try for another. */ if ((last_flags & NOT_END)) goto retry_unit; saved_unit = 1; state->units[unit_ptr] = unit; break; } } } /* * The unit picked and the digram formed are legal. * We now determine if we can end the syllable. It * may, in some cases, mean the last unit(s) may be * deferred to the next syllable. We also check * here to see if the digram formed expects a vowel * to follow. */ /* * Since we have a vowel in the syllable * already, if the digram calls for the end of * the syllable, we can legally split it * off. We also make sure that we are not at * the end of the dangerous because that * syllable may not have vowels, or it may not * be a legal syllable end, and the retrying * mechanism will loop infinitely with the * same digram. */ if ((vowel_count != 0) && (new_length_left > 0)) { /* * If we must begin a syllable, we do so if * the only vowel in THIS syllable is not * part of the digram we are pushing to the * next syllable. */ if ((flags & BEGIN) && (syll_length > 1) && !((vowel_count == 1) && (rules[last_unit].flags & VOWEL))) { saved_unit = 2; state->units[unit_ptr] = unit; /* remove last_unit from current syllable. */ syll_length--; unit_ptr--; break; } else if ((flags & BREAK)) { saved_unit = 1; state->units[unit_ptr] = unit; break; } } } /* * If the unit is a vowel, count it in. However, if * the unit is a y and appears at the start of the * syllable, treat it like a consonant (so that words * like year can appear and not conflict with the 3 * consecutive vowel rule. */ if ((rules[unit].flags & VOWEL) && ((syll_length > 0) || !(rules[unit].flags & ALTERNATE_VOWEL))) vowel_count++; /* * Append the unit to the syllable and update length_left, * syll_length and last_unit. */ state->units[unit_ptr] = unit; syll_length++; unit_ptr++; length_left = new_length_left; last_unit = unit; last_flags = flags; if ((flags & END)) break; } /* Create the textual form of the syllable */ while (state->unit_length < unit_ptr) StrCat(syllable, rules[state->units[state->unit_length++]].unit_code); state->unit_length = unit_ptr; state->saved_units = saved_unit; return;}/* * local variables: * mode: c * c-basic-offset: 4 * eval: (c-set-offset 'substatement-open 0) * end: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -