Boost.Spirit.Qiのparse/phrase_parse関数は、文字列を直接受け取るインタフェースではなく、文字列のイテレータの組を受け取るインタフェースになっています。
template <typename Iterator, typename Expr, typename... Attr> bool parse(Iterator& first, Iterator last, Expr const& expr, Attr&... attr);
このようなインタフェースになっているのは、文字列の解析というのが、記述したパターンで解析が成功したという結果の他に、解析したけどまだ未解析の文字列が残っている、という結果も必要だからです。
未解析の文字列があることをエラーにするのか。もしくは単に捨てるのかをユーザーが判定することができるようになっています。
文字列のパースに成功し、余りがない例:
#include <iostream> #include <string> #include <boost/spirit/include/qi.hpp> namespace qi = boost::spirit::qi; int main() { const std::string input = "1a3"; std::string::const_iterator it = input.begin(); if (!qi::parse(it, input.end(), qi::digit >> qi::char_ >> qi::digit)) { std::cout << "parse error" << std::endl; return 1; } if (it != input.end()) { std::cout << "remain string : " << std::string(it, input.end()) << std::endl; return 0; } std::cout << "success" << std::endl; }
success
パースが成功し、余りがある例:
#include <iostream> #include <string> #include <boost/spirit/include/qi.hpp> namespace qi = boost::spirit::qi; int main() { const std::string input = "1a3"; std::string::const_iterator it = input.begin(); if (!qi::parse(it, input.end(), qi::digit >> qi::char_)) { std::cout << "parse error" << std::endl; return 1; } if (it != input.end()) { std::cout << "remain string : " << std::string(it, input.end()) << std::endl; return 0; } std::cout << "success" << std::endl; }
remain string : 3
参照:
Iterator Based Parser API - Boost Spirit Library