Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>(This explains the idea hinted by <strong>Spudd86</strong>).</p> <p>You need to implement a finite state machine. There are the following states:</p> <ul> <li>General state</li> <li>Inside a file name</li> <li>Inside the <code>&amp;&amp;</code> token</li> <li>Inside the <code>||</code> token</li> </ul> <p>For each state and next input character, you have to decide what is the next state, and whether to output a token. For example:</p> <ul> <li>Current state: <strong>General</strong>; character: <strong>x</strong> => next state: <strong>inside-file-name</strong></li> <li>Current state: <strong>inside-file-name</strong>; character: <strong>space</strong> => next state: <strong>General</strong>; output the token</li> <li>Current state: <strong>inside-file-name</strong>; character: <strong>&amp;</strong> => next state: <strong>inside-&amp;&amp;</strong>; output the token</li> <li>Current state: <strong>inside-&amp;&amp;</strong>; character: <strong>&amp;</strong> => next state: <strong>General</strong>; output the token</li> <li>Current state: <strong>inside-&amp;&amp;</strong>; character: <strong>x</strong> => next state: <strong>General</strong>; syntax error</li> <li>... (ad nauseum)</li> </ul> <p>It's much boring work to work out all the rules (the fun starts when you must debug the resulting code), so most people use code generators to do that.</p> <hr> <p>Edit: some code (sorry if the syntax is messed-up; i usually program in C++)</p> <pre><code>enum state { STATE_GENERAL, STATE_IN_FILENAME, ... }; // Many characters are treated the same (e.g. 'x' and 'y') - so use categories enum character_category { CHAR_GENERAL, // can appear in filenames CHAR_WHITESPACE = ' ', CHAR_AMPERSAND = '&amp;', CHAR_PIPE = '|', CHAR_EOF = EOF, ... }; character_category translate(int c) { switch (c) { case '&amp;': return CHAR_AMPERSAND; case ' ': case '\t': case '\n': return CHAR_WHITESPACE; ... default: return CHAR_GENERAL; } } void do_stuff() { character_category cat; state current_state = STATE_GENERAL; state next_state; char token[100]; char token_length = 0; do { int c = getchar(); cat = translate(c); // The following implements a switch on 2 variables int selector = 1000 * current_state + cat; switch (selector) { case 1000 * STATE_GENERAL + CHAR_GENERAL: next_state = STATE_IN_FILENAME; token[token_length++] = c; // append a character to a filename token break; case 1000 * STATE_GENERAL + CHAR_WHITESPACE: next_state = STATE_GENERAL; // do nothing break; case 1000 * STATE_GENERAL + CHAR_PIPE: next_state = STATE_IN_OR_TOKEN; // the first char in '||' or just '|' break; // Much repetitive code already; define a macro for the case constants? // Have to cover all states and all character categories; good luck... case 1000 * STATE_IN_FILENAME + EOF: case 1000 * STATE_IN_FILENAME + CHAR_WHITESPACE: next_state = STATE_GENERAL; printf("Filename token: %s\n", token); break; default: printf("Bug\n"); // forgot one of the cases? } current_state = next_state; } while (cat != CHAR_EOF); } </code></pre>
 

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