Boost 1.47.0からBoost.Spiritに、構文木を扱うためのutreeクラスが入りました。
調べながら使ってみたらこんな感じでした。
#include <iostream> #include <string> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/support_utree.hpp> #include <boost/foreach.hpp> namespace qi = boost::spirit::qi; namespace spirit = boost::spirit; typedef std::string::const_iterator Iterator; int main() { const std::string input = "1,Akira,26"; spirit::utree ut; qi::rule<Iterator, spirit::utree()> r = qi::int_ >> ',' >> qi::as_string[*(qi::char_ - ',')] >> ',' >> qi::int_; Iterator it = input.begin(); if (!qi::parse(it, input.end(), r, ut)) { std::cout << "parse error" << std::endl; return 1; } BOOST_FOREACH (const spirit::utree& data, ut) { switch (data.which()) { case spirit::utree_type::int_type: std::cout << data.get<int>() << std::endl; break; case spirit::utree_type::string_type: { const spirit::utf8_string_range_type r = data.get<spirit::utf8_string_range_type>(); const std::string s(r.begin(), r.end()); std::cout << s << std::endl; break; } default: std::cout << "default" << std::endl; assert(false); } } }
1 Akira 26
utreeはイテレータインタフェースを持っているので、BOOST_FOREACHなどで走査することができます。
utreeに入ったデータはType Erasureによって型情報が消されているので、適切な型に変換して取り出す必要があります。
文字列はboost::spirit::utf8_string_range_typeになるらしいです。
std::stringには直接取り出せないので注意。
それと、as_stringしないと文字ごとにutreeになるので注意。
ちなみに、utreeは入出力ストリームの演算子を持ってるのでそのまま出力できます。
#include <iostream> #include <string> #include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/support_utree.hpp> #include <boost/foreach.hpp> namespace qi = boost::spirit::qi; namespace spirit = boost::spirit; typedef std::string::const_iterator Iterator; int main() { const std::string input = "1,Akira,26"; spirit::utree ut; qi::rule<Iterator, spirit::utree()> r = qi::int_ >> ',' >> qi::as_string[*(qi::char_ - ',')] >> ',' >> qi::int_; Iterator it = input.begin(); if (!qi::parse(it, input.end(), r, ut)) { std::cout << "parse error" << std::endl; return 1; } BOOST_FOREACH (const spirit::utree& data, ut) { std::cout << "|" << data << "|" << std::endl; } }
|1 | |"Akira" | |26 |
なぜかダブルクォーテーションと後ろにスペースが付く。