接着看 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。
时间: 2024-10-14 19:46:13