This article gave me a fair bit of nostalgic feelings. So much so, that I had to go and dig out one of my first university assignments from seven years ago[!], writing a simple Linux Shell, where I actually <i>had</i> to use "decision tables". In my case I remember thinking about using an automata for a grammar to prevent my code from becoming an unmaintainable, unexplainable, SEGFAULT-y mess.<p>Most important of all, I remember the lecture assistant telling us that we "won't pass the assignment as long as I can bring your program to SEGFAULT."<p>Many of us struggled, SEGFAULT after SEGFAULT, with uneven quotes, pipes inside or outside quotes, double bars, double ampersands, etc. As the days progressed, many code-bases became more complex and more fragile as we tried to deal with the pesky inputs of the lecture assistant. When our turn came up, we all grinned while the lecture assistant tried in frustration to bring our shell to SEGFAULT. I remember pointing out "those inputs are not supported by the grammar, and walking him through the bits I list below". Those were the days, oh man :)<p>---<p><pre><code> struct listNode {
char *token;
int type;
struct listNode *next;
};
...
#define M_BEGIN 0
#define T_WORD 1
#define T_QUOTE 2
#define T_BAR 3
#define T_AMP 4
#define T_NL 5
...
int validateInput(struct listNode * head) {
unsigned char smpshGrammar[6][6] = {
{0,1,0,0,0,1}, // M_BEGIN
{0,1,1,1,1,1}, // T_WORD
{0,1,1,1,1,1}, // T_QUOTE
{0,1,0,0,0,0}, // T_BAR
{0,0,0,0,0,1}, // T_AMP
{0,0,0,0,0,0}}; // T_NL
struct listNode * iterator = head;
int validInput = 1;
int previousState = 0;
while(iterator && validInput){
if(DEBUG) printf(" Debug Information > Validating transition from Q%d to Q%d ... Possible:%d\n",
previousState,
iterator->type,
smpshGrammar[previousState][iterator->type]);
if(smpshGrammar[previousState][iterator->type])
{
previousState = iterator->type;
iterator = iterator->next;
}
else { validInput = 0; }
}
if(previousState!=5){ validInput = 0; }
return validInput;
}</code></pre>