Каков наилучший способ реализации конечного автомата на С++?

Я видел несколько различных подходов к реализации FSM.

Switch-case Таблицы указателей на функции объектно-ориентированное программирование

Мой вопрос заключается в том, каковы основные факторы, о которых я должен знать, выбирая одну реализацию над другой. В моем случае у меня есть только 4 состояния с не более чем двумя переходами в каждом состоянии. Моя главная цель состоит в том, чтобы реализация была легко читаемой для изменения кем-то другим.

Спасибо


person sanders    schedule 17.05.2015    source источник
comment
Взгляните на буст msm. Вы также можете увидеть преимущества и недостатки в их документации. В этом очень простом конечном автомате, который вы описали, это может быть излишним, но msm предоставит очень удобочитаемую таблицу переходов.   -  person Kam    schedule 17.05.2015
comment
Одна вещь, которую вы могли бы рассмотреть, я думаю, это использовать парсер qi Boost Spirit для FSM? Поскольку вы говорите, что ваш FSM мал - если он очень естественно соответствует регулярным выражениям, и вы думаете, что это будет проще, чем написание таблицы переходов, то, возможно, стоит подумать о том, чтобы сделать это в грамматической форме (с семантическими действиями?). Если вы изучали теорию вычислений на уровне университета, то вы, вероятно, в какой-то момент узнали, что FSM и (простые) регулярные выражения формально эквивалентны (но не суперрегулярное выражение, используемое в perl и grep).   -  person Chris Beck    schedule 20.08.2015


Ответы (1)


Ознакомьтесь с методом реализацией FSA.

// abstract FSA
template<class C, typename T>
struct fsa {
    struct state_t {
        typedef state_t (C::*type)(T);
        inline state_t(type f) : state(f) {}
        type state;
    };

    fsa(state_t init) : state(init) {}

    inline bool next(T val) {
        state = (static_cast<C*>(this)->*state.state)(val);
        return state.state != nullptr;
    }
private:
    state_t state;
};

//concrete FSA implementation
struct myfsa : fsa<myfsa,char> {
    inline myfsa() : fsa<myfsa, char>(&myfsa::start) {}
    state_t start(char) {
        std::cout << "start" << std::endl;
        return &myfsa::state1;
    }
    state_t state1(char) {
        std::cout << "state1" << std::endl;
        return &myfsa::state2;
    }
    state_t state2(char) {
        std::cout << "state2" << std::endl;
        return nullptr;
    }
    char get() { return ' '; /*TODO*/ }
    void run() {
        while(next(get()));
    }
};
person hutorny    schedule 20.08.2015