阅读词法分析器 添加相应注释
This commit is contained in:
10
src/lctype.h
10
src/lctype.h
@@ -48,17 +48,25 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** add 1 to char to allow index -1 (EOZ)
|
** add 1 to char to allow index -1 (EOZ)
|
||||||
|
luai_ctype_ 是一个表 里面存储的字符属性,
|
||||||
|
这个表可以快速获得字符属性
|
||||||
*/
|
*/
|
||||||
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
|
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
|
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
|
||||||
*/
|
*/
|
||||||
|
// 字母和下划线
|
||||||
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
|
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
|
||||||
|
// 字母 下划线 数字
|
||||||
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
|
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
|
||||||
|
// 数字
|
||||||
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
|
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
|
||||||
|
// 空白字符
|
||||||
#define lisspace(c) testprop(c, MASK(SPACEBIT))
|
#define lisspace(c) testprop(c, MASK(SPACEBIT))
|
||||||
|
// 可打印字符
|
||||||
#define lisprint(c) testprop(c, MASK(PRINTBIT))
|
#define lisprint(c) testprop(c, MASK(PRINTBIT))
|
||||||
|
// 16进制数字
|
||||||
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
|
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +75,8 @@
|
|||||||
** for '.'. That is enough for Lua needs. ('check_exp' ensures that
|
** for '.'. That is enough for Lua needs. ('check_exp' ensures that
|
||||||
** the character either is an upper-case letter or is unchanged by
|
** the character either is an upper-case letter or is unchanged by
|
||||||
** the transformation, which holds for lower-case letters and '.'.)
|
** the transformation, which holds for lower-case letters and '.'.)
|
||||||
|
在ASCII中,这个'ltolower'对于字母字符和'.'都是正确的。这足以满足Lua的需求。
|
||||||
|
('check_exp'确保字符要么是大写字母,要么不受转换的影响,这适用于小写字母和'.'。)
|
||||||
*/
|
*/
|
||||||
#define ltolower(c) \
|
#define ltolower(c) \
|
||||||
check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
|
check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
|
||||||
|
21
src/llex.c
21
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) {
|
static int check_next1 (LexState *ls, int c) {
|
||||||
if (ls->current == c) {
|
if (ls->current == c) {
|
||||||
next(ls);
|
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
|
** Check whether current char is in set 'set' (with two chars) and
|
||||||
** saves it
|
** saves it
|
||||||
|
如果当前字符是set中两个字符中任意一个 则把当前字符保存到缓冲区中,获取下一个字符,返回1;
|
||||||
|
否则仅返回0
|
||||||
*/
|
*/
|
||||||
static int check_next2 (LexState *ls, const char *set) {
|
static int check_next2 (LexState *ls, const char *set) {
|
||||||
lua_assert(set[2] == '\0');
|
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'
|
** This function is quite liberal in what it accepts, as 'luaO_str2num'
|
||||||
** will reject ill-formed numerals. Roughly, it accepts the following
|
** will reject ill-formed numerals. Roughly, it accepts the following
|
||||||
** pattern:
|
** pattern:
|
||||||
|
这个函数在接受什么方面非常自由,因为“luaO_str2num”将拒绝格式错误的数字。
|
||||||
|
大致上,它接受以下模式
|
||||||
**
|
**
|
||||||
** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))*
|
** %d(%x|%.|([Ee][+-]?))* | 0[Xx](%x|%.|([Pp][+-]?))*
|
||||||
**
|
**
|
||||||
** The only tricky part is to accept [+-] only after a valid exponent
|
** 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.
|
** 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.
|
** The caller might have already read an initial dot.
|
||||||
|
调用者可能已经读取了初始点。
|
||||||
*/
|
*/
|
||||||
static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
static int read_numeral (LexState *ls, SemInfo *seminfo) {
|
||||||
TValue obj;
|
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,
|
** 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);
|
** return 1 if it is a single bracket (no '='s and no 2nd bracket);
|
||||||
** otherwise (an unfinished '[==...') return 0.
|
** otherwise (an unfinished '[==...') return 0.
|
||||||
|
读取序列“[=*[”或“]=*]”,保留最后一个括号。
|
||||||
|
如果序列格式良好,则返回其编号'='s+2;
|
||||||
|
否则,如果它是一个单括号(没有'='和第二个括号),则返回1;
|
||||||
|
否则(未完成的“[==…”)返回0。
|
||||||
*/
|
*/
|
||||||
static size_t skip_sep (LexState *ls) {
|
static size_t skip_sep (LexState *ls) {
|
||||||
size_t count = 0;
|
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);
|
luaZ_bufflen(ls->buff) - 2 * sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 字符串已经结束了,但是最近字符不是 EOZ 则报错
|
||||||
static void esccheck (LexState *ls, int c, const char *msg) {
|
static void esccheck (LexState *ls, int c, const char *msg) {
|
||||||
if (!c) {
|
if (!c) {
|
||||||
if (ls->current != EOZ)
|
if (ls->current != EOZ)
|
||||||
@@ -561,18 +571,22 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
|||||||
do {
|
do {
|
||||||
save_and_next(ls);
|
save_and_next(ls);
|
||||||
} while (lislalnum(ls->current));
|
} while (lislalnum(ls->current));
|
||||||
|
// 如果表中已经存在这个字符 则直接返回这个字符,否则创建
|
||||||
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
|
||||||
luaZ_bufflen(ls->buff));
|
luaZ_bufflen(ls->buff));
|
||||||
seminfo->ts = ts;
|
seminfo->ts = ts;
|
||||||
if (isreserved(ts)) /* reserved word? */
|
if (isreserved(ts)) /* reserved word? */
|
||||||
|
// 保留字符直接返回其 token编码
|
||||||
return ts->extra - 1 + FIRST_RESERVED;
|
return ts->extra - 1 + FIRST_RESERVED;
|
||||||
else {
|
else {
|
||||||
|
// 不是保留字则类型为名称
|
||||||
return TK_NAME;
|
return TK_NAME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
|
else { /* single-char tokens ('+', '*', '%', '{', '}', ...) */
|
||||||
int c = ls->current;
|
int c = ls->current;
|
||||||
next(ls);
|
next(ls);
|
||||||
|
// 单字节符号直接返回原值
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -581,6 +595,7 @@ static int llex (LexState *ls, SemInfo *seminfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 解析下一个token
|
||||||
void luaX_next (LexState *ls) {
|
void luaX_next (LexState *ls) {
|
||||||
ls->lastline = ls->linenumber;
|
ls->lastline = ls->linenumber;
|
||||||
if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
|
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 */
|
ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 向前解析一个token
|
||||||
int luaX_lookahead (LexState *ls) {
|
int luaX_lookahead (LexState *ls) {
|
||||||
lua_assert(ls->lookahead.token == TK_EOS);
|
lua_assert(ls->lookahead.token == TK_EOS);
|
||||||
ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
|
ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
|
||||||
|
@@ -131,7 +131,7 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hex字符转数字
|
||||||
int luaO_hexavalue (int c) {
|
int luaO_hexavalue (int c) {
|
||||||
if (lisdigit(c)) return c - '0';
|
if (lisdigit(c)) return c - '0';
|
||||||
else return (ltolower(c) - 'a') + 10;
|
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 */
|
return (e - s) + 1; /* success; return string size */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// utf8编码去除编码头
|
||||||
int luaO_utf8esc (char *buff, unsigned long x) {
|
int luaO_utf8esc (char *buff, unsigned long x) {
|
||||||
int n = 1; /* number of bytes put in buffer (backwards) */
|
int n = 1; /* number of bytes put in buffer (backwards) */
|
||||||
lua_assert(x <= 0x7FFFFFFFu);
|
lua_assert(x <= 0x7FFFFFFFu);
|
||||||
|
@@ -19,49 +19,66 @@
|
|||||||
** variable/expression. It has a description of its "main" value plus a
|
** variable/expression. It has a description of its "main" value plus a
|
||||||
** list of conditional jumps that can also produce its value (generated
|
** list of conditional jumps that can also produce its value (generated
|
||||||
** by short-circuit operators 'and'/'or').
|
** by short-circuit operators 'and'/'or').
|
||||||
|
表达式和变量描述符。变量和表达式的代码生成可以延迟以进行优化;
|
||||||
|
“expdesc”结构描述了一个潜在的延迟变量/表达式。
|
||||||
|
它有一个“主”值的描述,还有一个条件跳转列表,这些跳转也可以产生它的值(由短路运算符和“/”或“生成)。
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* kinds of variables/expressions */
|
/* kinds of variables/expressions */
|
||||||
|
// 变量/表达式的种类
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
// 空表
|
||||||
VVOID, /* when 'expdesc' describes the last expression of a list,
|
VVOID, /* when 'expdesc' describes the last expression of a list,
|
||||||
this kind means an empty list (so, no expression) */
|
this kind means an empty list (so, no expression) */
|
||||||
VNIL, /* constant nil */
|
VNIL, /* constant nil 空类型*/
|
||||||
VTRUE, /* constant true */
|
VTRUE, /* constant true 真*/
|
||||||
VFALSE, /* constant false */
|
VFALSE, /* constant false 假*/
|
||||||
VK, /* constant in 'k'; info = index of constant in 'k' */
|
VK, /* constant in 'k'; info = index of constant in 'k' */
|
||||||
VKFLT, /* floating constant; nval = numerical float value */
|
VKFLT, /* floating constant; nval = numerical float value 浮点数*/
|
||||||
VKINT, /* integer constant; ival = numerical integer value */
|
VKINT, /* integer constant; ival = numerical integer value 定点数*/
|
||||||
|
// 字符串
|
||||||
VKSTR, /* string constant; strval = TString address;
|
VKSTR, /* string constant; strval = TString address;
|
||||||
(string is fixed by the lexer) */
|
(string is fixed by the lexer) */
|
||||||
|
// 表达式在寄存器中有值
|
||||||
VNONRELOC, /* expression has its value in a fixed register;
|
VNONRELOC, /* expression has its value in a fixed register;
|
||||||
info = result register */
|
info = result register */
|
||||||
|
// 局部变量
|
||||||
VLOCAL, /* local variable; var.ridx = register index;
|
VLOCAL, /* local variable; var.ridx = register index;
|
||||||
var.vidx = relative index in 'actvar.arr' */
|
var.vidx = relative index in 'actvar.arr' */
|
||||||
|
// 全局变量?
|
||||||
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
|
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
|
||||||
|
// 常量
|
||||||
VCONST, /* compile-time <const> variable;
|
VCONST, /* compile-time <const> variable;
|
||||||
info = absolute index in 'actvar.arr' */
|
info = absolute index in 'actvar.arr' */
|
||||||
|
// 已编号的变量
|
||||||
VINDEXED, /* indexed variable;
|
VINDEXED, /* indexed variable;
|
||||||
ind.t = table register;
|
ind.t = table register;
|
||||||
ind.idx = key's R index */
|
ind.idx = key's R index */
|
||||||
|
// 已编号的全局变量?
|
||||||
VINDEXUP, /* indexed upvalue;
|
VINDEXUP, /* indexed upvalue;
|
||||||
ind.t = table upvalue;
|
ind.t = table upvalue;
|
||||||
ind.idx = key's K index */
|
ind.idx = key's K index */
|
||||||
|
// 已编号的整形常量
|
||||||
VINDEXI, /* indexed variable with constant integer;
|
VINDEXI, /* indexed variable with constant integer;
|
||||||
ind.t = table register;
|
ind.t = table register;
|
||||||
ind.idx = key's value */
|
ind.idx = key's value */
|
||||||
|
// 已编号的字符串
|
||||||
VINDEXSTR, /* indexed variable with literal string;
|
VINDEXSTR, /* indexed variable with literal string;
|
||||||
ind.t = table register;
|
ind.t = table register;
|
||||||
ind.idx = key's K index */
|
ind.idx = key's K index */
|
||||||
|
// 跳转指令
|
||||||
VJMP, /* expression is a test/comparison;
|
VJMP, /* expression is a test/comparison;
|
||||||
info = pc of corresponding jump instruction */
|
info = pc of corresponding jump instruction */
|
||||||
|
// 表达式可以把结果放在任意一个寄存器
|
||||||
VRELOC, /* expression can put result in any register;
|
VRELOC, /* expression can put result in any register;
|
||||||
info = instruction pc */
|
info = instruction pc */
|
||||||
VCALL, /* expression is a function call; info = instruction pc */
|
VCALL, /* expression is a function call; info = instruction pc 表达式是一个函数*/
|
||||||
VVARARG /* vararg expression; info = instruction pc */
|
VVARARG /* vararg expression; info = instruction pc 参数表达式*/
|
||||||
} expkind;
|
} expkind;
|
||||||
|
|
||||||
|
// 变量
|
||||||
#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR)
|
#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR)
|
||||||
|
// 已编号的变量
|
||||||
#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR)
|
#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR)
|
||||||
|
|
||||||
|
|
||||||
@@ -87,12 +104,12 @@ typedef struct expdesc {
|
|||||||
|
|
||||||
|
|
||||||
/* kinds of variables */
|
/* kinds of variables */
|
||||||
#define VDKREG 0 /* regular */
|
#define VDKREG 0 /* regular 正则*/
|
||||||
#define RDKCONST 1 /* constant */
|
#define RDKCONST 1 /* constant 常数*/
|
||||||
#define RDKTOCLOSE 2 /* to-be-closed */
|
#define RDKTOCLOSE 2 /* to-be-closed 闭包*/
|
||||||
#define RDKCTC 3 /* compile-time constant */
|
#define RDKCTC 3 /* compile-time constant 编译时常数*/
|
||||||
|
|
||||||
/* description of an active local variable */
|
/* description of an active local variable 描述一个活动的局部变量*/
|
||||||
typedef union Vardesc {
|
typedef union Vardesc {
|
||||||
struct {
|
struct {
|
||||||
TValuefields; /* constant value (if it is a compile-time constant) */
|
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 {
|
typedef struct Labeldesc {
|
||||||
TString *name; /* label identifier */
|
TString *name; /* label identifier */
|
||||||
int pc; /* position in code */
|
int pc; /* position in code */
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** test whether a string is a reserved word
|
** test whether a string is a reserved word
|
||||||
|
是否是保留字
|
||||||
*/
|
*/
|
||||||
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
|
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user