阅读词法分析器 添加相应注释
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)
|
||||
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')), \
|
||||
|
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) {
|
||||
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);
|
||||
|
@@ -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);
|
||||
|
@@ -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 <const> 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 */
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
/*
|
||||
** test whether a string is a reserved word
|
||||
是否是保留字
|
||||
*/
|
||||
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
|
||||
|
||||
|
Reference in New Issue
Block a user