interp函数的第二个参数是const ref* pref。
它来至于上层函数的调用:
下面的临时变量ref ifile;就是传入参数。
gs_main_set_lib_paths(minst);
code = gs_main_run_file_open(minst, gs_init_file, &ifile);
if (code < 0) {
*pexit_code = 255;
return code;
}
/* Check to make sure the first token is an integer */
/* (for the version number check.) */
scanner_init(&state, &ifile);
code = scan_token(i_ctx_p, &first_token, &state);
if (code != 0 || !r_has_type(&first_token, t_integer)) {
eprintf1("Initialization file %s does not begin with an integer./n", gs_init_file);
*pexit_code = 255;
return_error(e_Fatal);
}
*++osp = first_token;
r_set_attrs(&ifile, a_executable);
return gs_main_interpret(minst, &ifile, minst->user_errors,
pexit_code, perror_object);
}
这个参数在函数gs_main_run_file_open中被修改:
被修改的语句是:
r_set_attrs(pfref, a_execute+a_executable);
而这句代码的实现为:
也就是这个对象的type_attrs被修改了。而这个对象属性在interp函数中涉及到“分派”,是很重要的属性。
在gs_run_init_file ()中第一次调用scan_token()获得first_token,再把这个token放进操作符栈中。
*++osp = first_token;这句实现这个功能。
后面还有一句:r_set_attrs(&ifile, a_executable);从这句调试来看这句并没有改别type_attrs的值。
这个ifile被传给interp函数之后,通过:
{
..............................
.............................
case exec(t_file):
{ /* Executable file. Read the next token and interpret it. */
stream *s;
scanner_state sstate;
check_read_known_file(s, IREF, return_with_error_iref);
rt:
if (iosp >= ostop) /* check early */
return_with_stackoverflow_iref();
osp = iosp; /* scan_token uses ostack */
scanner_init_options(&sstate, IREF, i_ctx_p->scanner_options);
again:
code = scan_token(i_ctx_p, &token, &sstate);
iosp = osp; /* ditto */
switch (code) {
case 0: /* read a token */
/* It's worth checking for literals, which make up */
/* the majority of input tokens, before storing the */
/* state on the e-stack. Note that because of //, */
/* the token may have *any* type and attributes. */
/* Note also that executable arrays aren't executed */
/* at the top level -- they're treated as literals. */
if (!r_has_attr(&token, a_executable) ||
r_is_array(&token)
) { /* If scan_token used the o-stack, */
/* we know we can do a push now; if not, */
/* the pre-check is still valid. */
iosp++;
ref_assign_inline(iosp, &token);
goto rt;
}
store_state(iesp);
....................
......................
}
调用词法分析函数:scan_token()。
整个解析函数有两处调用scan_token()函数。
另外r_type_xe宏的实现在以前发过的文章关于iref.h中有讨论。