2 * Demonstrate the use of goto, call and return. This machine expects either a
3 * lower case char or a digit as a command then a space followed by the command
4 * arg. If the command is a char, then the arg must be an a string of chars.
5 * If the command is a digit, then the arg must be a string of digits. This
6 * choice is determined by action code, rather than though transition
19 int cs, top, stack[32];
22 int execute( const char *data, int len );
29 # Error machine, consumes to end of
30 # line, then starts the main line over.
33 ) >{cout << "error: garbling line" << endl;} @{fgoto main;};
35 # Look for a string of alphas or of digits,
36 # on anything else, hold the character and return.
37 alp_comm := alpha+ $!{fhold;fret;};
38 dig_comm := digit+ $!{fhold;fret;};
40 # Choose which to machine to call into based on the command.
48 # Specifies command string. Note that the arg is left out.
50 [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n'
51 ) @{cout << "correct command" << endl;};
53 # Any number of commands. If there is an
54 # error anywhere, garble the line.
55 main := command* $!{fhold;fgoto garble_line;};
60 int GotoCallRet::init( )
66 int GotoCallRet::execute( const char *data, int len )
69 const char *pe = data + len;
72 if ( cs == GotoCallRet_error )
74 if ( cs >= GotoCallRet_first_final )
79 int GotoCallRet::finish( )
82 if ( cs == GotoCallRet_error )
84 if ( cs >= GotoCallRet_first_final )
97 while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
98 gcr.execute( buf, strlen(buf) );
100 if ( gcr.finish() <= 0 )
101 cerr << "gotocallret: error: parsing input" << endl;