一种较为精细化区分广府话同音字的语音推导方案

来自个人维基
跳转到导航 跳转到搜索
/* 一种较为精细化区分广府话同音字的语音推导方案
 * 版本号:903.2.46-2
 *
 * 改编自切韵音系自动推导器“推導廣州話.js”
 * 原作者:@三日月綾香
 *
 */
 
if (!音韻地位) return [['标注声调', true]];
 
/** @type { 音韻地位["屬於"] } */
const is = (...x) => 音韻地位.屬於(...x);
/** @type { 音韻地位["判斷"] } */
const when = (...x) => 音韻地位.判斷(...x);
 
if (is`云母 通攝 舒聲`) 音韻地位 = 音韻地位.調整('匣母', ['匣母三等']); 
 
function 聲母規則() {
  return when([
    ['幫滂並母 C類', 'f'],
    ['幫母 或 並母 仄聲', 'b'],
    ['滂母 或 並母 平聲', 'p'],
    ['明母', [['C類 非 東尤韻', 'v'], ['', 'm']]],
 
    ['端母 或 定母 仄聲', 'd'],
    ['透母 或 定母 平聲', 't'],
    ['泥母', 'n'],
    ['來母', 'l'],
 
    ['知母 或 澄母 仄聲', 'dr'],
    ['徹母 或 澄母 平聲', 'tr'],
    ['孃母', 'r'],
 
    ['精母 或 從邪母 仄聲', 'z'], // 精莊組濁音塞擦音多於擦音(下同)
    ['清母 或 從邪母 平聲', 'c'],
    ['心母', 's'],
 
    ['莊母 或 崇俟母 仄聲', 'zh'],
    ['初母 或 崇俟母 平聲', 'ch'],
    ['生母', 'sh'],
 
    ['章母', 'zj'], 
    ['昌母', 'cj'],
    ['常書船母', 'sj'], // 章組濁音擦音多於塞擦音
    ['日母', 'nj'],
 
    ['見母 或 羣母 仄聲', 'g'],
    ['羣母 平聲', 'k'],
    ['疑母', 'ng'], // 細音為 nj,詳後
 
    ['溪母', 'kh'],
    ['曉母', 'h'], // 溪曉母三四等拼 a 元音部分韻母時為 (k)hj/(k)hw,詳後
    ['匣母', [
      ['合口 或 模韻 或 三等', 'j'], // 拼展脣或後元音時為 hw,詳後
      ['', 'h'],
    ]],
    ['影云以母', [
      ['三四等', 'j'], // 拼展脣或後元音時為 w,詳後
      ['', ''],
    ]],
  ], '無聲母規則');
}
 
function 韻母規則() {
  return when([
  // 通攝
  ['通攝', 'ung'],
 
  // 止攝
  ['止攝', [
    ['脣音', 'ei'],
    ['開口 (端組 或 孃來母 或 見溪羣曉匣母)', 'ei'],
    ['開口', 'i'],
    ['合口', [['舌齒音', 'eoi'], ['牙喉音', 'ai']]],
  ]],
 
  // 遇攝
  ['魚虞韻', [
    ['幫滂並母', 'u'],
    ['明母', 'ou'],
    ['莊組', 'o'],
    ['端精組 或 孃來母 或 見溪羣曉匣母', 'eoi'],
    ['', 'yu'],
  ]],
  ['模韻', [
    ['脣音 或 舌齒音', 'ou'],
    ['疑母', ''],
    ['牙喉音', 'u'],
  ]],
 
  // 蟹攝
  ['蟹攝', [
    ['廢韻 平上聲 章組', 'oi'], // 參照「茝」coi2
    ['合口 銳音', 'eoi'],
    ['三四等', 'ai'],
    ['佳韻', 'ae'],
    ['二等 或 泰韻 開口 (端組 或 來母)', 'aai'],
    ['一等', [
      ['開口 或 疑母', 'oi'],
      ['', 'ui'],
    ]],
  ]],
 
  // 臻攝
  ['真韻 合口 舌齒音', 'eon'],
  ['真臻文殷韻', 'an'],
  ['魂韻', [
    ['幫組', 'un'],
    ['端組 或 來母', 'eon'],
    ['精組', 'yun'],
    ['牙喉音', 'an'],
  ]],
  ['痕韻', 'en'],
 
  // 山攝
  ['寒韻', [
    ['幫組 或 合口 牙喉音', 'un'],
    ['開口 牙喉音', 'on'],
    ['舌齒音', [['開口', 'aan'], ['合口', 'yun']]],
  ]],
  ['山韻', 'aen'],
  ['刪韻 或 元韻 幫組', 'aan'],
  ['仙先韻 幫組', 'in'],
  ['元仙先韻', [['開口', 'in'], ['合口', 'yun']]],
 
  // 效流攝
  ['蕭韻', 'eu'],
  ['宵韻', 'iu'],
  ['肴韻', 'aau'],
  ['豪韻', 'ou'],
  ['幽韻 幫滂並母 或 尤幽韻 端組', 'iu'], // 「彪」「淲」「丟」
  ['流攝', 'au'],
 
   // 果假攝
  ['果假攝', [
    ['三四等', [
      ['脣音 C類', 'o'],
      ['開口 或 脣音', 'e'],
      ['合口', 'oe'],
    ]],
    ['二等', 'aa'],
    ['一等', 'o'],
  ]],
 
  // 宕江攝
  ['陽韻', [
    ['脣音 C類 或 開口 莊組 或 合口', 'ong'],
    ['', 'oeng'],
  ]],
  ['唐韻 開口', 'oeng'],
  ['唐韻', 'ong'], 
  ['江韻', 'oang'], 
 
  // 梗曾攝
  ['庚韻 (二等 或 三等 莊組)', 'aang'],
  ['耕韻', 'aeng'],
  ['梗攝 三四等', [
    ['合口', 'eong'],
    ['', 'ing'],
  ]],
  ['蒸韻', [['合口', 'oeng'], ['', 'eng']]],
  ['登韻', [['合口', 'ong'], ['', 'ang']]],
 
  // 深咸攝
  ['深攝', 'am'], // -m 拼脣音時為 -n,詳後,下同
  ['咸攝', [
    ['咸韻', 'aem'],
    ['二等 或 脣音 C類', 'aam'],
    ['三等', 'im'],
    ['四等', 'em'],
    ['一等 脣舌齒音', 'aam'], // 脣音僅僻字,如「姏」maan4
    ['一等 牙喉音', 'om'], // -om 併入 -am,但影響陰入分化,詳後
  ]],
], '無韻母規則');
}
 
function 聲調規則() {
  return when([
    ['清音', [
      ['平聲', '1'],
      ['上聲', '2'],
      ['去入聲', '3'], // 清音短元音為 1,濁音短元音為 4,詳後
    ]],
    ['濁音', [
      ['平聲', '4'],
      ['上聲 次濁', '5'],
      ['上聲 全濁 或 去入聲', '6'],
    ]]
  ], '無聲調規則');
}
 
function is短元音(韻母) {
  if (['am', 'an', 'ang', 'aem', 'aen', 'aeng', 'eon', 'eong', 'ing', 'ung'].includes(韻母)) return true;
  if (['aam', 'aan', 'aang', 'em', 'en', 'eng', 'im', 'in', 'om', 'on', 'ong', 'oang', 'oeng', 'un', 'yun'].includes(韻母)) return false;
  throw new Error('無長短元音規則:' + 韻母);
}
 
let 聲母 = 聲母規則();
let 韻母 = 韻母規則();
let 聲調 = 聲調規則();
 
// i 在 z/c/s(h) 前為 ii
if (['z', 'c', 's', 'zh', 'ch', 'sh'].includes(聲母) && 韻母 === 'i') 韻母 = 'ii';
 
// g/k/h 二等開口字加 j 介音
if (['g', 'k', 'kh', 'h'].includes(聲母) && is('二等 開口')) 聲母 = 聲母 + 'j';
 
// ng 拼細音時為 nj
const is細音 = ['eo', 'i', 'oe', 'u', 'yu'].some((x) => 韻母.startsWith(x));
if (聲母 === 'ng' && is細音) 聲母 = 'nj';
 
// 三四等清調 h 拼 a 元音部分韻母時為 hj/w
if (聲母 === 'h' && ['au', 'an', 'am'].includes(韻母) && is`清音 三四等 非 (臻攝 開口 入聲) 非 (臻攝 合口 舒聲)`) {
  聲母 = 'hj';
}
if (聲母 === 'kh' && ['au', 'an', 'am'].includes(韻母) && is`清音 三四等 非 (臻攝 開口 入聲) 非 (臻攝 合口 舒聲)`) {
  聲母 = 'khj';
}
 
// 陰入分化
if (is('入聲') && 聲調 === '1' && is短元音(韻母)) 聲調 = '3';
if (is('入聲') && 聲調 === '4' && is短元音(韻母)) 聲調 = '6';
 
if (is('合口 或 模韻') && !['eo', 'oe', 'yu'].some((x) => 韻母.startsWith(x))) { // 合口字
  if (聲母 === 'g' && !韻母.startsWith('u')) 聲母 = 'gw';
  else if (聲母 === 'k' && !韻母.startsWith('u')) 聲母 = 'kw';
  else if (聲母 === 'kh' && !韻母.startsWith('u')) 聲母 = 'khw';
  else if (聲母 === 'h' && !韻母.startsWith('i')) 聲母 = 'f';
  else if (聲母 === 'khj') 聲母 = 'khw';
  else if (聲母 === 'hj') 聲母 = 'hw';
  else if (聲母 === 'j') 聲母 = 'w';
  else if (聲母 === '') 聲母 = 'w';
}
 
// zj/cj/sj/gj/kj/hj在與 i/yu 韻腹相拼時抵消 j
if (['zj', 'cj', 'sj', 'gj', 'kj', 'khj', 'hj'].includes(聲母) && ['i', 'yu'].some((x) => 韻母.startsWith(x))) 聲母 = 聲母.slice(0, -1);
 
if (is('入聲')) {
  if (韻母.endsWith('m')) 韻母 = 韻母.slice(0, -1) + 'p';
  else if (韻母.endsWith('n')) 韻母 = 韻母.slice(0, -1) + 't';
  else if (韻母.endsWith('ng')) 韻母 = 韻母.slice(0, -2) + 'k';
}
 
// 一些特殊字
if (字頭 === '不') 聲母 = 'b';
if (字頭 === '打') 韻母 = 'aa';
if ('鳥鸟'.includes(字頭)) 聲母 = 'n';
if ('他她它祂它牠'.includes(字頭)) 韻母 = 'aa';
if ('这這'.includes(字頭)) {聲母 = 'zj'; 韻母 = 'e';}
if (字頭 === '那') 韻母 = 'aa';
 
if (選項.标注声调) return 聲母 + 韻母 + 聲調;
if (!選項.标注声调) return 聲母 + 韻母;