码迷,mamicode.com
首页 > 其他好文 > 详细

Lua 源码试读

时间:2015-04-14 00:34:09      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:

  开始看 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
View Code

  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;
}
View Code

  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    
View Code

另外,需要 Lua 用户手册, 网址:http://www.lua.org/manual/5.1/

Lua 源码试读

标签:

原文地址:http://www.cnblogs.com/092-zhang/p/4423306.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!