扩展 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()
原型的宏钩子。
在我的 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()
原型的宏钩子。