【发布时间】:2013-07-08 17:06:55
【问题描述】:
我是 Spirit::Qi 的新手,我正在尝试编写一个简单的 Wavefront Obj 解析器。我遵循了来自 Boost::Spirit 文档站点 (link) 的教程,并且大部分内联规则都在工作。我已经开始尝试语法,但我似乎无法让它们发挥作用。过了一会儿,我确实让它编译了,但是解析失败了。我真的不知道我做错了什么。
为了简单起见,我创建了一个包含以下内容的简单文本文件:
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 最后仍然为空...
有什么建议吗?
编辑:
在添加添加空格跳过符后(这是正确的名称吗?),只有第一个 'v' 被添加到编码为浮点数 (118.0f) 的 std::vector 中,但不添加实际数字。我的猜测是我的规则不正确。我只想添加数字并跳过 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 );
}
【问题讨论】:
-
1) 如果您提供完整的代码,您有机会获得更多关注 2) 快速浏览... 118 是您的“v”的 ascii 代码,因此它会错误地传播到输出。如果你想避免它,你有两个选择(也许更多): a) qi::lit('v') >> qi::float_ >> qi::float_ >> qi::float_ b) qi::omit [ qi::char_('v') ] >> qi::float_ >> qi::float_ >> qi::float_
-
@G.Civardi 啊。你和我差不多同时发现了这个问题。你错过了罪魁祸首,但我链接到你对浮点精度问题的回答:) 干杯
-
@sehe 没问题,非常感谢 :-) 干杯
标签: c++ grammar boost-spirit boost-spirit-qi