标签:
开始看 Lua 源码也有段时间了,由于尝试用各种方式切入,效果均不是很理想,应该是个人内功不做所致。加上先阶段个人时间有限,现记录下断点,待到来日能力足够有兴趣时再来看。
初期探索:
0、由于第一次尝试读源码,开始时竟将源码按大小顺序排列,从小文件看起。
1、尝试从数据结构看起,看完了 Lua 的数据结构后对 Lua 的数据结构还是有种朦胧的感觉。然后尝试看 Lua 的 GC 终止。
2、尝试把 Lua 当作一个程序来看,从 main 函数开始读,函数调用层层深入下去。。。作为一个菜鸟,这注定是失败的尝试。
3、从网络中找各种源码分析的文章看,源码分析看看看去也就几块,有一个人分析过了后就有一批人跟着转载,不够系统,不能随心。
4、看到了云风的 Lua 源码欣赏中关于源码的阅读顺序的合理方式,觉得可行,又一次尝试。
试读准备:
1、个人机器为 Win7 使用的源码编译工具为 minGW ,minGW 下载链接:http://sourceforge.net/projects/mingw/?source=typ_redirect。
可以使用 mingw32-make Makefile 编译 Lua 源码(说明:个人用的 Lua 源码为 5.1.4 编译出来的 dll 文件 163 kb, 然后总觉得 luaforWindows 里的 dll 要好些,就索性把 luaforWindows 的目录下的 include 文件夹和 lib 文件夹下的文件拷贝出来放在测试文件夹下不要自己编译的了)。
2、编写简单批处理生成动态链接库(make.bat)。
@echo off set curdir=%~dp0 pushd %curdir% set CFN=%1 REM remove the last build (del /q %CFN%.dll) 2>nul REM get file name except extension if "%CFN:~-2%" == ".c" set CFN=%CFN:~0,-2% gcc -shared -o %CFN%.dll %CFN%.c -B %curdir% -llua5.1 popd echo on
3、提取源码测试(LuaStr.c)。
/* Time :2015-04-07 09:13:23 Function :Lua 的正则匹配试读 ( 截取自 Lua 源码 ) Creater :Lazy_Pupa */ /* 输出说明 :_Fun_i_Step_k : Output Message -- i:功能代号, k:第几步。 1: str_find_aux; 2: posrelat; 3: match; 4: start_capture; 5: end_capture; 6: capture_to_close; 7: matchbalance; 8: classend; 9: matchbracketclass; 10: match_capture; 11: singlematch; 12: max_expand; 13: min_expand; 14: push_captures; 15: push_onecapture; 16: match_class; 17: check_capture; 18: ; 19: ; 20: ; */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include "lua.h" #include "lauxlib.h" #include "lualib.h" #define uchar(c) ((unsigned char)(c)) #define CAP_UNFINISHED (-1) #define CAP_POSITION (-2) #define L_ESC ‘%‘ #define SPECIALS "^$*+?.([%-" int Step = 0; typedef struct MatchState{ const char *str_init; const char *str_end; lua_State *L; int level; struct { const char *init; ptrdiff_t len; }capture[LUA_MAXCAPTURES]; }MatchState; /* function: calculate relate position parameters: (pos, len) return: (-4, 2) -> 0; (-3, 2) -> 0; (-2, 2) -> 1; (-1, 2) -> 2; (0, 2) -> 0; (1, 2) -> 1; (2, 2) -> 2; (3, 2) -> 3; */ static ptrdiff_t posrelat(ptrdiff_t pos, size_t len) { printf("_Fun_%02d_Step_%3d : parameters %d, %d\n", 2, ++Step, pos, len); if(pos < 0) pos += (ptrdiff_t)len + 1; printf("_Fun_%02d_Step_%3d :return %d ? %d : 0\n", 2, ++Step, (pos >= 0), pos); return (pos >= 0) ? pos : 0; } static const char *classend(MatchState *ms, const char *p) { // find the %f[match] pattern ‘]‘ // ms: 查找状态; *p: 匹配字符串 printf("_Fun_%02d_Step_%3d : parameters ‘%s‘\n", 8, ++Step, p); switch(*p++){ case L_ESC:{ if (*p == ‘\0‘) luaL_error(ms->L, "malformed pattern (end with " LUA_QL("%%") ")"); printf("_Fun_%02d_Step_%3d :case L_ESC return ‘%s‘\n", 8, ++Step, p + 1); return p + 1; } case ‘[‘:{ if(*p == ‘^‘) p++; do{ if(*p == ‘\0‘) luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); if(*(p++) == L_ESC && *p != ‘\0‘) p++; }while(*p != ‘]‘); printf("_Fun_%02d_Step_%3d :case ‘[‘ return ‘%s‘\n", 8, ++Step, p + 1); return p + 1; } default:{ printf("_Fun_%02d_Step_%3d :default return ‘%s‘\n", 8, ++Step, p); return p; } } } static int match_class(int c, int cl) { printf("_Fun_%02d_Step_%3d : parameters %d, %d\n", 16, ++Step, c, cl); int res; switch (tolower(cl)){ case ‘a‘: res = isalpha(c); break; case ‘c‘: res = iscntrl(c); break; case ‘d‘: res = isdigit(c); break; case ‘l‘: res = islower(c); break; case ‘p‘: res = ispunct(c); break; case ‘s‘: res = isspace(c); break; case ‘u‘: res = isupper(c); break; case ‘w‘: res = isalnum(c); break; case ‘x‘: res = isxdigit(c); break; case ‘z‘: res = (c == 0); break; default: return (cl == c); } printf("_Fun_%02d_Step_%3d :return (%d ? %d : %d)\n", 16, ++Step, islower(cl), res, !res); return (islower(cl) ? res : !res); } static int matchbracketclass(int c, const char *p, const char *ec) { // 匹配模版类。 // c: ; *p: 匹配字符串; *ec: 匹配结束位置。 printf("_Fun_%02d_Step_%3d : parameters %c, ‘%s‘, ‘%s‘\n", 9, ++Step, c, p, ec); int sig = 1; if (*(p+1) == ‘^‘) { sig = 0; p++; } while (++p < ec) { if (*p == L_ESC) { p++; if (match_class(c, uchar(*p))) { printf("_Fun_%02d_Step_%3d :if return %d\n", 9, ++Step, sig); return sig; } } else if ((*(p+1) == ‘-‘) && (p+2 < ec)) { p += 2; if (uchar(*(p-2)) <= c && c <= uchar(*p)) { printf("_Fun_%02d_Step_%3d :else if return %d\n", 9, ++Step, sig); return sig; } } else if (uchar(*p) == c) { printf("_Fun_%02d_Step_%3d :else if 2 return %d\n", 9, ++Step, sig); return sig; } } printf("_Fun_%02d_Step_%3d :return %d\n", 9, ++Step, !sig); return !sig; } static int singlematch(int c, const char *p, const char *ep) { // c: source char; *p: pattern string; *ep: pattern end printf("_Fun_%02d_Step_%3d : parameters %d, ‘%s‘, ‘%s‘\n", 11, ++Step, c, p, ep); switch(*p){ case ‘.‘: printf("_Fun_%02d_Step_%3d :return 1;\n", 11, ++Step); return 1; case L_ESC: printf("_Fun_%02d_Step_%3d :return match_class(c, uchar(*(p+1)));\n", 11, ++Step); return match_class(c, uchar(*(p+1))); case ‘[‘: printf("_Fun_%02d_Step_%3d :return matchbracketclass(c, p, ep-1);\n", 11, ++Step); return matchbracketclass(c, p, ep-1); default: printf("_Fun_%02d_Step_%3d :default return %d\n", 11, ++Step, (uchar(*p) == c)); return (uchar(*p) == c); } } static const char *match(MatchState *ms, const char *s, const char *p); static const char *matchbalance(MatchState *ms, const char *s, const char *p) { // ms: 查找状态; *s: 源字符串; *p: 匹配字符串 // printf("ms->str_end = ‘%s‘, *s = ‘%s‘, *p = ‘%s‘\n", ms->str_end, s, p); printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘\n", 7, ++Step, s, p); if(*p == 0 || *(p+1) == 0) // *p 以 %b"结尾。 luaL_error(ms->L, "unbalanced pattern"); if (*s != *p) { printf("_Fun_%02d_Step_%3d :if return NULL\n", 7, ++Step); return NULL; } else { int b = *p; // 开始 int e = *(p+1); // 结束 int cont = 1; // while (++s < ms->str_end) { // printf("*s = %d, b = %d, e = %d, cont = %d\n*s = ‘%s‘\n", *s, b, e, cont, s); if (*s == e) { if (--cont == 0) { printf("_Fun_%02d_Step_%3d :return ‘%s‘\n", 7, ++Step, s+1); return s+1; } }else if (*s == b) cont++; // 支持嵌套 } } printf("_Fun_%02d_Step_%3d :return NULL\n", 7, ++Step); return NULL; } static const char *max_expand(MatchState *ms, const char *s, const char *p, const char *ep) { // ms: 查找状态; *s: 源字符串; *p: 匹配字符串; *ep: 匹配字符串结尾 printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘, ‘%s‘\n", 12, ++Step, s, p, ep); ptrdiff_t i = 0; while((s+i) < ms->str_end && singlematch(uchar(*(s+i)), p, ep)) // anchor the match tail i++; while (i >= 0) { const char *res = match(ms, (s+i), ep+1); // if (res) { printf("_Fun_%02d_Step_%3d :return ‘%s‘\n", 12, ++Step, res); return res; } i--; } printf("_Fun_%02d_Step_%3d :return NULL\n", 12, ++Step); return NULL; } static const char *min_expand(MatchState *ms, const char *s, const char *p, const char *ep) { printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘, ‘%s‘\n", 13, ++Step, s, p, ep); for(;;) { const char *res = match(ms, s, ep+1); if (res != NULL) { printf("_Fun_%02d_Step_%3d : return ‘%s‘\n", 13, ++Step, res); return res; } else if (s<ms->str_end && singlematch(uchar(*s), p, ep)) s++; else { printf("_Fun_%02d_Step_%3d : return NULL\n", 13, ++Step); return NULL; } } } static const char *start_capture(MatchState *ms, const char *s, const char *p, int what) { // ms: 查找状态; *s: 源字符串; *p: 匹配字符串; what: 标记捕获是否结束 printf("_Fun_%02d_Step_%3d : parameters %d, ‘%s‘, ‘%s‘, %d\n", 4, ++Step, ms->level, s, p, what); const char *res; int level = ms->level; // 捕获个数 if (level > LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); ms->capture[level].init = s; ms->capture[level].len = what; // 捕获状态 ms->level = level + 1; // 捕获加一。 if ((res=match(ms, s, p)) == NULL) ms->level--; printf("_Fun_%02d_Step_%3d :return ‘%s‘\n", 4, ++Step, res); return res; } // 嵌套捕获结束 如:src = "Lua Test String!"; matchString = "((%a+) %a+)"; return "Lua Test", "Lua"; static int capture_to_close(MatchState *ms) { // ms: 查找状态 printf("_Fun_%02d_Step_%3d : parameters %d\n", 6, ++Step, ms->level); int level = ms->level; // 查找深度 for(level--; level>=0; level--) // 查找该捕获的起始深度 if(ms->capture[level].len == CAP_UNFINISHED) { printf("_Fun_%02d_Step_%3d :return %d\n", 6, ++Step, level); return level; } printf("_Fun_%02d_Step_%3d :return error\n", 6, ++Step); return luaL_error(ms->L, "invalid pattern capture"); } static const char *end_capture(MatchState *ms, const char *s, const char *p) { // ms: 查找状态; *s: 源字符串; *p: 捕获之后的字符串 printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘\n", 5, ++Step, s, p); int l = capture_to_close(ms); // 匹配的左括号。 printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘, ‘%s‘, %d\n", 5, ++Step, ms->capture[l].init, s, p, s - ms->capture[l].init); const char *res; ms->capture[l].len = s - ms->capture[l].init; // 记录捕获长度。 if((res = match(ms, s, p)) == NULL) // 捕获结束,开始后续匹配。 ms->capture[l].len = CAP_UNFINISHED; // UNKNOW... Um, just mark capture unfinished. printf("_Fun_%02d_Step_%3d :return ‘%s‘\n", 5, ++Step, res); return res; } static int check_capture(MatchState *ms, int l) { // ms : 查找状态; l : 匹配字符。 printf("_Fun_%02d_Step_%3d : parameters %d, %d, %d\n", 17, ++Step, ms->level, ms->capture[l].len, l); l -= ‘1‘; if (l<0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) return luaL_error(ms->L, "invalid capture index"); printf("_Fun_%02d_Step_%3d : parameters %d\n", 17, ++Step, l); return l; } static const char *match_capture(MatchState *ms, const char *s, int l) { // ms : 查找状态; *s : 查找源字符串; l : 匹配字符。 printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, %d\n", 10, ++Step, s, l); size_t len; l = check_capture(ms, l); printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘, %d\n", 10, ++Step, ms->capture[l].init, s, l); len = ms->capture[l].len; printf("_Fun_%02d_Step_%3d : parameters ‘%s‘, ‘%s‘, %d, %d\n", 10, ++Step, ms->capture[l].init, s, l, s+len); if ((size_t)(s+len) >= len && memcmp(ms->capture[l].init, s, len) == 0) { printf("_Fun_%02d_Step_%3d :return ‘%s‘\n", 10, ++Step, s+len); return s+len; } else { printf("_Fun_%02d_Step_%3d :return NULL\n", 10, ++Step); return NULL; } } static const char *match(MatchState *ms, const char *s, const char *p) { // ms : 查找状态; *s : 查找源字符串; *p : 匹配字符串。 init: printf("_Fun_%02d_Step_%3d : parameters *ms, ‘%s‘, ‘%s‘\n", 3, ++Step, s, p); switch(*p) { case ‘(‘:{ if (*(p+1) == ‘)‘) // 空捕获返回捕获的起始位置。如 find(‘Lua‘, ‘()‘) -> 1, 0, 1; find(‘Lua‘, ‘%a()‘) -> 1, 1, 2; { printf("_Fun_%02d_Step_%3d :return start_capture(ms, s, p+2, CAP_POSITION)\n", 3, ++Step); return start_capture(ms, s, p+2, CAP_POSITION); } else { printf("_Fun_%02d_Step_%3d :return start_capture(ms, s, p+1, CAP_UNFINISHED)\n", 3, ++Step); return start_capture(ms, s, p+1, CAP_UNFINISHED); } } case ‘)‘:{ printf("_Fun_%02d_Step_%3d :return end_capture(ms, s, p+1)\n", 3, ++Step); return end_capture(ms, s, p+1); } case L_ESC:{ // translate meaning char switch(*(p+1)) { case ‘b‘:{ s = matchbalance(ms, s, p+2); // if (s == NULL) { printf("_Fun_%02d_Step_%3d :case ‘b‘ return NULL\n", 3, ++Step); return NULL; } p += 4; printf("_Fun_%02d_Step_%3d :case ‘b‘ goto init\n", 3, ++Step); goto init; } case ‘f‘:{ // {LuaStr.find("Lua Test String!", "(%f[%a+])") -> 1 0} 没懂这是干嘛的。。。。 const char *ep; char previous; p += 2; if (*p != ‘[‘) luaL_error(ms->L, "missing" LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); ep = classend(ms, p); // anchor the %f[] end. previous = (s == ms->str_init) ? ‘\0‘ : *(s-1); if (matchbracketclass(uchar(previous), p, ep-1) || !matchbracketclass(uchar(*s), p, ep-1)) { printf("_Fun_%02d_Step_%3d :case ‘f‘ return NULL\n", 3, ++Step); return NULL; } p = ep; printf("_Fun_%02d_Step_%3d :case ‘f‘ goto init\n", 3, ++Step); goto init; } default: { if (isdigit(uchar(*(p+1)))) { s = match_capture(ms, s, uchar(*(p+1))); // 源自符指针后移,至下一个匹配开始。 if (s == NULL) { printf("_Fun_%02d_Step_%3d :case L_ESC return NULL\n", 3, ++Step); return NULL; } p += 2; printf("_Fun_%02d_Step_%3d :default goto init\n", 3, ++Step); goto init; } printf("_Fun_%02d_Step_%3d :case L_ESC goto dflt\n", 3, ++Step); goto dflt; } } } case ‘\0‘:{ printf("_Fun_%02d_Step_%3d :case ‘\\0‘ return ‘%s‘\n", 3, ++Step, s); return s; } case ‘$‘:{ if (*(p+1) == ‘\0‘) // 是否匹配结束位置。 { printf("_Fun_%02d_Step_%3d :case ‘$‘ return %d ? s : NULL\n", 3, ++Step, (s == ms->str_end)); return (s == ms->str_end) ? s : NULL; } else { printf("_Fun_%02d_Step_%3d :case ‘\0‘ goto dflt\n", 3, ++Step); goto dflt; } } default: dflt: { const char *ep = classend(ms, p); // check single match, if true jump to ‘[match string]‘ end ,( ep: end of *p) int m = s<ms->str_end && singlematch(uchar(*s), p, ep); // 简单匹配标识。 switch(*ep) { case ‘?‘:{ // 匹配 0 次或 1 次。 const char *res; if (m && ((res = match(ms, s+1, ep+1)) != NULL)) // UNKNOW ... Um, like match a result. { printf("_Fun_%02d_Step_%3d :case ‘?‘ return ‘%s‘\n", 3, ++Step, res); return res; } p=ep+1; // Don‘t match any result. printf("_Fun_%02d_Step_%3d :case ‘?‘ goto init\n", 3, ++Step); goto init; } case ‘*‘:{ // 匹配 0 次或多次。 printf("_Fun_%02d_Step_%3d :return max_expand(ms, s, p, ep)\n", 3, ++Step); return max_expand(ms, s, p, ep); } case ‘+‘:{ // 匹配 1 次或多次。 printf("_Fun_%02d_Step_%3d :return (m ? max_expand(ms, s+1, p, ep) : NULL)\n", 3, ++Step); return (m ? max_expand(ms, s+1, p, ep) : NULL); } case ‘-‘:{ // 匹配 0 次或多次。 printf("_Fun_%02d_Step_%3d :return min_expand(ms, s, p, ep)\n", 3, ++Step); return min_expand(ms, s, p, ep); } default: { if (!m) { printf("_Fun_%02d_Step_%3d :default: dflt: return NULL\n", 3, ++Step); return NULL; } s++; p=ep; printf("_Fun_%02d_Step_%3d :default: dflt goto init\n", 3, ++Step); goto init; } } } } } static const char * lmemfind(const char *s1, size_t l1, const char *s2, size_t l2) { return NULL; } static void push_onecapture(MatchState *ms, int i, const char *s, const char *e) { printf("_Fun_%02d_Step_%3d : parameters %d, ‘%s‘, ‘%s‘\n", 15, ++Step, i, s, e); if (i>=ms->level) { if (i == 0) lua_pushlstring(ms->L, s, e - s); else luaL_error(ms->L, "invalid capture index!"); } else { ptrdiff_t l = ms->capture[i].len; if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); if (l == CAP_POSITION) lua_pushinteger(ms->L, ms->capture[i].init - ms->str_init +1); else lua_pushlstring(ms->L, ms->capture[i].init, l); } } static int push_captures(MatchState *ms, const char *s, const char *e) { printf("_Fun_%02d_Step_%3d : parameters %d, ‘%s‘, ‘%s‘\n", 14, ++Step, ms->level, s, e); int i; int nlevels = (ms->level == 0 && s) ? 1 : ms->level; luaL_checkstack(ms->L, nlevels, "too many captures"); for(i=0; i<nlevels; i++) push_onecapture(ms, i, s, e); printf("_Fun_%02d_Step_%3d :return %d\n", 14, ++Step, nlevels); return nlevels; } static int str_find_aux(lua_State *L, int find) { printf("_Fun_%02d_Step_%3d : parameters find = %d\n", 1, ++Step, find); size_t srcStrLen, matchStrLen; const char *srcStr = luaL_checklstring(L, 1, &srcStrLen); const char *matchStr = luaL_checklstring(L, 2, &matchStrLen); ptrdiff_t startFindPostion = posrelat(luaL_optinteger(L, 3, 1), srcStrLen) - 1; if(startFindPostion < 0) startFindPostion = 0; else if ((size_t)(startFindPostion) > srcStrLen) startFindPostion = (ptrdiff_t)srcStrLen; if (find && (lua_toboolean(L, 4) || strpbrk(matchStr, SPECIALS) == NULL)) { const char *s2 = lmemfind(srcStr+startFindPostion, srcStrLen-startFindPostion, matchStr, matchStrLen); // 常规匹配查找 if (s2) { lua_pushinteger(L, s2-srcStr+1); lua_pushinteger(L, s2-srcStr+matchStrLen); printf("_Fun_%02d_Step_%3d :return 2.\n", 1, ++Step); return 2; } } else { // 正则匹配查找 MatchState ms; int anchor = (*matchStr == ‘^‘) ? (matchStr++, 1) : 0; // 是否定位头部 const char *s1 = srcStr + startFindPostion; // 待查找的字符串 ms.L = L; // 保存脚本上下文 ms.str_init = srcStr; // 保存待查找的字符串 ms.str_end = srcStr + srcStrLen; // 保存字符串结束位置 do { const char *res; ms.level = 0; // 设置默认捕获的数量 if ((res=match(&ms, s1, matchStr)) != NULL) { // 匹配主体部分 if (find) { // 返回查找结果 lua_pushinteger(L, s1-srcStr+1); lua_pushinteger(L, res-srcStr); printf("_Fun_%02d_Step_%3d :return push_captures(&ms, NULL, 0) + 2\n", 1, ++Step); return push_captures(&ms, NULL, 0) + 2; }else // 返回匹配结果 { printf("_Fun_%02d_Step_%3d :return push_captures(&ms, s1, res)\n", 1, ++Step); return push_captures(&ms, s1, res); } } }while (s1++ < ms.str_end && !anchor); // 一次匹配不成功且非从头部开始定位则继续。 } lua_pushnil(L); // 查找失败。 printf("_Fun_%02d_Step_%3d :return 1.\n", 1, ++Step); return 1; } static int str_find(lua_State *L) { printf( "=================================== Lua Find Test ===================================\n" " 1: str_find_aux ; 4: start_capture ; 5: end_capture; 2: posrelat; 3: match;\n" " 6: capture_to_close; 7: matchbalance ; 8: classend ; 9: matchbracketclass;\n" "10: match_capture ; 11: singlematch ; 12: max_expand ; 13: min_expand;\n" "14: push_captures ; 15: push_onecapture; 16: match_class; 17: check_capture;\n" "=================================== Lua Find Test ===================================\n"); return str_find_aux(L, 1); } static const luaL_Reg strlib[] = { {"find", str_find}, {NULL, NULL} }; // Open String Library extern int luaopen_LuaStr(lua_State *L) { const char *libraryName = "LuaStr"; luaL_register(L, libraryName, strlib); return 1; }
4、编译测试代码 make LuaStr.c
5、测试源码
require "LuaStr" print(LuaStr.find("Lua Test String!", "(%f[%a+])"));
6、运行看结果
=================================== Lua Find Test =================================== 1: str_find_aux ; 4: start_capture ; 5: end_capture; 2: posrelat; 3: match; 6: capture_to_close; 7: matchbalance ; 8: classend ; 9: matchbracketclass; 10: match_capture ; 11: singlematch ; 12: max_expand ; 13: min_expand; 14: push_captures ; 15: push_onecapture; 16: match_class; 17: check_capture; =================================== Lua Find Test =================================== _Fun_01_Step_ 1 : parameters find = 1 _Fun_02_Step_ 2 : parameters 1, 16 _Fun_02_Step_ 3 :return 1 ? 1 : 0 _Fun_03_Step_ 4 : parameters *ms, ‘Lua Test String!‘, ‘(%f[%a+])‘ _Fun_03_Step_ 5 :return start_capture(ms, s, p+1, CAP_UNFINISHED) _Fun_04_Step_ 6 : parameters 0, ‘Lua Test String!‘, ‘%f[%a+])‘, -1 _Fun_03_Step_ 7 : parameters *ms, ‘Lua Test String!‘, ‘%f[%a+])‘ _Fun_08_Step_ 8 : parameters ‘[%a+])‘ _Fun_08_Step_ 9 :case ‘[‘ return ‘)‘ _Fun_09_Step_ 10 : parameters , ‘[%a+])‘, ‘])‘ _Fun_16_Step_ 11 : parameters 0, 97 _Fun_16_Step_ 12 :return (2 ? 0 : 1) _Fun_09_Step_ 13 :return 0 _Fun_09_Step_ 14 : parameters L, ‘[%a+])‘, ‘])‘ _Fun_16_Step_ 15 : parameters 76, 97 _Fun_16_Step_ 16 :return (2 ? 1 : 0) _Fun_09_Step_ 17 :if return 1 _Fun_03_Step_ 18 :case ‘f‘ goto init _Fun_03_Step_ 19 : parameters *ms, ‘Lua Test String!‘, ‘)‘ _Fun_03_Step_ 20 :return end_capture(ms, s, p+1) _Fun_05_Step_ 21 : parameters ‘Lua Test String!‘, ‘‘ _Fun_06_Step_ 22 : parameters 1 _Fun_06_Step_ 23 :return 0 _Fun_05_Step_ 24 : parameters ‘Lua Test String!‘, ‘Lua Test String!‘, ‘‘, 0 _Fun_03_Step_ 25 : parameters *ms, ‘Lua Test String!‘, ‘‘ _Fun_03_Step_ 26 :case ‘\0‘ return ‘Lua Test String!‘ _Fun_05_Step_ 27 :return ‘Lua Test String!‘ _Fun_04_Step_ 28 :return ‘Lua Test String!‘ _Fun_01_Step_ 29 :return push_captures(&ms, NULL, 0) + 2 _Fun_14_Step_ 30 : parameters 1, ‘(null)‘, ‘(null)‘ _Fun_15_Step_ 31 : parameters 0, ‘(null)‘, ‘(null)‘ _Fun_14_Step_ 32 :return 1 1 0
另外,需要 Lua 用户手册, 网址:http://www.lua.org/manual/5.1/
标签:
原文地址:http://www.cnblogs.com/092-zhang/p/4423306.html