扩展flex检测到的转义序列

问题描述

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

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

在我的c ++文件中,我有这个:

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

显然有一些逻辑,可以从stdin中获取输入。 现在,如果该程序获得输入“ Hello \ nWorld”,则我的输出"STRING: Hello\nWorld",而我希望输出为:

Hello
World

其他转义字符也是如此,例如\"\0\x<hex_number>\t\\ ...但是我不确定如何做到这一点。我什至不确定这是否是弹性问题,还是只能使用c ++工具解决此问题...

我该怎么做?

解决方法

正如@Some programmer dude在评论中提到的那样,Flex文档中有一个an example of how to do this using start conditions。该示例将转义规则置于单独的开始条件中。每个规则都是通过将未转义的文本附加到缓冲区来实现的。这就是通常的方式。

当然,您可能会发现一个外部库,该库对C样式的转义字符串进行了转义,可以对flex返回的字符串进行调用。但这将比Flex手册中所建议的方法既慢又不灵活:较慢,因为它需要对字符串进行第二次扫描,而灵活性较差,因为库可能对要转义的内容有自己的想法。>

如果您使用的是C ++,则修改该示例以使用std::string缓冲区而不是任意固定大小的字符数组可能会更优雅。您可以使用C ++编译由Flex生成的扫描程序,因此在扫描程序代码中使用C ++标准库对象没有问题。

根据您要管理的各种语义值类型,您可能需要修改yylex原型以使用附加的引用参数或结构化的返回类型,以便将令牌值返回给呼叫者。请注意,虽然可以在下一次调用yytext之前使用yylex,但由于大多数解析器都无法使用它,因此通常不认为它是好的样式:通常,解析器需要具有查找一个或更多的令牌,因此yytext可能会在解析器需要其值时被覆盖。 The flex manual介绍了用于修改yylex()原型的宏挂钩。