c++ - Boost Qi/X3 解析的类型安全
问题描述
考虑使用 Boost Spirit X3 的代码(概念上与 Boost Spirit Qi 相同):
string command;
string value;
x3::parse(command.begin(), command.end(), "float:" >> x3::double_, value);
为什么这段代码在编译过程中没有产生任何错误?解析器不应该"float:" >> x3::double_
具有类型属性,double
因此不接受std::string
作为第四个参数parse
吗?
顺便说一句,我知道我可以这样做:
string value;
auto assign = [](auto& ctx){value = _attr(ctx)};
x3::parse(command.begin(), command.end(), "float:" >> x3::double_[assign], value)
这会产生错误,但它比必要的复杂。
作为最后的手段:是否有任何众所周知的替代品sscanf
是类型安全的(可能在 boost 中)?
解决方案
这是因为将属性自动传播到容器中非常灵活。
并且std::string
是一个容器。
也许如果我们做以下实验,它会更有意义:
#include <boost/spirit/home/x3.hpp>
#include <iostream>
namespace x3 = boost::spirit::x3;
int main() {
//std::string command = "f: hello world";
std::string command = "f: 104 101 108 108 111 32 119 111 114 108 100";
std::string value;
x3::phrase_parse(
command.begin(),
command.end(),
"f:" >> *x3::double_, x3::blank,
value);
std::cout << value << "\n";
}
您可能会猜到,它会打印:
hello world
对于字符串,这似乎令人惊讶。如果目标是,那就不会那么令人惊讶了std::vector<float>
——但它需要完全相同数量的转换。
每个元素享受传播转换是公平的。如果您正在解析 Ast 节点,例如:
struct Operation {
Operator op;
std::vector<Expression> operands;
}
如果操作数没有隐式转换为Expression
from Unary
,您会讨厌FunctionCall
,StringLiteral
等等。
推荐阅读
- substrate - 我尝试安装子键但得到空安装错误
- node.js - 使用多个 v-如果在 vuejs 中抛出 NonErrorEmittedError?
- html - 如何在这段代码中使用 HTML 中的视频标签
- python-3.x - tkinter 创建未确定数量的复选框/IntVar
- html - 背景颜色隐藏在元素的 box-shadow 上方
- c++ - 如何构建具有 cmake 文件的 c++/c 项目?
- android - 当 ViewModel 通过 LiveData 公开 UiModel 中的更改时,如何对其做出反应?
- reactjs - measure 没有查看 react-virtualized 中的其余数据
- android - 添加位图背景
- node.js - Mongoose:如何从 find() 批量更新修改后的数据