読者です 読者をやめる 読者になる 読者になる

Boost.Spirit.Qi パース成功と余り

C++

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