基本上,函数可以通过三种方式将信息传递回其调用者:
而且,类似地,函数有一些方法可以在调用之间保持状态:
- 通过全局或(函数)静态变量
- 通过将其作为函数参数提供并在每次调用后返回
- 通过指针参数。
词法分析器/标记器的一个很好的编码约定是使用返回值来传达消耗的字符数。(并且可能使用额外的指针变量来来回调用解析器状态)
这是 wakkerbot 的解析器:
STATIC size_t tokenize(char *string, int *sp);
用法:
STATIC void make_words(char * src, struct sentence * target)
{
size_t len, pos, chunk;
STRING word ;
int state = 0; /* FIXME: this could be made static to allow for multi-line strings */
target->size = 0;
len = strlen(src);
if (!len) return;
for(pos=0; pos < len ; ) {
chunk = tokenize(src+pos, &state);
if (!chunk) { /* maybe we should reset state here ... */ pos++; }
if (chunk > STRLEN_MAX) {
warn( "Make_words", "Truncated too long string(%u) at %s\n", (unsigned) chunk, src+pos);
chunk = STRLEN_MAX;
}
word.length = chunk;
word.word = src+pos;
if (word_is_usable(word)) add_word_to_sentence(target, word);
if (pos+chunk >= len) break;
pos += chunk;
}
...
}