只是为了给你背景。我们有一个学校项目,我们需要在C中编写自己的编译器。我的任务是编写词法分析。到目前为止一直很好,但我在逃脱序列方面遇到了一些困难。
当我找到一个转义序列并且转义序列是正确的时,我将它保存在一个看起来像 \ xAF 的字符串中,否则它就是词法错误。
我的问题是如何将仅包含转义序列的字符串转换为一个字符?所以我可以将它添加到包含其余字符串的“buffer”中。
我对一个只包含转义序列的大型表有一个想法,然后逐个进行比较,但它看起来并不优雅。
答案 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项目。
可能这会回答你的问题。