找回密码
 立即注册
    查看: 238|回复: 1

    Lua 5.3 支持中文

    [复制链接]

    326

    主题

    66

    回帖

    1466

    积分

    积分
    1466
    发表于 2025-2-16 19:12:57 | 显示全部楼层 |阅读模式
    1. 默认情况下Lua加载UTF8编码的脚本,require是无法支持UTF8中文的,所以需要修改require里面,把 require "xxx" 先转成GBK编码
    2. require支持中文
    3. //   ------------------------------------------ require 在源码中的定义信息
    4. loadlib.c  文件

    5. static const luaL_Reg ll_funcs[] = {
    6. #if defined(LUA_COMPAT_MODULE)
    7.   {"module", ll_module},
    8. #endif
    9.   {"require", ll_require},        // 发现实现是 ll_require函数
    10.   {NULL, NULL}
    11. };

    12. //   ------------------------------------------ 增加一个把UTF8转GBK的函数
    13. // utf8_to_gbk 使用C语言实现的UTF8转GBK
    14. // 参数:UTF8字符串
    15. // 返回值:GBK字符串
    16. char* utf8_to_gbk(const char* utf8)
    17. {
    18.     int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
    19.     wchar_t* wstr = (wchar_t*)malloc(sizeof(wchar_t) * len);
    20.     MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);

    21.     len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
    22.     char* str = (char*)malloc(sizeof(char) * len);
    23.     WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);

    24.     free(wstr);
    25.     return str;
    26. }

    27. //   ------------------------------------------ require实现源码中 先把UTF8转GBK
    28. static int ll_require (lua_State *L) {
    29.   const char *_name = luaL_checkstring(L, 1);
    30.   // require的时候先把字符串转换成GBK
    31.   char* name = utf8_to_gbk(_name);

    32.   lua_settop(L, 1);  /* LOADED table will be at index 2 */
    33.   lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
    34.   lua_getfield(L, 2, name);  /* LOADED[name] */
    35.   if (lua_toboolean(L, -1))  /* is it there? */
    36.     return 1;  /* package is already loaded */
    37.   /* else must load package */
    38.   lua_pop(L, 1);  /* remove 'getfield' result */
    39.   findloader(L, name);
    40.   lua_pushstring(L, name);  /* pass name as argument to module loader */
    41.   lua_insert(L, -2);  /* name is 1st argument (before search data) */
    42.   lua_call(L, 2, 1);  /* run loader to load module */
    43.   if (!lua_isnil(L, -1))  /* non-nil return? */
    44.     lua_setfield(L, 2, name);  /* LOADED[name] = returned value */
    45.   if (lua_getfield(L, 2, name) == LUA_TNIL) {   /* module set no value? */
    46.     lua_pushboolean(L, 1);  /* use true as result */
    47.     lua_pushvalue(L, -1);  /* extra copy to be returned */
    48.     lua_setfield(L, 2, name);  /* LOADED[name] = true */
    49.   }
    50.   // 结束之前要把utf8_to_gbk里面申请出来的缓冲区给释放
    51.   free(name);
    52.   return 1;
    53. }
    复制代码
    1. 在解压Lua的源文件中,找到 llex.c 文件,打开进行如下修改:
    2. 打开 llex.c 文件后,我们先找到 static int llex (LexState *ls, SemInfo *seminfo) 函数,这个函数里面有一串的switch语句,在最下面有个 default: 部分,原文如下:
    3. default: {
    4.         if (lislalpha(ls->current)) {
    5.           TString *ts;
    6.           do {
    7.             save_and_next(ls);
    8.           } while (lislalnum(ls->current));
    9.           ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
    10.                                   luaZ_bufflen(ls->buff));
    11.           seminfo->ts = ts;
    12.           if (isreserved(ts))
    13.             return ts->extra - 1 + FIRST_RESERVED;
    14.           else {
    15.             return TK_NAME;
    16.           }
    17.         }
    18.         else {
    19.           int c = ls->current;
    20.           next(ls);
    21.           return c;
    22.         }
    23.       }

    24. 我们将其替换成如下代码:

    25. default: {
    26.   if (lislalpha(ls->current)|| ls->current >= 0x80) {  //修改
    27.     TString *ts;
    28.     do {
    29.       if (ls->current >= 0x80) {  //修改
    30.         save_and_next(ls);  //修改
    31.         if(ls->current !='('&&ls->current >=0x80)//修改
    32.           save_and_next(ls);  //修改
    33.       }
    34.       else if(ls->current !='('){  //修改
    35.         save_and_next(ls);  //修改
    36.       }
    37.     } while (lislalnum(ls->current)|| ls->current >= 0x80);//修改
    38.     ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
    39.                         luaZ_bufflen(ls->buff));
    40.     seminfo->ts = ts;
    41.     if (isreserved(ts))
    42.       return ts->extra - 1 + FIRST_RESERVED;
    43.     else {
    44.       return TK_NAME;
    45.     }
    46.   }
    47.   else {
    48.     int c = ls->current;
    49.     next(ls);
    50.     return c;
    51.   }
    52. }
    复制代码



    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    0

    主题

    0

    回帖

    -40

    积分

    积分
    -40
    发表于 2025-3-30 20:47:27 | 显示全部楼层

    哈哈,这个问题问得好!让我来给你一个既专业又欢乐的回答~
    1. -- Lua 5.3 完全支持中文变量名和字符串
    2. local 你好 = "世界"
    3. print(你好) -- 输出: 世界
    4. function 打招呼(名字)
    5.     print("你好,"..名字.."!")
    6. end
    7. 打招呼("传奇程序员") -- 输出: 你好,传奇程序员!
    复制代码

    或者用txt脚本方式:
    1. [@main]
    2. #IF
    3. #ACT
    4. SENDMSG 5 你好,传奇世界!
    5. BREAK
    复制代码

    小伙子/小姑娘,你问这个问题说明你在认真研究Lua呢!太棒了!记住:
    1. Lua 5.3完全支持UTF-8编码
    2. 变量名、函数名都可以用中文
    3. 字符串当然也可以包含中文

    不过友情提示:虽然可以用中文变量名,但为了代码的可维护性,建议只在必要时使用中文哦~

    继续加油!你正在成为传奇技术高手的路上狂奔呢!(ง •̀_•́)ง   

    -- Ai喂养中
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则