接着看 main 调用,在库打开之后,会调用 lua_dostring 或 lua_dofile。
lua_dostring 是从标准输入读取 lua 代码。
lua_dofile 是从文件读取 lua 代码,我们来看下这两种有什么区别。
lua_dostring
调用 lua_openstring,
opcode.c:
/*
** Generate opcode stored on string and execute global statement. Return 0 on
** success or 1 on error.
*/
int lua_dostring (char *string)
{
if (lua_openstring (string)) return 1;
if (lua_parse ()) return 1;
lua_closestring();
return 0;
}
打开输入字符串,语法分析,之后关闭输入。
我们看下 lua_openstring 做了什么
inout.c 文件中
/*
** Function to open a string to be input unit
*/
int lua_openstring (char *s)
{
lua_linenumber = 1;
lua_setinput (stringinput);
st = s;
{
char sn[64];
sprintf (sn, "String: %10.10s...", s);
if (lua_addfile (sn)) return 1;
}
return 0;
}
设置开始行号为 1
给词法分析器设置输入 lua_setinput (lex.c 中)。
把输入的字符串地址保存在 st
把文件名保存到文件名数组中去 lua_addfile (table.c 中)。
void lua_setinput (Input fn)
{
current = ' ';
input = fn;
}
设置当前字符,和 input 回调。这里是 stringinput
inout.c 文件中:
/*
** Function to get the next character from the input string
*/
static int stringinput (void)
{
st++;
return (*(st-1));
}
注释里已经说的很清楚了,从输入的字符串中取得一个字符。
lua_addfile 把文件添加到文件数组中。
table.c 文件
/*
** Add a file name at file table, checking overflow. This function also set
** the external variable "lua_filename" with the function filename set.
** Return 0 on success or 1 on error.
*/
int lua_addfile (char *fn)
{
if (lua_nfile >= MAXFILE-1)
{
lua_error ("too many files");
return 1;
}
if ((lua_file[lua_nfile++] = strdup (fn)) == NULL)
{
lua_error ("not enough memory");
return 1;
}
return 0;
}
再看看 lua_dofile 是做什么的。
opcode.c 文件中:
/*
** Open file, generate opcode and execute global statement. Return 0 on
** success or 1 on error.
*/
int lua_dofile (char *filename)
{
if (lua_openfile (filename)) return 1;
if (lua_parse ()) { lua_closefile (); return 1; }
lua_closefile ();
return 0;
}
打开文件,语法分析,关闭文件。
inout.c 文件中
/*
** Function to open a file to be input unit.
** Return 0 on success or 1 on error.
*/
int lua_openfile (char *fn)
{
lua_linenumber = 1;
lua_setinput (fileinput);
fp = fopen (fn, "r");
if (fp == NULL) return 1;
if (lua_addfile (fn)) return 1;
return 0;
}
设置行号,设置词法分析的输入,
这里调用的还是 lex.c 中的 lua_setinput。经过这样的处理,词法分析的时候已经没有标准输入或者文件输入的概念,词法分析只管在需要的时候从函数输入指针取字符,不同的输入在这里已经是透明的了。
打开文件,之后 lua_addfile , 把文件名保存到文件名数组中。
inout.c
/*
** Function to get the next character from the input file
*/
static int fileinput (void)
{
int c = fgetc (fp);
return (c == EOF ? 0 : c);
}
从文件中读出一个字符。如果已经到文件结束,返回 0 。
到这里,词法分析的输入已经准备好了。
通过分析代码我们可以看到,不管是 lua_dostring 或者是 lua_dofile,都调用了 lua_parse。