1

次を解析したい (最初の列は識別子、2 番目の列 (日付) は識別子ごとに一意であり、その後にフロートのタプルが続く):

Max,2016-02-01,1.0,2.0,3.0
Max,2016-02-02,1.0,2.0,3.0
Rob,2016-02-01,1.0,2.0,3.0
Max,2016-02-03,1.0,2.0,3.0

私の好きな構造は

using ValueType = std::tuple<float, float, float>;
using ValueMap  = std::map<std::time_t, ValueType>;
using DataType  = std::unordered_map<std::string, ValueMap>;

属性の伝播を伴う有効な文法を作成することは可能ですか (セマンティック アクションおよび/または後でこの構造にコピーする必要はありません) ?

構文解析は次のようになります。

namespace grammar
{
        using namespace x3;

        auto str2date = [](auto& ctx)
        {
                int y,m,d;
                auto tub = std::tie(y,m,d);
                fusion::copy(_attr(ctx), tub);

                std::tm t{};
                t.tm_year = y - 1900;
                t.tm_mon  = m - 1;
                t.tm_mday = d;

                auto time = std::mktime(&t);
                _val(ctx) = time;
                _pass(ctx) = time > 0;
        };

        auto date_  = rule<struct date_, std::time_t>{"date"}
                                = (int_ >> '-' >> int_ >> int_)[str2date];

        auto values_= rule<struct values_, ValueType>{"values"}
                                = float_ >> ',' >> float_ >> ',' >> float_;

        auto line_ = rule<struct line_, std::pair<std::time_t, ValueType>>{"line"}
                                = date_ >> ',' >> values_;

        auto start_ = rule<struct start_, DataType>{"start"}
                                = (+~char_(',') >> ',' >> line_) % eol >> (eol | eoi); 

};

コリルでライブの例が動かない

4

1 に答える 1

1

私は実用的な例を作りました:

http://coliru.stacked-crooked.com/a/70ba89f254467f9e

x3 の自然な属性と融合構造体マッピングを使用して、中間の ast::Row に簡単に解析できるようにしました。

このように、どこでも正しい rule<> にする必要はありません。1回だけ。x3 はデータを中間形式にする作業を行います。その後、「store()」メソッドを記述して、データを最終的な宛先に取得するのは簡単です。

一度に 1 行だけを中間形式に解析し、その一時変数を保存して破棄します。そうすれば、中間段階で大量のメモリを使い果たすことはありません。

于 2016-09-11T17:51:29.747 に答える