繁体   English   中英

用C标记s表达式

[英]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一样绝对必要的参数吗? startend参数是否不足,因为start前没有数据是必要的?

简单的拼写错误。

 printf("%.*s\n", (int)(p - input), token);

应该

 printf("%.*s\n", (int)(p - token), token);

str是输入参数, startend是输出参数。 你可以start一个inout参数,但不是每个人都喜欢那些。

在任何情况下,返回的标记在start ,其长度为end - start ,这就是printf length参数需要为p - token

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM