{"id":495,"date":"2021-12-04T15:47:13","date_gmt":"2021-12-04T07:47:13","guid":{"rendered":"https:\/\/www.ccagml.com\/?p=495"},"modified":"2021-12-04T15:47:13","modified_gmt":"2021-12-04T07:47:13","slug":"lua%e4%bb%8emain%e5%bc%80%e5%a7%8b2%e4%b9%8btable%e6%93%8d%e4%bd%9c%e8%a7%a3%e6%9e%90token","status":"publish","type":"post","link":"https:\/\/www.ccagml.com\/?p=495","title":{"rendered":"lua\u4ecemain\u5f00\u59cb2\u4e4btable\u64cd\u4f5c\u89e3\u6790token"},"content":{"rendered":"<h1>\u672c\u7ae0\u6211\u4eec\u6765\u770btable\u7684\u57fa\u672c\u64cd\u4f5c<\/h1>\n<h2>1. \u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50<\/h2>\n<pre><code class=\"line-numbers\">local a = {1,2,3}\na[6] = 1\na[\"aaa\"]= 1\n\n<\/code><\/pre>\n<h2>1.1 \u6267\u884c\u6211\u4eec\u7684\u4f8b\u5b50<\/h2>\n<pre><code class=\"line-numbers\">gafq test\/hello.gafq\n\n<\/code><\/pre>\n<h1>1.\u6709\u4e86\u4e0a\u4e00\u8282\u7684\u57fa\u7840\u6211\u4eec\u76f4\u63a5\u6765\u5230\u8bcd\u6cd5\u5206\u6790\u5904<\/h1>\n<pre><code class=\"line-numbers\">\/\/gparser.c\n\/\/ \u89e3\u91ca\u5668,\u89e3\u91ca\u6587\u4ef6\u5185\u5bb9\nProto *gafqY_parser(gafq_State *L, ZIO *z, Mbuffer *buff, const char *name)\n{\n    struct LexState lexstate;\n    struct FuncState funcstate;\n    gafqX_next(&amp;lexstate); \/\/ \u8bfb\u53d6\u7b2c\u4e00\u4e2atoken\n}\n<\/code><\/pre>\n<h1>2.\u8bcd\u6cd5\u5206\u6790<\/h1>\n<pre><code class=\"line-numbers\">glex.c\n\nvoid gafqX_next(LexState *ls)\n{\n    ...\n    ls-&gt;t.token = glex(ls, &amp;ls-&gt;t.seminfo); \u8bfb\u53d6\u4e0b\u4e00\u4e2atoken\n    ...\n}\n\n\/\/ \u8bfb\u53d6\u4e0b\u4e00\u4e2atoken, \u8bcd\u6cd5\u5206\u6790 SemInfo\u662f\u8bed\u4e49\u4fe1\u606f\nstatic int glex(LexState *ls, SemInfo *seminfo)\n{\n    gafqZ_resetbuffer(ls-&gt;buff);\n    for (;;)\n    {\n        switch (ls-&gt;current)\/\/ \u9996\u5148\u6211\u4eec\u7684\u4f8b\u5b50\u7b2c\u4e00\u4e2a\u5b57\u8282\u662flocal\u4e2d\u7684l \u8fd9\u91ccls_current = 108 \u5c31\u662fl\u7684ascii\u7801\n        {\n        default:\n        {\n            \/\/ \u5224\u65ad\u662f\u5b57\u6bcd\n            if (isalpha(ls-&gt;current) || ls-&gt;current == '_')\n            {\n                TString *ts;\n                \/\/ \u5faa\u73af\u5982\u679c\u63a5\u4e0b\u53bb\u7684\u5b57\u7b26\u662f\u6570\u5b57,\u5b57\u7b26\u6216\u8005\u4e0b\u5212\u7ebf\u5c31\u4e0d\u65ad\u8bfb\u53d6\n                do\n                {\n                    save_and_next(ls);\n                } while (isalnum(ls-&gt;current) || ls-&gt;current == '_');\n                \/\/ \u524d\u9762\u7684\u8bfb\u53d6\u64cd\u4f5c,\u5230\u8fd9\u91cc,\u6211\u4eec\u7684ls-&gt;buff \u7b49\u4e8e local\n                ts = gafqX_newstring(ls, gafqZ_buffer(ls-&gt;buff), gafqZ_bufflen(ls-&gt;buff));\n                if (ts-&gt;tsv.reserved &gt; 0) \/\/ \u8fd9\u91cc\u5f97\u5230\u7684\u5b57\u7b26\u4e32ts \u7684\u503c\u662f12, \u8ba4\u4e3a\u8fd9\u662f\u4e00\u4e2a\u5173\u952e\u5b57\n                    return ts-&gt;tsv.reserved - 1 + FIRST_RESERVED;\n\n            }\n        }\n        }\n    }\n}\n\n<\/code><\/pre>\n<h1>3.\u56de\u52301\u4e2d,\u8bfb\u53d6\u4e86\u7b2c\u4e00\u4e2atoken\u662flocal 12, \u5f00\u59cb\u89e3\u6790\u6574\u4e2a\u6587\u4ef6chunk<\/h1>\n<pre><code class=\"line-numbers\">\/\/ \u89e3\u91ca\u5668,\u89e3\u91ca\u6587\u4ef6\u5185\u5bb9\n3.1 Proto *gafqY_parser(gafq_State *L, ZIO *z, Mbuffer *buff, const char *name)\n{\n    ...\n    gafqX_next(&amp;lexstate);\n    chunk(&amp;lexstate);\n    ...\n}\n\n\/\/ \u8fd9\u91cc\u662f\u89e3\u6790\u4ee3\u7801\u5757?\n3.2 static void chunk(LexState *ls)\n{\n    -- \u4e0d\u662f\u7ed3\u5c3e\u5c31\u4e0d\u65ad\u89e3\u6790\n    while (!islast &amp;&amp; !block_follow(ls-&gt;t.token))\n    {\n        islast = statement(ls);\n    }\n}\n\n\/\/ \u5224\u65ad\u5f53\u524d\u7684token, \u6839\u636etoken\u83b7\u53d6\u63a5\u4e0b\u53bb\u89e3\u6790\u7684\u89c4\u5219?\n3.3 static int statement(LexState *ls)\n{\n    switch (ls-&gt;t.token)\n    {\n    case TK_LOCAL:\n    {                                \n        gafqX_next(ls);                \/\/ \u8df3\u8fc7local\u7684token\n        localstat(ls);\n        return 0;\n    }\n    }\n}\n\n3.4 static void localstat(LexState *ls)\n{\n    ...\n    if (testnext(ls, '=')) \/\/ \u8df3\u8fc7 61 '='\n        nexps = explist1(ls, &amp;e); \/\/ \u51c6\u5907\u89e3\u6790 = \u540e\u9762\u7684\u4e1c\u897f\n    ...\n}\n\n\/\/\u89e3\u6790\u53c2\u6570\u5217\u8868?, \u53d8\u91cf\u7684\u503c\n3.5 static int explist1(LexState *ls, expdesc *v)\n{\n    ...\n    expr(ls, v); \/\/ 285(TK_NAME)\n    while (testnext(ls, ','))\n    {\n        gafqK_exp2nextreg(ls-&gt;fs, v);\n        expr(ls, v);\n        n++;\n    }\n    return n;\n}\n\n3.6 static BinOpr subexpr(LexState *ls, expdesc *v, unsigned int limit)\n{\n    uop = getunopr(ls-&gt;t.token); \/\/ \u8fd9\u91cc\u73b0\u5728token\u662f123\n    simpleexp(ls, v); \/\/ \u8ba4\u4e3a\u540e\u9762\u662f\u7b80\u5355\u7c7b\u578b\n}\n\n\n3.7 static void simpleexp(LexState *ls, expdesc *v)\n{\n    switch (ls-&gt;t.token) \/\/ token = 123\n    {\n    case '{':\n    {\n        constructor(ls, v);\n        return;\n    }\n}\n\n\/\/ \u8fd9\u91cc\u89e3\u6790{ \u4e4b\u540e\u7684\u4e1c\u897f, \u8ba4\u4e3a\u662f\u4e2atable\n3.8 static void constructor(LexState *ls, expdesc *t)\n{\n    checknext(ls, '{');\n    do\n    {\n        gafq_assert(cc.v.k == VVOID || cc.tostore &gt; 0);\n        if (ls-&gt;t.token == '}')\n            break;\n        switch (ls-&gt;t.token) \/\/ \u63a5\u4e0b\u53bb\u662f\u4e2a\u6570\u5b57 token = 284\n        {\n        default:\n        {\n            listfield(ls, &amp;cc);\n            break;\n        }\n        }\n    } while (testnext(ls, ',') || testnext(ls, ';'));\n}\n\n\n3.9 static void listfield(LexState *ls, struct ConsControl *cc)\n{\n    expr(ls, &amp;cc-&gt;v);\n}\n\n3.10 static BinOpr subexpr(LexState *ls, expdesc *v, unsigned int limit)\n{\n    ...\n    simpleexp(ls, v);\n    ...\n}\n\n\/\/\u7b80\u5355\u7c7b\u578b, \u6570\u5b57 | \u5b57\u7b26\u4e32 | nil | \u5bf9 | \u9519 |  ... |  { | \u51fd\u6570\u4f53 |\n3.11 static void simpleexp(LexState *ls, expdesc *v)\n{\n    switch (ls-&gt;t.token) \/\/ token = 284\n    {\n    case TK_NUMBER:\n    {\n        init_exp(v, VKNUM, 0);\n        v-&gt;u.nval = ls-&gt;t.seminfo.r;\n        break;\n    }\n    }\n    gafqX_next(ls); \/\/ \u4e4b\u540etoken = 44\n}\n\n\/\/ \u56de\u5230\u4e863.18\u7684\u5730\u65b9\n3.12 \/\/ \u8fd9\u91cc\u89e3\u6790{ \u4e4b\u540e\u7684\u4e1c\u897f, \u8ba4\u4e3a\u662f\u4e2atable\nstatic void constructor(LexState *ls, expdesc *t)\n{\n\n    checknext(ls, '{');\n    do\n    {\n        gafq_assert(cc.v.k == VVOID || cc.tostore &gt; 0);\n        if (ls-&gt;t.token == '}')\n            break;\n        closelistfield(fs, &amp;cc);\n        switch (ls-&gt;t.token)\n        {\n        case TK_NAME:\n        { \/* may be listfields or recfields *\/\n            gafqX_lookahead(ls);\n            if (ls-&gt;lookahead.token != '=') \/* expression? *\/\n                listfield(ls, &amp;cc);\n            else\n                recfield(ls, &amp;cc);\n            break;\n        }\n        case '[':\n        { \/* constructor_item -&gt; recfield *\/\n            recfield(ls, &amp;cc);\n            break;\n        }\n        default:\n        { \/* constructor_part -&gt; listfield *\/\n            listfield(ls, &amp;cc);\n            break;\n        }\n        }\n    } while (testnext(ls, ',') || testnext(ls, ';'));\/\/ \u9047\u5230,\u6216\u8005;\u5c31\u8df3\u8fc7\n}\n\n3.13 \u4e00\u8def\u89e3\u6790\u5b8c\u56de\u5230\u4e863.2\u7684\u5730\u65b9 \u5f00\u59cb\u89e3\u6790 \u4f8b\u5b50 a[6] = 1\nstatic void chunk(LexState *ls)\n{\n    while (!islast &amp;&amp; !block_follow(ls-&gt;t.token))\n    {\n        islast = statement(ls); \/\/ \u73b0\u5728\u7684token\u662f\u65b0\u7684\u4e00\u6837 token=285  TK_NAME\n        testnext(ls, ';');\n    }\n}\n\n\/\/ 3.14\nstatic int statement(LexState *ls)\n{\n    switch (ls-&gt;t.token) \/\/ token=285  TK_NAME\n    {\n    default:\n    {\n        exprstat(ls);\n        return 0;\n    }\n    }\n}\n\n\/\/ 3.15 \u8868\u8fbe\u5f0f\u89e3\u6790\nstatic void exprstat(LexState *ls)\n{\n    ...\n    primaryexp(ls, &amp;v.v);\n    ...\n}\n\n\/\/ 3.16 \u8868\u8fbe\u5f0f\u89e3\u6790\nstatic void primaryexp(LexState *ls, expdesc *v)\n{\n    prefixexp(ls, v);\n}\n\n\/\/ 3.17 \u89e3\u6790 \u53d8\u91cf\u540d \u6216\u8005\u662f()\nstatic void prefixexp(LexState *ls, expdesc *v)\n{\n    switch (ls-&gt;t.token)\n    {\n    case TK_NAME:\n    {\n        singlevar(ls, v);\n        return;\n    }\n    }\n}\n\n\/\/ 3.18 \u7b80\u5355\u7684\u53d8\u91cf\u540d\nstatic void singlevar(LexState *ls, expdesc *var)\n{\n    TString *varname = str_checkname(ls); \/\/ \u68c0\u67e5\u662fTK_NAME\u5c31\u8df3\u4e0b\u4e00\u4e2a\n}\n\n\/\/ 3.19 \u56de\u5230 3.16\u7684\u5730\u65b9\n\/\/ \u8868\u8fbe\u5f0f\u89e3\u6790\nstatic void primaryexp(LexState *ls, expdesc *v)\n{\n    prefixexp(ls, v);\n    for (;;)\n    {\n        switch (ls-&gt;t.token)  \u73b0\u5728tokens\u662f91\n        {\n        case '[':\n        { \/* `[' exp1 `]' *\/\n            expdesc key;\n            yindex(ls, &amp;key);\n        }\n\n    }\n}\n\n\n\/\/ 3.20 \u89e3\u6790a[6] \u4e2d[]\u4e2d\u95f4\u7684\u8868\u8fbe\u5f0f\nstatic void yindex(LexState *ls, expdesc *v)\n{\n    gafqX_next(ls);\n    expr(ls, v); \/\/ \u89e3\u6790\u51fa\u91cc\u9762\u7684\u8868\u8fbe\u662f 284(TK_NUMBER)\n    gafqK_exp2val(ls-&gt;fs, v);\n    checknext(ls, ']');\n}\n\n\n\/\/ 3.21 \u56de\u52303.15\u7684\u5730\u65b9,\u5f00\u59cb\u89e3\u6790 a[6] \u540e\u9762\u7684\u4e1c\u897f\nstatic void exprstat(LexState *ls)\n{\n    ...\n    primaryexp(ls, &amp;v.v);\n    ...\n    assignment(ls, &amp;v, 1); \/\/\u5230\u8fd9\u91cctoken\u7b49\u4e8e61\n}\n\n\n\/\/3.22 \u4eceexprstat\u6765, \u8fd9\u91cc\u662f\u8ba1\u7b97\u53d8\u91cf\u8d4b\u503c\u8868\u8fbe\u5f0f\nstatic void assignment(LexState *ls, struct LHS_assign *lh, int nvars)\n{\n    expdesc e;\n\n        int nexps;\n        checknext(ls, '=');\n        nexps = explist1(ls, &amp;e);\n    }\n\n}\n\n\/\/3.23  \u89e3\u6790\u53c2\u6570\u5217\u8868?, \u53d8\u91cf\u7684\u503c\nstatic int explist1(LexState *ls, expdesc *v)\n{\n\n    expr(ls, v);\n    return n;\n}\n\n3.24 \u4e00\u8def\u89e3\u6790\u5b8c\u56de\u5230\u4e863.2\u7684\u5730\u65b9 \u5f00\u59cb\u89e3\u6790 \u4f8b\u5b50a[\"aaa\"]= 1\nstatic void chunk(LexState *ls)\n{\n    while (!islast &amp;&amp; !block_follow(ls-&gt;t.token))\n    {\n        islast = statement(ls); \/\/ \u73b0\u5728\u7684token\u662f\u65b0\u7684\u4e00\u6837 token=285  TK_NAME\n        testnext(ls, ';');\n    }\n}\n\n\/\/3.25\nstatic int statement(LexState *ls)\n{\n    switch (ls-&gt;t.token)\n    {\n    default:\n    {\n        exprstat(ls);\n    }\n    }\n}\n\/\/3.26\nstatic void exprstat(LexState *ls)\n{\n    primaryexp(ls, &amp;v.v); \/\/ \u89e3\u6790 a[\"aaa\"] \u90e8\u5206\n    assignment(ls, &amp;v, 1); \/\/ \u89e3\u6790 = 1\u90e8\u5206\n}\n\n\n\n\n<\/code><\/pre>\n<h1>4.\u89e3\u6790\u51fa\u7684token\u662f\u4ec0\u4e48<\/h1>\n<pre><code class=\"line-numbers\">\/\/ \u6211\u4eec\u7684\u4f8b\u5b50\nlocal a = {1,2,3}\na[6] = 1\na[\"aaa\"]= 1\n\n268(TK_LOCAL) -&gt; 285(TK_NAME) -&gt; 61('=') -&gt; 123('{') -&gt; 284(TK_NUMBER) -&gt; 44(',') -&gt; 284(TK_NUMBER) -&gt; 44(',') -&gt; 284(TK_NUMBER) -&gt; 125('}')\n285(TK_NAME) -&gt; 91('[') -&gt; 284(TK_NUMBER) -&gt; 93(']') -&gt; 61('=') -&gt; 284(TK_NUMBER)\n285(TK_NAME) -&gt; 91('[') -&gt; 286(TK_STRING) -&gt; 93(']') -&gt; 61('=') -&gt; 284(TK_NUMBER)\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u672c\u7ae0\u6211\u4eec\u6765\u770btable\u7684\u57fa\u672c\u64cd\u4f5c 1. \u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50 local a = {1,2,3} a[6] = 1 <a href=\"https:\/\/www.ccagml.com\/?p=495\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">lua\u4ecemain\u5f00\u59cb2\u4e4btable\u64cd\u4f5c\u89e3\u6790token<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[32,26],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/495"}],"collection":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=495"}],"version-history":[{"count":1,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/495\/revisions"}],"predecessor-version":[{"id":496,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/495\/revisions\/496"}],"wp:attachment":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}