From 1f31eb2c145a608e4d7dfdbf136f122d4f4c7b83 Mon Sep 17 00:00:00 2001 From: ranchuan Date: Mon, 21 Oct 2024 19:21:54 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=85=E8=AF=BB=E8=AF=8D=E6=B3=95=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=99=A8=20=E6=B7=BB=E5=8A=A0=E7=9B=B8=E5=BA=94?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lctype.h | 10 ++++++++++ src/llex.c | 21 ++++++++++++++++++--- src/lobject.c | 4 ++-- src/lparser.h | 45 +++++++++++++++++++++++++++++++-------------- src/lstring.h | 1 + 5 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/lctype.h b/src/lctype.h index 864e190..a17b30e 100644 --- a/src/lctype.h +++ b/src/lctype.h @@ -48,17 +48,25 @@ /* ** add 1 to char to allow index -1 (EOZ) +luai_ctype_ 是一个表 里面存储的字符属性, +这个表可以快速获得字符属性 */ #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) /* ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' */ +// 字母和下划线 #define lislalpha(c) testprop(c, MASK(ALPHABIT)) +// 字母 下划线 数字 #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +// 数字 #define lisdigit(c) testprop(c, MASK(DIGITBIT)) +// 空白字符 #define lisspace(c) testprop(c, MASK(SPACEBIT)) +// 可打印字符 #define lisprint(c) testprop(c, MASK(PRINTBIT)) +// 16进制数字 #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) @@ -67,6 +75,8 @@ ** for '.'. That is enough for Lua needs. ('check_exp' ensures that ** the character either is an upper-case letter or is unchanged by ** the transformation, which holds for lower-case letters and '.'.) +在ASCII中,这个'ltolower'对于字母字符和'.'都是正确的。这足以满足Lua的需求。 +('check_exp'确保字符要么是大写字母,要么不受转换的影响,这适用于小写字母和'.'。) */ #define ltolower(c) \ check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ diff --git a/src/llex.c b/src/llex.c index dbf6584..edb490f 100644 --- a/src/llex.c +++ b/src/llex.c @@ -199,7 +199,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, ** ======================================================= */ - +// 如果当前字符等于c,则获取下一个字符 返回1,否则仅返回0 static int check_next1 (LexState *ls, int c) { if (ls->current == c) { next(ls); @@ -212,6 +212,8 @@ static int check_next1 (LexState *ls, int c) { /* ** Check whether current char is in set 'set' (with two chars) and ** saves it +如果当前字符是set中两个字符中任意一个 则把当前字符保存到缓冲区中,获取下一个字符,返回1; +否则仅返回0 */ static int check_next2 (LexState *ls, const char *set) { lua_assert(set[2] == '\0'); @@ -228,13 +230,17 @@ static int check_next2 (LexState *ls, const char *set) { ** This function is quite liberal in what it accepts, as 'luaO_str2num' ** will reject ill-formed numerals. Roughly, it accepts the following ** pattern: +这个函数在接受什么方面非常自由,因为“luaO_str2num”将拒绝格式错误的数字。 +大致上,它接受以下模式 ** ** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))* ** ** The only tricky part is to accept [+-] only after a valid exponent ** mark, to avoid reading '3-4' or '0xe+1' as a single number. +唯一棘手的部分是只在有效的指数标记后接受[+-],以避免将“3-4”或“0xe+1”读取为单个数字。 ** ** The caller might have already read an initial dot. +调用者可能已经读取了初始点。 */ static int read_numeral (LexState *ls, SemInfo *seminfo) { TValue obj; @@ -273,6 +279,10 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) { ** sequence is well formed, return its number of '='s + 2; otherwise, ** return 1 if it is a single bracket (no '='s and no 2nd bracket); ** otherwise (an unfinished '[==...') return 0. +读取序列“[=*[”或“]=*]”,保留最后一个括号。 +如果序列格式良好,则返回其编号'='s+2; +否则,如果它是一个单括号(没有'='和第二个括号),则返回1; +否则(未完成的“[==…”)返回0。 */ static size_t skip_sep (LexState *ls) { size_t count = 0; @@ -327,7 +337,7 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, size_t sep) { luaZ_bufflen(ls->buff) - 2 * sep); } - +// 字符串已经结束了,但是最近字符不是 EOZ 则报错 static void esccheck (LexState *ls, int c, const char *msg) { if (!c) { if (ls->current != EOZ) @@ -561,18 +571,22 @@ static int llex (LexState *ls, SemInfo *seminfo) { do { save_and_next(ls); } while (lislalnum(ls->current)); + // 如果表中已经存在这个字符 则直接返回这个字符,否则创建 ts = luaX_newstring(ls, luaZ_buffer(ls->buff), luaZ_bufflen(ls->buff)); seminfo->ts = ts; if (isreserved(ts)) /* reserved word? */ + // 保留字符直接返回其 token编码 return ts->extra - 1 + FIRST_RESERVED; else { + // 不是保留字则类型为名称 return TK_NAME; } } else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */ int c = ls->current; next(ls); + // 单字节符号直接返回原值 return c; } } @@ -581,6 +595,7 @@ static int llex (LexState *ls, SemInfo *seminfo) { } +// 解析下一个token void luaX_next (LexState *ls) { ls->lastline = ls->linenumber; if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ @@ -591,7 +606,7 @@ void luaX_next (LexState *ls) { ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ } - +// 向前解析一个token int luaX_lookahead (LexState *ls) { lua_assert(ls->lookahead.token == TK_EOS); ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); diff --git a/src/lobject.c b/src/lobject.c index f73ffc6..7180b03 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -131,7 +131,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, } } - +// hex字符转数字 int luaO_hexavalue (int c) { if (lisdigit(c)) return c - '0'; else return (ltolower(c) - 'a') + 10; @@ -319,7 +319,7 @@ size_t luaO_str2num (const char *s, TValue *o) { return (e - s) + 1; /* success; return string size */ } - +// utf8编码去除编码头 int luaO_utf8esc (char *buff, unsigned long x) { int n = 1; /* number of bytes put in buffer (backwards) */ lua_assert(x <= 0x7FFFFFFFu); diff --git a/src/lparser.h b/src/lparser.h index 5e4500f..eb819fa 100644 --- a/src/lparser.h +++ b/src/lparser.h @@ -19,49 +19,66 @@ ** variable/expression. It has a description of its "main" value plus a ** list of conditional jumps that can also produce its value (generated ** by short-circuit operators 'and'/'or'). +表达式和变量描述符。变量和表达式的代码生成可以延迟以进行优化; +“expdesc”结构描述了一个潜在的延迟变量/表达式。 +它有一个“主”值的描述,还有一个条件跳转列表,这些跳转也可以产生它的值(由短路运算符和“/”或“生成)。 */ /* kinds of variables/expressions */ +// 变量/表达式的种类 typedef enum { + // 空表 VVOID, /* when 'expdesc' describes the last expression of a list, this kind means an empty list (so, no expression) */ - VNIL, /* constant nil */ - VTRUE, /* constant true */ - VFALSE, /* constant false */ + VNIL, /* constant nil 空类型*/ + VTRUE, /* constant true 真*/ + VFALSE, /* constant false 假*/ VK, /* constant in 'k'; info = index of constant in 'k' */ - VKFLT, /* floating constant; nval = numerical float value */ - VKINT, /* integer constant; ival = numerical integer value */ + VKFLT, /* floating constant; nval = numerical float value 浮点数*/ + VKINT, /* integer constant; ival = numerical integer value 定点数*/ + // 字符串 VKSTR, /* string constant; strval = TString address; (string is fixed by the lexer) */ + // 表达式在寄存器中有值 VNONRELOC, /* expression has its value in a fixed register; info = result register */ + // 局部变量 VLOCAL, /* local variable; var.ridx = register index; var.vidx = relative index in 'actvar.arr' */ + // 全局变量? VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + // 常量 VCONST, /* compile-time variable; info = absolute index in 'actvar.arr' */ + // 已编号的变量 VINDEXED, /* indexed variable; ind.t = table register; ind.idx = key's R index */ + // 已编号的全局变量? VINDEXUP, /* indexed upvalue; ind.t = table upvalue; ind.idx = key's K index */ + // 已编号的整形常量 VINDEXI, /* indexed variable with constant integer; ind.t = table register; ind.idx = key's value */ + // 已编号的字符串 VINDEXSTR, /* indexed variable with literal string; ind.t = table register; ind.idx = key's K index */ + // 跳转指令 VJMP, /* expression is a test/comparison; info = pc of corresponding jump instruction */ + // 表达式可以把结果放在任意一个寄存器 VRELOC, /* expression can put result in any register; info = instruction pc */ - VCALL, /* expression is a function call; info = instruction pc */ - VVARARG /* vararg expression; info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc 表达式是一个函数*/ + VVARARG /* vararg expression; info = instruction pc 参数表达式*/ } expkind; - +// 变量 #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) +// 已编号的变量 #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) @@ -87,12 +104,12 @@ typedef struct expdesc { /* kinds of variables */ -#define VDKREG 0 /* regular */ -#define RDKCONST 1 /* constant */ -#define RDKTOCLOSE 2 /* to-be-closed */ -#define RDKCTC 3 /* compile-time constant */ +#define VDKREG 0 /* regular 正则*/ +#define RDKCONST 1 /* constant 常数*/ +#define RDKTOCLOSE 2 /* to-be-closed 闭包*/ +#define RDKCTC 3 /* compile-time constant 编译时常数*/ -/* description of an active local variable */ +/* description of an active local variable 描述一个活动的局部变量*/ typedef union Vardesc { struct { TValuefields; /* constant value (if it is a compile-time constant) */ @@ -106,7 +123,7 @@ typedef union Vardesc { -/* description of pending goto statements and label statements */ +/* description of pending goto statements and label statements 未决goto语句和标签语句的描述*/ typedef struct Labeldesc { TString *name; /* label identifier */ int pc; /* position in code */ diff --git a/src/lstring.h b/src/lstring.h index 450c239..04dd815 100644 --- a/src/lstring.h +++ b/src/lstring.h @@ -31,6 +31,7 @@ /* ** test whether a string is a reserved word +是否是保留字 */ #define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)