1

関数ポインターのテーブルを使用して DFA を成文化しようとしています。

テーブルには、マシンが受け取る入力に基づいて、何かを出力するか、テーブル内の別の状態に移動する関数への関数ポインターが入力されます。

今、私にできることは

function<token* ()> A1 = bind(A, &data);
function<token* ()> A2 = bind(B, &data);
function<token* ()> S1 = bind(S, 1);
function<token* ()> S2 = bind(S, 2);

vector< function<token* ()> > _table = { A1, A2, S1, S2 };

[0][0] がアクション A1 を実行し、[0][1] がアクション A2 を実行し、[1][0] が行 1 にシフトし、[1][1] が行 1 にシフトする 2x2 の「テーブル」を作成するには行 2... など。

私の質問は、c++11 でこれを行うためのより速い方法はありますか? 私の状態テーブルは 60x150 に成長しました。50 の異なるアクションがすべて異なる関数にバインドされており、各行に到達するためのシフト関数を定義する必要があります。

これをすべて C++11 の初期化機能で実行しようとしているので、実行時ではなくコンパイル時に実行されます。

次のようなものを実行するマクロまたは何かを作成することは可能ですか:

vector<function<token* ()> > S;
for(int i = 0; i < 60; i++){
  function<token* ()> S[i] = bind(S, i);
}

その後、参照S[3]などを行うことができ、適切にバインドされた関数ポインターが返されますか?

4

1 に答える 1

1

Boost Preprocessorを使用すると、簡単に作成できます。

例えば:

#include <vector>
#include <functional>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
struct token{};
token* S(int){return new token;}
#define MAKE_FUNCT(z, n, unused)         \
BOOST_PP_COMMA_IF(n)                     \
std::bind(S, n)                          \

int main()
{
   std::vector<std::function<token* ()>> table = 
                  {BOOST_PP_REPEAT(10, MAKE_FUNCT, ~)};
}

以下は、取得したフラグを渡す例です。-E

std::vector<std::function<token* ()>> table = { std::bind(S, 0) , std::bind(S, 1) , std::bind(S, 2) , std::bind(S, 3) , std::bind(S, 4) , std::bind(S, 5) , std::bind(S, 6) , std::bind(S, 7) , std::bind(S, 8) , std::bind(S, 9)};
于 2013-03-07T23:13:04.963 に答える