2

テキストファイルの浮動小数点数を解析して、シンボルテーブルに挿入したいと思います。パーサーとシンボルテーブルはspirit::qiによって提供されます。

これが私のコードです:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
    VTable() {} // empty
};

int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;
    VTable<double> floatDecs;
    floatDecs.add("hallo", 15.26)("duDa", 18.5);

const std::string some = "some";
    rule<std::string::iterator, double> value = real_parser<double, strict_real_policies<double>>() [ boost::phoenix::bind(&VTable<double>::add, floatDecs, boost::phoenix::cref(some), _1) ];

    std::cout << boost::spirit::qi::phrase_parse(test.begin(), test.end(), value, space);
    return 0;
}

ここでの問題はboost::phoenix :: bindにありますが、それを修正する方法がわかりません(私はこのライブラリにかなり慣れていません)。

4

1 に答える 1

3

ここに作業バージョンがあります。その後、あなたの問題点をリストします。

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

#include <stdint.h>
#include <iostream>
#include <string>
template<typename VTYPE>
struct VTable : boost::spirit::qi::symbols<char, VTYPE> {
    VTable() {} // empty
};

int main() {
using boost::spirit::qi::_1;
using boost::spirit::qi::eps;
using boost::spirit::qi::rule;
using boost::spirit::qi::ascii::space;
using boost::spirit::qi::space_type;
using boost::spirit::qi::real_parser;
using boost::spirit::qi::int_parser;
using boost::spirit::qi::strict_real_policies;

    VTable<double> floatDecs;
    floatDecs.add("hallo", 15.26)("duDa", 18.5);

    const char some[] = "some";

    rule<std::string::iterator, double()> value =
            real_parser<double, strict_real_policies<double> >()
            [ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];

    std::string test("10.6");

    std::string::iterator b(test.begin()), e(test.end());

    std::cout << boost::spirit::qi::phrase_parse(b, e, value, space);

    return 0;
}

まず、add() の引数として使用する変数を修正する必要があります。

const char some[] = "some";

次に、ルール テンプレート パラメーターの構文を修正する必要があります。

rule<std::string::iterator, double()>

遅延評価のために、double を通常の double ではなくファンクター宣言にするために、括弧に注意してください。

次に、セマンティック アクションに上記の構文を使用する必要があります。

[ boost::phoenix::bind(floatDecs.add, boost::phoenix::val(some), _1) ];

正直なところ、私はフェニックスの専門家ではないため、なぜこれが機能するのかわかりませんが、上記の「sehe's」コメントのリンクが答えを提供してくれました。また、あなたは間違ったツリーを で吠えていました. の宣言crefからは、参照が必要であることを示すものはありません. 変数をフェニックスに適した怠惰な引数に変えるために必要なものです。add()valsome

最後に、妥当なテスト データを提供する必要があります。

上記のコードは、すぐに機能するはずです。

于 2013-01-21T10:13:40.587 に答える