1

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

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

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

我对一个只包含转义序列的大表有一个想法,然后将它一一进行比较,但它似乎并不优雅。

4

3 回答 3

3

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

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

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

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


有关类似方法的示例,请参见我多年前制作的这个旧词法分析器。搜索 lex_getescape功能。尽管此方法使用直接算术而不是strtoul将转义码转换为数字,也不是标准isxdigit等函数。

于 2012-11-18T14:44:43.417 回答
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;
}

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

于 2012-11-18T14:45:47.140 回答
-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 样式引用字符串的示例,"How do I expand backslash-escape sequences in C-style quoted strings?"在 flex 手册中也有标题为 FAQ 的项。可能这会回答你的问题。

于 2012-11-18T14:44:14.157 回答