这几天在写一个解释器,用的语言是C语言,环境是VXWORKS 6.7。由于源语言是我自己定义的,有时便会为了方便写解释器而回去修改源语言的语法。最后经过整理,设定源语言每行的第一个单词,标识这条语句的类型。
因此在写解释器的时候,就可以根据每行扫描到的首个单词来决定到底是用哪一个子函数来解析。这就需要在解释器中用C语言实现动态选择函数入口。
首先理顺一下思路,源程序读入到内存后(可以全部读入也可以用两对半缓冲,详见编译技术),解释器要进行逐行扫描,扫描到首个单词时,根据这个单词来决定函数入口。这就需要有一个分配函数,它的返回值是所需函数入口的匹配值,参数是首个单词的字符串。为了方便,我们把所有的函数入口定义为枚举类型:
typedef enum {
key_IF = 0,
key_FOR,
key_GOTO,
key_ERROR
}keywords;
然后定义分配函数:
keywords yacc(const STRING line)
{
if(!strncmp(line, "IF", 2)){
return key_IF;
}
if(!strncmp(line, "FOR", 3)){
return key_DerivedTask;
}
return key_ERROR;
}
这样我们就知道了扫描到某个首单词时该调用哪个函数,下面构造一个函数指针数组,看着比较高级:
void (*key_func[])(const STRING) = {
exec_IF,
exec_FOR,
exec_error
};
调用时可以这样用:
(*key_func[yacc(FirstName)])(FirstName);
这样就实现了动态选择函数入口的目的。