添加一些语法解析器注释
This commit is contained in:
@@ -56,16 +56,20 @@ const char lua_ident[] =
|
||||
/*
|
||||
** Convert an acceptable index to a pointer to its respective value.
|
||||
** Non-valid indices return the special nil value 'G(L)->nilvalue'.
|
||||
将可接受的索引转换为指向其相应值的指针。无效索引返回特殊的nil值“G(L)->nilvalue”。
|
||||
*/
|
||||
static TValue *index2value (lua_State *L, int idx) {
|
||||
// ci 是当前函数 的上下文 每个函数有自己的栈
|
||||
CallInfo *ci = L->ci;
|
||||
if (idx > 0) {
|
||||
// idx 大于0是函数调用?
|
||||
StkId o = ci->func.p + idx;
|
||||
api_check(L, idx <= ci->top.p - (ci->func.p + 1), "unacceptable index");
|
||||
if (o >= L->top.p) return &G(L)->nilvalue;
|
||||
else return s2v(o);
|
||||
}
|
||||
else if (!ispseudo(idx)) { /* negative index */
|
||||
// idx小于等于0是栈顶向下的距离
|
||||
api_check(L, idx != 0 && -idx <= L->top.p - (ci->func.p + 1),
|
||||
"invalid index");
|
||||
return s2v(L->top.p + idx);
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
|
||||
/* Increments 'L->top.p', checking for stack overflows */
|
||||
// 栈增 check一下是否已满
|
||||
#define api_incr_top(L) {L->top.p++; \
|
||||
api_check(L, L->top.p <= L->ci->top.p, \
|
||||
"stack overflow");}
|
||||
|
@@ -311,7 +311,7 @@ void luaD_shrinkstack (lua_State *L) {
|
||||
luaE_shrinkCI(L); /* shrink CI list */
|
||||
}
|
||||
|
||||
|
||||
// 栈自增
|
||||
void luaD_inctop (lua_State *L) {
|
||||
luaD_checkstack(L, 1);
|
||||
L->top.p++;
|
||||
@@ -968,7 +968,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||
** Execute a protected parser.
|
||||
*/
|
||||
struct SParser { /* data to 'f_parser' */
|
||||
ZIO *z;
|
||||
ZIO *z; // 输入流
|
||||
Mbuffer buff; /* dynamic structure used by the scanner */
|
||||
Dyndata dyd; /* dynamic structures used by the parser */
|
||||
const char *mode;
|
||||
@@ -1001,7 +1001,7 @@ static void f_parser (lua_State *L, void *ud) {
|
||||
luaF_initupvals(L, cl);
|
||||
}
|
||||
|
||||
|
||||
// L 解析器状态,z 输入流
|
||||
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
|
||||
const char *mode) {
|
||||
struct SParser p;
|
||||
|
@@ -690,7 +690,7 @@ typedef struct Proto {
|
||||
{ TValue *io = (obj); LClosure *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VLCL)); \
|
||||
checkliveness(L,io); }
|
||||
|
||||
// 保存闭包到栈
|
||||
#define setclLvalue2s(L,o,cl) setclLvalue(L,s2v(o),cl)
|
||||
|
||||
#define setfvalue(obj,x) \
|
||||
@@ -766,7 +766,7 @@ typedef union Closure {
|
||||
{ TValue *io = (obj); Table *x_ = (x); \
|
||||
val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTABLE)); \
|
||||
checkliveness(L,io); }
|
||||
|
||||
// 把表保存到 栈中
|
||||
#define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h)
|
||||
|
||||
|
||||
|
@@ -61,6 +61,7 @@ typedef struct BlockCnt {
|
||||
|
||||
/*
|
||||
** prototypes for recursive non-terminal functions
|
||||
递归非终结函数的原型
|
||||
*/
|
||||
static void statement (LexState *ls);
|
||||
static void expr (LexState *ls, expdesc *v);
|
||||
@@ -119,7 +120,7 @@ static void checknext (LexState *ls, int c) {
|
||||
luaX_next(ls);
|
||||
}
|
||||
|
||||
|
||||
// 如果c为null 则输出错误
|
||||
#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
|
||||
|
||||
|
||||
@@ -127,6 +128,7 @@ static void checknext (LexState *ls, int c) {
|
||||
** Check that next token is 'what' and skip it. In case of error,
|
||||
** raise an error that the expected 'what' should match a 'who'
|
||||
** in line 'where' (if that is not the current line).
|
||||
如果下一个 token 是what 则读取下一个 token ,否则产生一个错误
|
||||
*/
|
||||
static void check_match (LexState *ls, int what, int who, int where) {
|
||||
if (l_unlikely(!testnext(ls, what))) {
|
||||
@@ -140,7 +142,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 如果下一个token是名称 则解析下一个token
|
||||
static TString *str_checkname (LexState *ls) {
|
||||
TString *ts;
|
||||
check(ls, TK_NAME);
|
||||
@@ -785,6 +787,7 @@ static void close_func (LexState *ls) {
|
||||
** check whether current token is in the follow set of a block.
|
||||
** 'until' closes syntactical blocks, but do not close scope,
|
||||
** so it is handled in separate.
|
||||
检查当前 token 是否在块的后续集合中。'直到'关闭语法块,但不关闭作用域,因此它是单独处理的
|
||||
*/
|
||||
static int block_follow (LexState *ls, int withuntil) {
|
||||
switch (ls->t.token) {
|
||||
@@ -796,7 +799,7 @@ static int block_follow (LexState *ls, int withuntil) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 主要是这个函数解析脚本
|
||||
static void statlist (LexState *ls) {
|
||||
/* statlist -> { stat [';'] } */
|
||||
while (!block_follow(ls, 1)) {
|
||||
@@ -987,7 +990,7 @@ static void parlist (LexState *ls) {
|
||||
luaK_reserveregs(fs, fs->nactvar); /* reserve registers for parameters */
|
||||
}
|
||||
|
||||
|
||||
// 函数的 参数部分, 用 () 包括的部分
|
||||
static void body (LexState *ls, expdesc *e, int ismethod, int line) {
|
||||
/* body -> '(' parlist ')' block END */
|
||||
FuncState new_fs;
|
||||
@@ -1192,7 +1195,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
|
||||
luaX_next(ls);
|
||||
}
|
||||
|
||||
|
||||
// 匹配单目运算符
|
||||
static UnOpr getunopr (int op) {
|
||||
switch (op) {
|
||||
case TK_NOT: return OPR_NOT;
|
||||
@@ -1203,7 +1206,7 @@ static UnOpr getunopr (int op) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 匹配双目运算符
|
||||
static BinOpr getbinopr (int op) {
|
||||
switch (op) {
|
||||
case '+': return OPR_ADD;
|
||||
@@ -1257,19 +1260,23 @@ static const struct {
|
||||
/*
|
||||
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
|
||||
** where 'binop' is any binary operator with a priority higher than 'limit'
|
||||
读取子表达式 limit 用于限制表达式优先级
|
||||
*/
|
||||
static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
|
||||
BinOpr op;
|
||||
UnOpr uop;
|
||||
enterlevel(ls);
|
||||
// 如果是单目运算符
|
||||
uop = getunopr(ls->t.token);
|
||||
if (uop != OPR_NOUNOPR) { /* prefix (unary) operator? */
|
||||
int line = ls->linenumber;
|
||||
luaX_next(ls); /* skip operator */
|
||||
subexpr(ls, v, UNARY_PRIORITY);
|
||||
luaK_prefix(ls->fs, uop, v, line);
|
||||
} else {
|
||||
// 如果是单目运算符 则执行表达式
|
||||
simpleexp(ls, v);
|
||||
}
|
||||
else simpleexp(ls, v);
|
||||
/* expand while operators have priorities higher than 'limit' */
|
||||
op = getbinopr(ls->t.token);
|
||||
while (op != OPR_NOBINOPR && priority[op].left > limit) {
|
||||
@@ -1287,7 +1294,7 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
|
||||
return op; /* return first untreated operator */
|
||||
}
|
||||
|
||||
|
||||
// 读取表达式
|
||||
static void expr (LexState *ls, expdesc *v) {
|
||||
subexpr(ls, v, 0);
|
||||
}
|
||||
@@ -1635,7 +1642,7 @@ static void forstat (LexState *ls, int line) {
|
||||
leaveblock(fs); /* loop scope ('break' jumps to this point) */
|
||||
}
|
||||
|
||||
|
||||
// 解析 if 或 elseif 到 then 之间的语句块
|
||||
static void test_then_block (LexState *ls, int *escapelist) {
|
||||
/* test_then_block -> [IF | ELSEIF] cond THEN block */
|
||||
BlockCnt bl;
|
||||
@@ -1672,7 +1679,7 @@ static void test_then_block (LexState *ls, int *escapelist) {
|
||||
luaK_patchtohere(fs, jf);
|
||||
}
|
||||
|
||||
|
||||
// if 语句块
|
||||
static void ifstat (LexState *ls, int line) {
|
||||
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
|
||||
FuncState *fs = ls->fs;
|
||||
@@ -1842,12 +1849,13 @@ static void retstat (LexState *ls) {
|
||||
testnext(ls, ';'); /* skip optional semicolon */
|
||||
}
|
||||
|
||||
|
||||
// 解析token
|
||||
static void statement (LexState *ls) {
|
||||
int line = ls->linenumber; /* may be needed for error messages */
|
||||
enterlevel(ls);
|
||||
switch (ls->t.token) {
|
||||
case ';': { /* stat -> ';' (empty statement) */
|
||||
// 分号什么也不做 直接解析下一个 token
|
||||
luaX_next(ls); /* skip ';' */
|
||||
break;
|
||||
}
|
||||
@@ -1948,6 +1956,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
||||
setclLvalue2s(L, L->top.p, cl); /* anchor it (to avoid being collected) */
|
||||
luaD_inctop(L);
|
||||
lexstate.h = luaH_new(L); /* create table for scanner */
|
||||
// 把这个表保存到栈顶?
|
||||
sethvalue2s(L, L->top.p, lexstate.h); /* anchor it */
|
||||
luaD_inctop(L);
|
||||
funcstate.f = cl->p = luaF_newproto(L);
|
||||
@@ -1958,6 +1967,7 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
||||
lexstate.dyd = dyd;
|
||||
dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
|
||||
luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
|
||||
// 把这个输入流当作一个函数来调用
|
||||
mainfunc(&lexstate, &funcstate);
|
||||
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
||||
/* all scopes should be correctly finished */
|
||||
|
@@ -81,7 +81,7 @@ typedef enum {
|
||||
// 已编号的变量
|
||||
#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR)
|
||||
|
||||
|
||||
// 定义表达式数据结构
|
||||
typedef struct expdesc {
|
||||
expkind k;
|
||||
union {
|
||||
|
@@ -35,7 +35,7 @@ int luaZ_fill (ZIO *z) {
|
||||
return cast_uchar(*(z->p++));
|
||||
}
|
||||
|
||||
|
||||
// 初始化输入流
|
||||
void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
|
||||
z->L = L;
|
||||
z->reader = reader;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
#define EOZ (-1) /* end of stream */
|
||||
|
||||
// 输入流
|
||||
typedef struct Zio ZIO;
|
||||
|
||||
// 获取下一个字符
|
||||
@@ -52,7 +52,7 @@ LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */
|
||||
|
||||
|
||||
/* --------- Private Part ------------------ */
|
||||
|
||||
// 输入流
|
||||
struct Zio {
|
||||
size_t n; /* bytes still unread */
|
||||
const char *p; /* current position in buffer */
|
||||
|
Reference in New Issue
Block a user