samouczki maszyn państwowych [zamknięte]

Zastanawiam się, czy ktoś zna jakieś dobre tutoriale w Internecie do tworzenia maszyn państwowych. Czy ebooki?

Zaczynam pracę nad maszynami państwowymi i potrzebuję czegoś ogólnego, żeby zacząć.

Author: paradigmatic, 2009-09-03

8 answers

Maszyny stanowe są bardzo proste w C, jeśli używasz wskaźników funkcji.

Zasadniczo potrzebujesz 2 tablic-jedna dla wskaźników funkcji stanu i jedna dla reguł przejścia stanu. Każda funkcja state zwraca kod, przeglądasz tabelę przejścia stanu według stanu i zwracasz kod, aby znaleźć następny stan, a następnie po prostu go wykonaj.

int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);

/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};

enum ret_codes { ok, fail, repeat};
struct transition {
    enum state_codes src_state;
    enum ret_codes   ret_code;
    enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
    {entry, ok,     foo},
    {entry, fail,   end},
    {foo,   ok,     bar},
    {foo,   fail,   end},
    {foo,   repeat, foo},
    {bar,   ok,     end},
    {bar,   fail,   end},
    {bar,   repeat, foo}};

#define EXIT_STATE end
#define ENTRY_STATE entry

int main(int argc, char *argv[]) {
    enum state_codes cur_state = ENTRY_STATE;
    enum ret_codes rc;
    int (* state_fun)(void);

    for (;;) {
        state_fun = state[cur_state];
        rc = state_fun();
        if (EXIT_STATE == cur_state)
            break;
        cur_state = lookup_transitions(cur_state, rc);
    }

    return EXIT_SUCCESS;
}

Nie umieszczam lookup_transition() funkcji, ponieważ jest ona trywialna.

Tak robię maszyny państwowe od lat.
 111
Author: qrdl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-06 10:21:19

Wolę używać wskaźników funkcji niż gigantycznych instrukcji switch, ale w przeciwieństwie do odpowiedzi qrdl zwykle nie używam jawnych kodów zwrotnych ani tabel przejściowych.

Ponadto, w większości przypadków będziesz potrzebował mechanizmu do przekazywania dodatkowych danych. Oto przykładowa maszyna stanowa:

#include <stdio.h>

struct state;
typedef void state_fn(struct state *);

struct state
{
    state_fn * next;
    int i; // data
};

state_fn foo, bar;

void foo(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = bar;
}

void bar(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = state->i < 10 ? foo : 0;
}

int main(void)
{
    struct state state = { foo, 0 };
    while(state.next) state.next(&state);
}
 23
Author: Christoph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:29

Maszyny Stanowe nie są czymś, co z natury wymaga samouczka do wyjaśnienia lub nawet użycia. Sugeruję, abyś spojrzał na dane i jak należy je przeanalizować.

Na przykład, musiałem przeanalizować protokół danych dla w pobliżu komputera lotu balonem, przechowywał On dane na karcie SD w określonym formacie (binarnym), który musiał zostać przetransferowany do oddzielonego przecinkami pliku. Używanie do tego Maszyny stanowej ma największy sens, ponieważ w zależności od tego, co Następna informacja jest taka, że musimy zmienić to, co analizujemy.

Kod jest napisany w C++ i jest dostępny jako ParseFCU . Jak widać, najpierw wykrywa, którą wersję analizujemy, a stamtąd wchodzi do dwóch różnych maszyn stanowych.

Wchodzi do maszyny stanowej w stanie znany-dobry, w tym momencie zaczynamy parsować i w zależności od tego, jakie znaki napotkamy, albo przechodzimy do następnego stanu, albo wracamy do poprzedniego stanu. To w zasadzie pozwala na kod do samodzielnego dostosowania się do sposobu przechowywania danych i tego, czy pewne dane w ogóle istnieją.

W moim przykładzie ciąg GPS nie jest wymagany dla komputera pokładowego do logowania, więc przetwarzanie ciągu GPS może zostać pominięte, jeśli znaleziono końcowe bajty dla tego pojedynczego zapisu dziennika.

