2

そのため、boost 1.59 で提供されている boost::spirit::x3 で奇妙な動作に遭遇しました。

次の方法で「動的」シンボルテーブルを定義しました。

struct instructions : x3::symbols<OpCode> {
    instructions()
    {
        name("instructions");
    }

    void set_instruction_set(const std::unordered_map<std::string, OpCode>& instruction_set) {
        for (const auto& var : instruction_set) {
            add(var.first, var.second);
        }
    }
} instructions_parser;

OpCodeと定義されている

struct OpCode
{
    std::string mnemonic;
    std::vector<...> variants;// actual type in vector<> not important.
};

現在、必要なルールに埋め込まれた記号テーブルを使用して、次のような入力文字列を解析する場合

mov r2  r1
mov r1  @80

結果の ast には、最初のmovオペランドのみが含まれます。2 番目の mov がありませんが、オペランドは正しく解析されています。結果の AST を出力すると、次のようになります。

mov r2 r1 
    r1 @80

デバッガーを使用して、symbols.hpp のエラーの原因を特定しましたsymbol_parser::parse()

template <typename Iterator, typename Context, typename Attribute>
    bool parse(Iterator& first, Iterator const& last
      , Context const& context, unused_type, Attribute& attr) const
    {
        x3::skip_over(first, last, context);

        if (value_type* val_ptr
            = lookup->find(first, last, get_case_compare<Encoding>(context)))
        {
            x3::traits::move_to(*val_ptr, attr); //<- the error originates from here
            return true;
        }
        return false;
    }

move_toビーイング で:

template <typename T>
inline void move_to(T& src, T& dest)
{
    if (boost::addressof(src) != boost::addressof(dest))
        dest = std::move(src);
}

ご覧のとおりsrc、symbol_parser に追加された OpCode インスタンスが移動されています。これは、最初の呼び出しの後に再び空になることを意味し、そのため最初の命令のみが表示されます。簡単に言えば、シンボルテーブルから移動しました。

最後に私の質問: これはバグですか、それとも間違いですか?

4

1 に答える 1