在C中标记s表达式
我试图创建自己的Lisp解释器,但在解析s表达式时遇到了一些问题。我最初的想法是将表达式标记化,并一次处理一点。在我自己的尝试失败后,我对它的输出感到困惑在C中标记s表达式,c,parsing,lisp,tokenize,s-expression,C,Parsing,Lisp,Tokenize,S Expression,我试图创建自己的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 = "()'`";
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);
}
查看代码时,我期望它输出17
而不是17'(a b c)
,或者输出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
好吧,这让人尴尬。。。谢谢你接电话。
printf("%.*s\n", (int)(p - token), token);