Spirit.Qi セマンティックアクション

セマンティックアクションがおもしろい。
これを使うと、"(123)"という文字列から123という整数値を取り出す処理をこんな感じで書けます。

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

template <class Expr>
bool parse(const std::string& s, const Expr& expr)
{
    std::string::const_iterator first = s.begin();
    return boost::spirit::qi::parse(first, s.end(), expr);
}

int main()
{
    int result;
    parse("(123)", '(' >> qi::int_[phx::ref(result) = qi::_1] >> ')');

    std::cout << result << std::endl;
}
123

パース時の動作をその場に記述することができます。
実際、このレベルの簡単なパースをすることがよくあるので、とてもうれしい。



これを使って演算なんかもできますが、私は意味解析とかは全然しないのでとくには。

#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

template <class Expr>
bool parse(const std::string& s, const Expr& expr)
{
    std::string::const_iterator first = s.begin();
    return boost::spirit::qi::parse(first, s.end(), expr);
}

int main()
{
    int sum = 0;
    parse("1+2+3", qi::repeat[ qi::int_[phx::ref(sum) += qi::_1] >> '+' ]);

    std::cout << sum << std::endl;
}
6