Maszyny stanowe są proste do napisania i generalnie kieruję się zasadą, że powinny płynąć. Dane wejściowe przechodzące przez system powinny płynąć z pewną łatwością od stanu do stanu.

 9
Author: X-Istence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-03 05:06:36

Niestety, większość artykułów o maszynach stanowych jest napisana dla C++ lub innych języków, które mają bezpośrednie wsparcie dla polimorfizmu, ponieważ miło jest modelować stany w implementacji FSM jako klasy wywodzące się z abstrakcyjnej klasy stanu.

Jest jednak dość łatwo zaimplementować maszyny stanowe w języku C, używając instrukcji switch do wysyłania zdarzeń do Stanów (dla prostych FSMs są one prawie kodowane) lub używając tabel do mapowania zdarzeń do stanu przejścia.

Istnieje kilka prostych, ale przyzwoitych artykułów na temat podstawowych frameworków dla maszyn stanowych w języku C:

Edit : Site "under maintenance", web archive linki:

switch maszyny stanowe oparte na instrukcjach często używają zestawu makr do "ukrycia" mechaniki switch instrukcji (lub używają zestawu if/then/else poleceń zamiast switch) i tworzą "język FSM" do opisu maszyny stanowej w źródle C. Osobiście wolę podejście oparte na tabelach, ale z pewnością mają one zalety, są szeroko stosowane i mogą być skuteczne zwłaszcza w przypadku prostszych FSMs.

[6]}jeden z takich frameworków został opisany przez Steve 'a Rabina w rozdziale 3.0" Game Programming Gems " (projektowanie ogólnego solidnego silnika si) [15].

Podobny zestaw makr jest omawiany tutaj:

Jeśli interesują Cię również implementacje maszyn stanowych C++, można znaleźć o wiele więcej. Jeśli jesteś zainteresowany, zamieszczę wskazówki.

 7
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-10 21:36:27

Modelowanie obiektowe w czasie rzeczywistym było fantastyczne (opublikowane w 1994 roku i obecnie sprzedawane za zaledwie 81 centów, plus 3,99 USD za wysyłkę).

 4
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-03 04:55:25

Jest wiele lekcji do nauczenia się ręcznego tworzenia maszyn stanowych w C, ale pozwolę sobie również zasugerować kompilator maszyn stanowych Ragel:

Http://www.complang.org/ragel/

Ma dość prosty sposób definiowania maszyn stanowych, a następnie można generować wykresy, generować kod w różnych stylach( table-driven, goto-driven), analizować ten kod, jeśli chcesz, itp. I jest potężny, może być używany w kodzie produkcyjnym dla różnych protokołów.

 3
Author: Roman Khimov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-03 08:45:06

To wszystko, co musisz wiedzieć.

int state = 0;
while (state < 3)
{
    switch (state)
    {
        case 0:
            // Do State 0 Stuff
            if (should_go_to_next_state)
            {
                state++;
            }
            break;
        case 1:
            // Do State 1 Stuff    
            if (should_go_back) 
            {
                state--;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        case 2:
            // Do State 2 Stuff    
            if (should_go_back_two) 
            {
                state -= 2;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        default:
            break;
    }
}
 2
Author: ChaosPandion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-03 04:52:01

Maszyny stanowe mogą być bardzo złożone dla złożonego problemu. Są one również przedmiotem nieoczekiwanych błędów. Mogą zmienić się w koszmar, jeśli ktoś natknie się na błąd lub będzie musiał zmienić logikę w przyszłości. Są one również trudne do naśladowania i debugowania bez diagramu stanu. Programowanie strukturalne jest znacznie lepsze (na przykład prawdopodobnie nie używałbyś maszyny stanowej na poziomie linii głównej). Można używać programowania strukturalnego nawet w kontekście przerwań (gdzie maszyny stanowe są zwykle używany). Zobacz ten artykuł "makra do symulacji kodu wielozadaniowego / blokującego na poziomie przerwania" znaleziony na codeproject.com.

 -5
Author: eddyq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-26 01:29:11