只是为了给你背景。我们有一个学校项目,我们需要用 C 编写自己的编译器。我的任务是编写词法分析。到目前为止一切顺利,但我在转义序列方面遇到了一些困难。
当我找到一个转义序列并且转义序列是正确的时,我将它保存在一个看起来像\xAF的字符串中,否则它是词法错误。
我的问题是如何将只包含转义序列的字符串转换为一个字符?所以我可以将它添加到包含字符串其余部分的“缓冲区”中。
我对一个只包含转义序列的大表有一个想法,然后将它一一进行比较,但它似乎并不优雅。
只是为了给你背景。我们有一个学校项目,我们需要用 C 编写自己的编译器。我的任务是编写词法分析。到目前为止一切顺利,但我在转义序列方面遇到了一些困难。
当我找到一个转义序列并且转义序列是正确的时,我将它保存在一个看起来像\xAF的字符串中,否则它是词法错误。
我的问题是如何将只包含转义序列的字符串转换为一个字符?所以我可以将它添加到包含字符串其余部分的“缓冲区”中。
我对一个只包含转义序列的大表有一个想法,然后将它一一进行比较,但它似乎并不优雅。
此解决方案可用于所有长度和类型的数字转义序列,包括八进制、十六进制等。
当你看到 a 时,你要做的'\'
是检查下一个字符。如果是'x'
(或'X'
),则读取一个字符,如果是十六进制数字(isxdigit
),则读取另一个字符。如果最后一个不是十六进制数字,则将其放回流中(“unget”操作),并仅使用您读取的第一个数字。
您读取的每个数字都放入一个字符串中,然后您可以使用例如strtol
将该字符串转换为一个数字。将该数字直接放入令牌值中。
对于八进制序列,最多只能使用三个字符。
有关类似方法的示例,请参见我多年前制作的这个旧词法分析器。搜索
lex_getescape
功能。尽管此方法使用直接算术而不是strtoul
将转义码转换为数字,也不是标准isxdigit
等函数。
您可以使用以下代码,使用您的字符串调用 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;
}
这应该可以,只需添加错误检查和处理(如果您尚未在代码中验证它们)
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 的项。可能这会回答你的问题。