扩展 flex 检测到的转义序列

Expand escape sequences detected by flex

在我的 scanner.lex 文件中我有这个:

{Some rule that matches strings} return STRING; //STRING is enum

在我的 C++ 文件中我有这个:

if (yylex == STRING) {
    cout << "STRING: " << yytext << endl;

显然有一些逻辑可以从标准输入中获取输入。 现在如果这个程序得到输入“Hello\nWorld”,我的输出是 "STRING: Hello\nWorld",而我希望我的输出是:

Hello
World

其他转义字符也是如此,例如\"[=15=]\x<hex_number>\t\...但是我不知道如何实现这一目标。我什至不确定这是一个 flex 问题还是我是否可以仅使用 C++ 工具解决这个问题...

我该如何完成?

如 Flex 文档中的 @Some programmer dude mentions in a comment, there is an an example of how to do this using start conditions。该示例将转义规则放入单独的开始条件;每个规则都是通过将未转义的文本附加到缓冲区来实现的。这就是通常的做法。

当然,您可能会找到一个外部库,它可以对 C-style 转义字符串进行转义,您可以在 flex 编辑的 return 字符串上调用它。但这将比 Flex 手册中建议的方法更慢且更不灵活:更慢是因为它需要对字符串进行第二次扫描,并且更不灵活因为库可能对要处理的转义有自己的想法。

如果您使用的是 C++,您可能会发现修改该示例以使用 std::string 缓冲区而不是任意 fixed-size 字符数组会更优雅。您可以使用 C++ 编译 flex-generated 扫描器,因此在扫描器代码中使用 C++ 标准库对象没有问题。

根据您管理的各种语义值类型,您可能希望修改 yylex 原型以使用额外的引用参数或更结构化的 return 类型,以便return 调用者的令牌值。请注意,虽然在下一次调用 yylex 之前使用 yytext 是可以的,但它通常不被认为是好的风格,因为它不适用于大多数解析器:一般来说,解析器需要能够看一个或更多标记,因此 yytext 很可能在您的解析器需要其值时被覆盖。 The flex manual 记录了用于修改 yylex() 原型的宏钩子。