问题描述
{Some rule that matches strings} return STRING; //STRING is enum
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()
原型的宏挂钩。