用Spirit语法解析:齐不及格
Grammar parsing with Spirit::Qi fails
我是Spirit::Qi的新手,我正在尝试编写一个简单的Wavefront Obj解析器。我已经学习了Boost::Spirit文档网站(链接)上的教程,我已经掌握了大部分内联规则。我已经开始尝试语法,但我似乎无法让它们发挥作用。过了一段时间,我确实编译了它,但解析失败了。我真的不知道我做错了什么。
为了简单起见,我创建了一个简单的文本文件,其中包含以下内容:
v -1.5701 33.8087 0.3592
v -24.0119 0.0050 21.7439
v 20.8717 0.0050 21.7439
v 20.8717 0.0050 -21.0255
v -24.0119 0.0050 -21.0255
v -1.5701 0.0050 0.3592
可以肯定的是:读取输入文件效果良好。
我已经编写了一个小函数来解析输入字符串,但由于某种原因它失败了:
bool Model::parseObj( std::string &data, std::vector<float> &v )
{
struct objGram : qi::grammar<std::string::const_iterator, float()>
{
objGram() : objGram::base_type(vertex)
{
vertex = 'v' >> qi::float_
>> qi::float_
>> qi::float_;
}
qi::rule<std::string::const_iterator, float()> vertex;
};
objGram grammar;
return qi::phrase_parse( data.cbegin(), data.cend(),
grammar, iso8859::space, v );
}
qi::phrase_parse不断返回false,std::vector v在末尾仍然为空。。。
有什么建议吗?
编辑:
在添加添加空格skippers(这是正确的名称吗?)后,只有第一个"v"被添加到编码为浮点(118.0f)的std::向量中,但实际数字没有添加。我的猜测是我的规则不正确。我只想加上数字,跳过v。
这是我修改过的函数:
bool Model::parseObj( std::string &data, std::vector<float> &v )
{
struct objGram : qi::grammar<std::string::const_iterator, float(), iso8859::space_type>
{
objGram() : objGram::base_type(vertex)
{
vertex = qi::char_('v') >> qi::float_
>> qi::float_
>> qi::float_;
}
qi::rule<std::string::const_iterator, float(), iso8859::space_type> vertex;
} objGrammar;
return qi::phrase_parse( data.cbegin(), data.cend(),
objGrammar, iso8859::space, v );
}
您的规则声明了错误的公开属性。更改:
qi::rule<std::string::const_iterator, std::vector<float>(), iso8859::space_type> vertex;
然而,由于您没有在任何东西上模板化语法结构(如迭代器/队长类型),因此使用语法结构是没有意义的。相反,让phrase_parse
简单地同时推导迭代器、队长和规则类型,然后写:
bool parseObj(std::string const& data, std::vector<float> &v )
{
return qi::phrase_parse(
data.cbegin(), data.cend(),
'v' >> qi::float_ >> qi::float_ >> qi::float_,
qi::space, v);
}
我想你会同意这更切中要害。作为奖励,它"刚好有效"(TM),因为自动属性传播规则令人敬畏。
然而,看到你的语法,你肯定会想看到这些:
如何在C++中快速解析空格分隔的浮点?展示了如何解析为结构向量
struct float3 { float x,y,z; }; typedef std::vector<float3> data_t;
很少或根本没有额外的工作。哦,它将读取500Mb文件的精神方法与竞争的
fscanf
和atod
调用进行了基准测试。因此,它一次解析多行:)使用
qi::double_
解析器而不是qi::float_
,即使您最终分配给单精度float
变量也是如此。请参阅Boost精灵浮点数解析器精度
- boost::spirit::x3 中的简单字符串解析器不起作用
- (如何)我可以在不安装完整的提升库的情况下使用 boost::spirit X3 吗?
- 在 Spirit X3 中使用布尔属性而不是可选属性
- 在 Boost.Spirit 中,为什么向量(包裹在结构中)需要融合包装器,而不是变体?
- Boost spirit解析器失败,出现不完整的类型错误
- Boost Spirit-项目使用-O1构建,但不使用-O2
- Boost Spirit Parser用三个字符串的矢量编译成一个结构,自适应不工作
- boostqi::语法不更新使用spirit/fenix的valuetype
- Boost.Spirit解析字符串的语义操作不起作用
- 为什么我的 boost::spirit 规则不编译用于解析列表列表?
- boost.spirit:对不完整的输入流采取行动
- 为什么当我使用 boost::bind 时,boost::spirit::qi 语义操作不能使用两个参数?
- 用Spirit语法解析:齐不及格
- Boost Spirit中的名称表达式,不指定规则
- Boost::spirit::qi解析器不消耗整个字符串
- 不能编译boost spirit example4.cpp
- 不能编译boost spirit word_count_lexer示例
- boost::spirit::lex不区分大小写的关键字
- Boost::spirit::qi::parse语法不能正常工作
- 存储在变量模板专门化中的Spirit-X3解析器在Clang上不起作用