如何将带有转义序列的字符串转换为C中的一个char

时间:2012-11-18 14:29:31

标签: c lexical-analysis

只是为了给你背景。我们有一个学校项目,我们需要在C中编写自己的编译器。我的任务是编写词法分析。到目前为止一直很好,但我在逃脱序列方面遇到了一些困难。

当我找到一个转义序列并且转义序列是正确的时,我将它保存在一个看起来像 \ xAF 的字符串中,否则它就是词法错误。

我的问题是如何将仅包含转义序列的字符串转换为一个字符?所以我可以将它添加到包含其余字符串的“buffer”中。

我对一个只包含转义序列的大型表有一个想法,然后逐个进行比较,但它看起来并不优雅。

3 个答案:

答案 0 :(得分:3)

此解决方案可用于所有长度和类型的数字转义序列,包括八进制,十六进制等。

当您看到'\'时,您要检查下一个字符。如果它是'x'(或'X'),那么你读一个字符,如果它是一个十六进制数字(isxdigit),那么你读另一个字符。如果最后一个不是十六进制数字,则将其放回流中(“unget”操作),并仅使用您读取的第一个数字。

您读取的每个数字都放入一个字符串中,然后您可以使用例如strtol将该字符串转换为数字。将该数字直接放入令牌值。

对于八进制序列,最多只需三个字符。


有关类似方法的示例,请参阅我多年前制作的this old lexer。搜索 lex_getescape函数。虽然此方法使用直接算术而不是strtoul将转义码转换为数字,而不是标准isxdigit等函数。

答案 1 :(得分:2)

您可以使用以下代码,使用您的字符串调用xString2char。

char x2char(const char c)
{
    if (c >= '0' && c <= '9')
        return c - '0';
    if (c >= 'a' && c <= 'f')
        return c - 'a';
    if (c >= 'A' && c <= 'F')
        return c - 'A';
    //if we got here it's an error - handle it as you like...
}

char xString2char(const char* buf)
{
    char ans;
    ans = x2char(buf[2]);
    ans <<= 4;
    ans += x2char(buf[3]);
    return ans;
}

这应该可行,只需添加错误检查&amp;处理(如果您尚未在代码中验证它们)

答案 2 :(得分:-1)

flex具有start条件。这样可以进行上下文分析。 例如,在flex手册中有一个C注释分析的例子(在/**/之间):

<INITIAL>"/*"   BEGIN(IN_COMMENT);
<IN_COMMENT>{
"*/"            BEGIN(INITIAL);
[^*\n]+         /* eat comment in chunks */
"*"             /* eat the lone star */
\n              yylineno++;
}

启动条件还启用字符串文字分析。有一个示例说明如何在项目开始条件中使用开始条件匹配C风格的引用字符串,并且在flex手册中还有一个标题为"How do I expand backslash-escape sequences in C-style quoted strings?"的FAQ项目。 可能这会回答你的问题。