人造語翻譯系統
作者:陳鍾誠
我設計《人造語》主要是受到《世界語、道本語、邏輯語、新加坡式英語》等語言的影響。
我中學時最困擾的事情就是背英文單字,於是我總是想,如果不需要背單字的話,那會有多好!
等到我學了電腦程式,發現電腦最會的就是《記憶》,目前 4GB 的記憶體,可以輕鬆地記住《幾千萬個單字》。
那麼、我們可不可以《人機結合》,人類只要用自己熟悉的語言講出符合《人造語》語法的語句,剩下的事情就交給電腦來翻譯就行了。
於是我設計了 AL0 人造語言的語法和翻譯系統!
人造語 AL0 的語法
AL0 的 BNF 語法
S = Q? NP* (VP)* .
VP = VP (c VP)* | (v* V+ v*)+ NP*
NP = NP (c NP)* | (n* N+)
詞性說明
S : 語句 NP : 名詞子句 VP : 動詞子句
Q : 疑問詞 V : 動詞 N : 名詞
c : 連接詞 v : 動詞修飾詞 n : 名詞修飾詞
剖析範例
小明 有 5 個 蘋果 , 給 了 小華 3 個 蘋果 , 請問 他 還 剩 幾 個 蘋果 ?
NP V n NP V v NP n NP Q NP v V n NP
VP VP VP
執行結果
PS D:\ccc\book\aijs\code\07-language\almt> node almt0
======= 中文 =============
小明 有 5 個 蘋果 , 給 了 小華 3 個 蘋果 , 請問 他 還 剩 幾 個 蘋果 ?
======= 剖析 =============
小明:N 有:V 5:n 個:n 蘋果:N ,:.
給:V 了:v 小華:N 3:n 個:n 蘋果:N ,:.
請問:Q 他:N 還:v 剩:V 幾:n 個:n 蘋果:N ?:.
======= 英文 =============
ShaoMin have 5 _ge apple , give _le ShaoHua 3 _ge apple , Q he still own _gi _ge apple ?
======= 中文 =============
小明 和 小華 一起 吃 蘋果 。
======= 剖析 =============
小明:N 和:c 小華:N 一起:v 吃:V 蘋果:N 。:.
======= 英文 =============
ShaoMin and ShaoHua together eat apple 。
======= 中文 =============
風 與 日 。 風 日 爭 , 旅人 至 , 脫 者 勝 , 風 狂 吹 , 人 緊 衣 , 風 敗 , 日
暖 照 , 人 脫 衣 , 日 勝 。
======= 剖析 =============
風:N 與:c 日:N 。:.
風:N 日:N 爭:V ,:.
旅人:N 至:V ,:.
脫:V 者:N 勝:V ,:.
風:N 狂:V 吹:V ,:.
人:N 緊:V 衣:N ,:.
風:N 敗:V ,:.
日:N 暖:V 照:V ,:.
人:N 脫:V 衣:N ,:.
日:N 勝:V 。:.
======= 英文 =============
wind and3 sun 。 wind sun argue , travler come , take_off guy win , wind wild blow , people tighten cloth , wind lose , sun warm shine , people take_off cloth , sun win 。
======= 中文 =============
黑 黑 的 天 , 大 大 的 風 , 爸爸 去 捕 魚 , 為甚麼 還 不 回 家 ?
======= 剖析 =============
黑:n 黑:n 的:n 天:N ,:.
大:n 大:n 的:n 風:N ,:.
爸爸:N 去:V 捕:V 魚:N ,:.
為甚麼:Q 還:v 不:v 回:V 家:N ?:.
======= 英文 =============
black black _de sky , big big _de wind , Papa go hunt fish , why still not back home ?
======= 中文 =============
黑 黑 天 , 大 大 風 ,
======= 剖析 =============
黑:n 黑:n 天:N ,:.
大:n 大:n 風:N ,:.
======= 英文 =============
black black sky , big big wind ,
======= 中文 =============
天 黑 黑 , 風 大 大 ,
======= 剖析 =============
天:N 黑:n 黑:n ,:N
==> 錯誤: , 不具有 N 詞性!
==> 這語句不合法!
======= 中文 =============
天 黑 黑 的 , 風 大 大 的,
======= 剖析 =============
天:N 黑:n 黑:n 的:n ,:N
==> 錯誤: , 不具有 N 詞性!
==> 這語句不合法!
程式 : almt0.js
// S = Q? NP* (VP)* .
// VP = VP (c VP)* | (v* V+ v*)+ NP*
// NP = NP (c NP)* | (n* N+)
// 小明 有 5 個 蘋果 , 給 了 小華 3 個 蘋果 , 請問 他 還 剩 幾 個 蘋果 ?
// NP V n NP V v NP n NP Q NP v V n NP
// VP VP VP
var c = console;
var tagMap={
N : ["小明", "小華", "小莉", "大雄", "爸爸", "魚", "天", "家", "風", "日", "旅人", "人", "衣", "者",
"他", "你", "我",
"蘋果", "橘子", "柳丁", "番茄"],
V : ["有", "給", "剩", "吃", "去", "捕", "回", "至", "爭", "勝", "吹", "抓", "緊", "敗", "勝", "照", "脫", "狂", "暖"],
v : ["還", "了", "一起", "不"],
c : ["又", "和", "且", "或", "與"],
n : ["幾", "這", "那", "5", "3", "個", "隻", "條", "黑", "大", "的"],
Q : ["請問", "為甚麼", "誰", "甚麼", "何時", "如何", "哪裡"],
"." : [",", "?", "。"]
}
var mtMap = {
"小明":"ShaoMin", "小華":"ShaoHua", "小莉":"ShaoLi", "大雄":"DaShon",
"他":"he", "你":"you", "我":"me",
"蘋果":"apple", "橘子":"tangerine", "柳丁":"orange", "番茄":"tomato",
"有":"have", "給":"give", "剩":"own", "吃":"eat", "一起":"together",
"還":"still", "又":"again", "和":"and", "了":"_le", "且":"and2", "或":"or", "與":"and3",
"個":"_ge", "隻":"_ji", "條":"_tio", "的":"_de",
"幾":"_gi", "這":"this", "那":"that",
"黑":"black", "大":"big", "天":"sky", "風":"wind", "爸爸":"Papa", "去":"go", "捕":"hunt", "魚":"fish", "為甚麼":"why", "不":"not", "回":"back", "家":"home",
"風":"wind", "日":"sun", "旅人":"travler", "人":"people", "衣":"cloth", "者":"guy",
"至":"come", "爭":"argue", "勝":"win", "吹":"blow", "抓":"catch", "緊":"tighten", "敗":"lose", "勝":"win", "照":"shine", "脫":"take_off", "狂":"wild", "暖":"warm" ,
"請問":"Q", "?":"?", "誰":"Who", "甚麼":"What", "何時":"When", "如何":"How", "哪裡":"Where",
}
var wi = 0;
var words = [], mtWords=[];
function isTag(tag) {
var tagWords=tagMap[tag];
if (typeof tagWords === "undefined")
return false;
else
return (tagWords.indexOf(words[wi])>=0);
}
function mt(w) {
var wt = mtMap[w];
if (typeof wt === 'undefined')
return w;
else
return wt;
}
var print = function(s) { process.stdout.write(s) }
function next(tag) {
var w = words[wi];
print(w+':'+tag+" ");
if (isTag(tag)) {
mtWords.push(mt(w));
wi++;
return w;
} else {
c.log('\n==> 錯誤: ' + w + ' 不具有 ' + tag + " 詞性!");
throw Error("Error !");
}
}
function T() {
while (wi < words.length) {
S();
}
}
// S = Q? NP* (VP)* .
function S() {
if (isTag("Q"))
next("Q");
while (isTag("n") || isTag("N"))
NP();
while (isTag("V") || isTag("v"))
VP();
next(".");
console.log('');
}
// VP = VP (c VP)* | (v* V+ v*)+ NP*
function VP() {
while (isTag("v") || isTag("V")) {
while (isTag("v")) next("v");
do { next("V") } while (isTag("V"));
while (isTag("v")) next("v");
}
while (isTag("n") || isTag("N"))
NP();
}
// NP = NP (c NP)* | (n* N+)
function NP() {
while (isTag("n")) next("n");
do { next("N") } while (isTag("N"));
if (isTag("c")) {
next("c");
NP();
}
}
function parse(sentence) {
try {
words=sentence.split(" ");
wi = 0, mtWords=[];
c.log("======= 中文 =============");
c.log(words.join(" "));
c.log("======= 剖析 =============");
T(words);
c.log("======= 英文 =============");
c.log(mtWords.join(" "));
} catch {
c.log("==> 這語句不合法!");
}
}
parse("小明 有 5 個 蘋果 , 給 了 小華 3 個 蘋果 , 請問 他 還 剩 幾 個 蘋果 ?");
parse("小明 和 小華 一起 吃 蘋果 。");
parse("風 與 日 。 風 日 爭 , 旅人 至 , 脫 者 勝 , 風 狂 吹 , 人 緊 衣 , 風 敗 , 日 暖 照 , 人 脫 衣 , 日 勝 。");
parse("黑 黑 的 天 , 大 大 的 風 , 爸爸 去 捕 魚 , 為甚麼 還 不 回 家 ?");
// 全文: https://www.facebook.com/photo.php?fbid=1464494203561879&set=p.1464494203561879&type=3&theater
// parse("聽 狂 風 怒 吼 , 真 叫 我們 害怕 。 爸爸!爸爸! 我們 心理 多麼 牽掛 , 只要 您 早點兒 回家,就是 空 船 也罷 !");
// parse("我 的 好 孩子 , 爸爸 回來 啦 ! 你 看 船艙 裡 , 裝 滿 魚 和 蝦 , 努力 就 有 好 收穫 , 大 風 大 浪 不用 怕 , 快 去 告訴 媽媽 , 爸爸 已經 回 家 !");
parse("黑 黑 天 , 大 大 風 ,");
parse("天 黑 黑 , 風 大 大 ,");
parse("天 黑 黑 的 , 風 大 大 的,");
parse("你 , 風 大 大 的,");
結語
上述程式中的人造語的辭典很小,但是只要花時間對現成辭典進行標記,然後讀入程式中,就能建構出一個實用的人造語翻譯系統了。
最後的問題是,不知有多少人會願意用這樣的方式和外國人交談呢?