c++ - 展开 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
其他转义字符也是如此,例如\"
, \0
, \x<hex_number>
, \t
, \\
... 但我不知道如何实现这一点。我什至不确定这是否是一个弹性问题,或者我是否可以仅使用 c++ 工具来解决这个问题......
我怎样才能完成这项工作?
解决方案
正如@Some 程序员花花公子在评论中提到的那样,Flex 文档中有一个如何使用开始条件来执行此操作的示例。该示例将转义规则置于单独的开始条件中;每个规则都是通过将未转义的文本附加到缓冲区来实现的。这就是通常的做法。
当然,您可能会找到一个对 C 样式转义字符串进行转义的外部库,您可以在 flex 返回的字符串上调用它。但这会比 Flex 手册中建议的方法更慢且更不灵活:更慢是因为它需要对字符串进行第二次扫描,而且灵活性更低,因为库可能对要处理的转义有自己的想法。
如果您使用 C++,您可能会发现修改该示例以使用std::string
缓冲区而不是任意固定大小的字符数组更优雅。您可以使用 C++ 编译 flex 生成的扫描仪,因此在您的扫描仪代码中使用 C++ 标准库对象没有问题。
根据您管理的各种语义值类型,您可能需要修改yylex
原型以使用额外的引用参数或更结构化的返回类型,以便将令牌值返回给调用者。请注意,虽然可以yytext
在下一次调用之前使用yylex
它,但它通常不被认为是好的样式,因为它不适用于大多数解析器:通常,解析器需要能够提前查看一个或多个标记,因此yytext
很可能在解析器需要它的值时被覆盖。flex 手册记录了用于修改yylex()
原型的宏钩子。
推荐阅读
- dart - 将 json 转换为 Map
> 格式 - python - 在python中比较单个元素和数组时选择最大值
- python - 列表中的重复项 - 在第二项之后插入输出
- c# - API 返回图片
- hyperledger-fabric - Hyperledger 结构加入通道:错误:2 未知:访问被拒绝:通道 [] 创建者组织 [Org1MSP]
- php - 尝试使用作曲家安装 guzzle 时如何解决错误?
- jenkins - 启用“块构建直到完成”选项触发远程作业时,Jenkins Pipeline 失败
- c - 当我尝试将其更改为反向字母顺序时,排序功能会中断?
- javascript - 从 php 文件重定向到本地 HTML 文件
- azure-cosmosdb - 如何清空集合,重建索引,然后再次填充集合?