首页 > 代码库 > Lua1.1 输入准备

Lua1.1 输入准备

接着看 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。

Lua1.1 输入准备