编辑:正如关于sehe的回答的评论中提到的那样,下面的代码看起来很好;这是我处理迭代器(这里没有显示)的错误。对不起这是我的错。投票结束非主题/不可复制。
EDIT2:详细说明...... 如果您正在使用boost::spirit::istream_iterator
将ifstream
提供给解析功能(就像我一样)不要忘记先在unsetf( std::ios::skipws )
上调用ifstream
,否则你的解析会失败......
我有一个DSL(特定于域的语言)文件,看起来像这样:
# Comment (optional)
codepage = "ISO-8859-2";
...
即,codepage
规范是文件中的第一个非注释语句,或者该文件被认为是默认代码页。
我为这项任务征服了Boost Spirit。由于技术原因(咳嗽 AIX / XLC 咳嗽),我不得不继续使用Spirit Classic,并且在经历了一些令人头疼的教程之后 - 总是瞄准更多的参与设置,比我想要的要复杂得多 - 我想出了这段代码:
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_rule.hpp>
#include <boost/spirit/include/classic_utility.hpp>
#include <string>
namespace spirit_classic = boost::spirit::classic;
template< typename Iterator >
static std::string getCodepage( Iterator first, Iterator last )
{
std::string codepage;
spirit_classic::parse(
first,
last,
spirit_classic::as_lower_d[ "codepage" ]
>> spirit_classic::ch_p( '=' )
>> spirit_classic::lexeme_d[ spirit_classic::ch_p( '"' )
>> ( +( spirit_classic::anychar_p - spirit_classic::ch_p( '"' ) ) )[spirit_classic::assign_a( codepage )]
>> spirit_classic::ch_p( '"' ) ]
>> spirit_classic::ch_p( ';' ),
spirit_classic::space_p | spirit_classic::comment_p( '#' )
);
if ( codepage.empty() )
{
codepage = "UTF-8";
}
return codepage;
}
这很有效......除了船长:
...
spirit_classic::space_p | spirit_classic::comment_p( '#' )
...
这可以跳过空白 - 但完全没有跳过评论(即从'#'
到行尾的任何内容),我理解`comment_p(&#39;#&#39;)来实现
显然我明白了一些错误。我只是无法弄清楚是什么。帮助
答案 0 :(得分:1)
我在这里没有太多的见解,我只是在这里测试MSVC / GCC,但问题可能是comment_p
试图消耗eol
(space_p
吃掉了{ {1}}船长代替)?
所以要么你可以使用spirit_classic::blank_p
(并明确你的eols),或你可能有幸逆转了船长的分支:
spirit_classic::comment_p( '#' ) | spirit_classic::space_p
查看 Live On Coliru :
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_rule.hpp>
#include <boost/spirit/include/classic_utility.hpp>
#include <string>
namespace spirit_classic = boost::spirit::classic;
template< typename Iterator >
static std::string getCodepage( Iterator first, Iterator last )
{
std::string codepage;
spirit_classic::parse(
first,
last,
spirit_classic::as_lower_d[ "codepage" ]
>> spirit_classic::ch_p( '=' )
>> spirit_classic::lexeme_d[ spirit_classic::ch_p( '"' )
>> ( +( spirit_classic::anychar_p - spirit_classic::ch_p( '"' ) ) )[spirit_classic::assign_a( codepage )]
>> spirit_classic::ch_p( '"' ) ]
>> spirit_classic::ch_p( ';' ),
spirit_classic::comment_p( '#' ) | spirit_classic::space_p
);
if ( codepage.empty() )
{
codepage = "UTF-8";
}
return codepage;
}
int main()
{
std::string input = "# Comment (optional)\n"
"\n"
"\n"
"\n"
"codepage = \"ISO-8859-2\"; \n";
std::cout << getCodepage(input.begin(), input.end());
}
打印
ISO-8859-2