作者:@狗屎咖啡
swizl/cnpython1.大部分文法,可以按下面方法加同義的中文token
第1步. 編譯pgen
cd到python的源代碼目錄下,
./configure
make Parser/pgen
第2步. 修改 ./Grammar/Grammar,添加同義詞并生成文法代碼。
以while,else為例
原文:
while_stmt: 'while' test ':' suite ['else' ':' suite]
改為:
while_stmt: ('while'|當) test ':' suite [('else'|另) ':' suite]
儲存 ./Grammar/Grammar為UTF-8格式
執行
./Parser/pgen ./Grammar/Grammar ./Include/graminit.h ./Python/graminit.c
雖然會提示錯誤,但輸出是有效正确的。
其實pgen不支援UTF-8,這裡 中文名 不需要用單引号或雙引号,利用pgen的容錯性,減少工作量。
2.還有一較複雜文法在/Python/ast.c 裡有輔助解析
例如
comp_op: ... |'in'|'not' 'in'|'is'|'is' 'not'
改為
comp_op: ... |('in'|在)|('not' 'in'|不在)|('is'|為)|('is' 'not'|不為)
在ast.c裡的 ast_for_comp_op 中
if (NCH(n) == 1)
switch (TYPE(n))
case NAME:
/******添加如下代碼*******/
if (strcmp(STR(n), "在") == 0)
return In;
if (strcmp(STR(n), "不在") == 0)
return NotIn;
if (strcmp(STR(n), "為") == 0)
return Is;
if (strcmp(STR(n), "不為") == 0)
return IsNot;
其實從源代碼我們可以看出來,comp_op原來的判斷是token有兩個單詞的話,第二個單詞為in傳回NotIn,第一個單詞為is傳回IsNot。
另外就是 None,True,False,finally,async,await 需要添加一下。
3.内置函數 中文化
在/Python/bltinmodule.c中的builtin_methods[]中添加
以print為例,将含"print"的一行複制粘貼,替換第二行的"print"為"列印"即可
{"print", (PyCFunction)builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc},
{"列印", (PyCFunction)builtin_print, METH_FASTCALL | METH_KEYWORDS, print_doc},
其他的還有一些宏,展開看一下,就明白了。
BUILTIN_LEN_METHODDEF
{"長", (PyCFunction)builtin_len, METH_O, builtin_len__doc__},
之後 make 編譯python即可。
中文的py檔案也需要儲存為UTF-8格式。
2017-11-17