1. 程式人生 > >為Python新增中文關鍵字

為Python新增中文關鍵字

知乎原文地址 作者:@狗屎咖啡

swizl/cnpython

1.大部分語法,可以按下面方法加同義的中文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格式。