Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Consider using tables instead of <code>switch</code> statements. One column could be the transition criteria and another column is the destination state. </p> <p>This scales nicely because you don't have to change the table processing function; just add another row to the table.</p> <pre><code>+------------------+---------------------+---------------+ | Current state ID | transition criteria | Next state ID | +------------------+---------------------+---------------+ | | | | +------------------+---------------------+---------------+ </code></pre> <p>In my code at work, we use a column of function pointers rather than the "Next state ID". The table is a separate file with accessor functions defined. There is one or more include statements to resolve each function pointer.</p> <h2>Edit 1: Example of separate table files.</h2> <p><strong>table.h</strong></p> <pre><code>#ifndef TABLE_H #define TABLE_H struct Table_Entry { unsigned int current_state_id; unsigned char transition_letter; unsigned int next_state_id; }; Table_Entry const * table_begin(void); Table_Entry const * table_end(void); #endif // TABLE_H </code></pre> <p><strong>table.cpp:</strong> </p> <pre><code>#include "table.h" static const Table_Entry my_table[] = { // Current Transition Next // State ID Letter State ID { 0, 'A', 1}, // From 0 goto 1 if letter is 'A'. { 0, 'B', 2}, // From 0 goto 2 if letter is 'B'. { 0, 'C', 3}, // From 0 goto 3 if letter is 'C'. { 1, 'A', 1}, // From 1 goto 1 if letter is 'A'. { 1, 'B', 3}, // From 1 goto 3 if letter is 'B'. { 1, 'C', 0}, // From 1 goto 0 if letter is 'C'. }; static const unsigned int TABLE_SIZE = sizeof(my_table) / sizeof(my_table[0]); Table_Entry const * table_begin(void) { return &amp;my_table[0]; } Table_Entry const * table_end(void) { return &amp;my_table[TABLE_SIZE]; } </code></pre> <p><strong>state_machine.cpp</strong></p> <pre><code>#include "table.h" #include &lt;iostream&gt; using namespace std; // Because I'm lazy. void Execute_State_Machine(void) { unsigned int current_state = 0; while (1) { char transition_letter; cout &lt;&lt; "Current state: " &lt;&lt; current_state &lt;&lt; "\n"; cout &lt;&lt; "Enter transition letter: "; cin &gt;&gt; transition_letter; cin.ignore(1000, '\n'); /* Eat up the '\n' still in the input stream */ Table_Entry const * p_entry = table_begin(); Table_Entry const * const p_table_end = table_end(); bool state_found = false; while ((!state_found) &amp;&amp; (p_entry != p_table_end)) { if (p_entry-&gt;current_state_id == current_state) { if (p_entry-&gt;transition_letter == transition_letter) { cout &lt;&lt; "State found, transitioning" &lt;&lt; " from state " &lt;&lt; current_state &lt;&lt; ", to state " &lt;&lt; p_entry-&gt;next_state_id &lt;&lt; "\n"; current_state = p_entry-&gt;next_state_id; state_found = true; break; } } ++p_entry; } if (!state_found) { cerr &lt;&lt; "Transition letter not found, current state not changed.\n"; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload