【发布时间】:2015-10-26 05:02:03
【问题描述】:
我正在尝试创建自己的 Lisp 解释器,但在解析 s 表达式时遇到了一些问题。我最初的想法是标记表达式并一次处理一个位。 I came across some code to do this 在我自己的尝试失败后,但我对它的输出感到困惑。
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 '(a b c),或者输出2 而不是2)。是什么原因造成的,我该如何解决?如果在这种情况下标记化不是最佳解决方案,我也愿意接受建议。
第二点,像str 这样的参数是绝对必要的吗? start 和 end 参数是否不够,因为在 start 之前没有数据是必需的?
【问题讨论】:
标签: c parsing lisp tokenize s-expression