[英]Tokenizing an s-expression in C
我正在尝试创建自己的Lisp解释器,并在解析s表达式时遇到了一些问题。 我最初的想法是将表达式标记化并一次处理一个位。 我在尝试失败之后遇到了一些代码来执行此操作 ,但是我对它的输出感到困惑。
int lex(const char *str, const char **start, const char **end)
{
const char *ws = " \t\r\n";
const char *delim = "() \t\r\n";
const char *prefix = "()'`";
str += strspn(str, ws);
if (str[0] == '\0') {
*start = *end = NULL;
return 1;
}
*start = str;
if (strchr(prefix, str[0]) != NULL)
*end = *start + 1;
else
*end = *start + strcspn(str, delim);
return 0;
}
用法:
const char *input = "(foo bar 17 '(a b c) 2)";
char *token;
char *p = input;
lex(p, &token, &p);
while(token != NULL)
{
printf("%.*s\n", (int)(p - input), token);
lex(p, &token, &p);
}
(
foo
bar 17 '
17 '(a b c)
'(a b c) 2)
(a b c) 2)
a b c) 2)
b c) 2)
c) 2)
) 2)
2)
)
看一下代码,我曾预料到它会输出17
而不是17 '(abc)
或输出2
而不是2)
。 造成这种情况的原因是什么?如何解决? 如果令牌化不是这种情况下的最佳解决方案,我也愿意接受建议。
在第二个注释,是一个像str
一样绝对必要的参数吗? start
和end
参数是否不足,因为start
前没有数据是必要的?
简单的拼写错误。
printf("%.*s\n", (int)(p - input), token);
应该
printf("%.*s\n", (int)(p - token), token);
str
是输入参数, start
和end
是输出参数。 你可以start
一个inout参数,但不是每个人都喜欢那些。
在任何情况下,返回的标记在start
,其长度为end - start
,这就是printf length参数需要为p - token
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.