[英]Translating source code into a foreign language
我正在運行一個教育網站,教孩子們(12-15歲)。
因為他們並不都在解決方案的代碼源中說英語,所以我們使用法語變量和函數名稱。 但是,我們計划將內容翻譯成其他語言(德語,西班牙語,英語)。 為此,我想盡快翻譯源代碼。 我們大多數都有C / C ++代碼。
我打算使用的解決方案:
是否已經有一些開源代碼/項目可以做到這一點? (對於第1,2和4點)
如果沒有,那么第一個中最困難的一點是:使用C / C ++解析器構建一個語法樹然后用它們的位置提取變量似乎是要走的路。 你有其他想法嗎?
謝謝你的任何建議。
編輯:如評論中所述,我還需要處理注釋,但只有少數幾個:完整的解決方案已經用純文本解釋,然后我們用自解釋的變量顯示代碼源/函數名稱。 源代碼很少超過30/40行,如果您已經知道代碼在做什么,那么好的名稱必須使它在沒有注釋的情況下可以理解。
附加信息:對於感興趣的人來說,網站是國際奧林匹克信息學和C / C ++的培訓平台(至少是編程競賽所需的最低限度),12歲時學習並不困難。
你真的不需要一個C / C ++解析器,只是一個簡單的詞法分析器,它逐個為你提供代碼元素。 然后你得到很多{
, [
, 213
, )
等你只是忽略並寫入結果文件。 您只翻譯由字母組成的字母(關鍵字除外),並將它們放在輸出中。
現在我考慮一下,它就像這樣簡單:
bool is_letter(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
bool is_keyword(string &s)
{
return s == "if" || s == "else" || s == "void" /* rest of them */;
}
void translateCode(istream &in, ostream &out)
{
while (!in.eof())
{
char c = in.get();
if (is_letter(c))
{
string name = "";
do
{
name += c;
c = in.get();
} while (is_letter(c) && !in.eof());
if (is_keyword(name))
out << name;
else
out << translate(name);
}
out << c; // even if is_letter(c) was true, there is a new c from the
// while inside that was read (which was not letter), but
// not written, so would be written here.
}
}
我在編輯器中編寫了代碼,因此可能存在輕微錯誤。 告訴我,如果有,我會解決它。
編輯:說明:
代碼所做的只是逐個字符地讀取輸入,輸出它讀取的任何非字母字符(包括空格,制表符和新行)。 如果它確實看到一個字母,它將開始將所有以下字母放在一個字符串中(直到它到達另一個非字母)。 然后,如果字符串是關鍵字,它將輸出關鍵字本身。 如果不是,則將其翻譯並輸出。
輸出將具有與輸入完全相同的格式。
您確定需要完整的語法樹嗎? 我認為進行詞法分析以找到標識符就足夠了,這更容易。 然后排除也包含在頭文件中的關鍵字和標識符。
原則上,您可能希望將具有相同英文名稱的不同變量翻譯成法語/德語中的不同單詞 - 但是對於教育用途,這種情況的風險可能很小,一開始可能忽略不計。 您可以通過使用一些消除歧義的准匈牙利語前綴來編寫原始資源來回避問題,然后使用相同的翻譯機制將其刪除,以便向講英語的最終用戶顯示。
在選擇翻譯之前,請務必讓翻譯人員在完整背景下查看他們正在翻譯的名稱。
我真的認為你可以使用clang (libclang)來解析你的資源並做你想做的事情( 詳見更多信息 ),好消息是它們有python綁定,如果你想訪問翻譯,這將使你的生活更輕松服務或類似的東西。
我不認為替換代碼中的標識符是個好主意。
首先,你不會得到體面的翻譯。 這里非常重要的一點是,翻譯(特別是自動或相當愚蠢的翻譯)會丟失和扭曲信息。 實際上你可能會得到比原版更糟糕的東西。
其次,如果要再次編譯代碼,編譯器可能無法在已翻譯的標識符中編譯包含非英文字母的代碼。
第三,如果您使用其他內容替換標識符,則需要確保不使用相同的單詞替換2個或更多不同的標識符。 這要么使代碼不可編輯,要么破壞其邏輯。
第四,您必須確保不翻譯來自語言標准庫的保留字和標識符。 翻譯這些將使代碼不可編輯且不可讀。 區分程序員定義的標識符與語言提供的標識符及其標准庫可能不是一項非常簡單的任務。
我所做的不是用翻譯替換標識符,而是將翻譯作為評論提供給他們,例如:
void eat/*comer*/(int* food/*comida*/)
{
if (*food/*comida*/ <= 0)
{
printf("nothing to eat!"/*no hay que comer!*/);
exit/*salir*/(-1);
}
(*food/*comida*/)--;
}
這樣您就不會因為錯誤的翻譯而丟失任何信息,也不會破壞代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.