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
20 int cs, top, stack[32];
23 int execute( const char *data, int len, bool isEof );
30 # Error machine, consumes to end of
31 # line, then starts the main line over.
34 ) >{cout << "error: garbling line" << endl;} @{fgoto main;};
36 # Look for a string of alphas or of digits,
37 # on anything else, hold the character and return.
38 alp_comm := alpha+ $!{fhold;fret;};
39 dig_comm := digit+ $!{fhold;fret;};
41 # Choose which to machine to call into based on the command.
49 # Specifies command string. Note that the arg is left out.
51 [a-z0-9] @{comm = fc;} ' ' @comm_arg '\n'
52 ) @{cout << "correct command" << endl;};
54 # Any number of commands. If there is an
55 # error anywhere, garble the line.
56 main := command* $!{fhold;fgoto garble_line;};
61 int GotoCallRet::init( )
67 int GotoCallRet::execute( const char *data, int len, bool isEof )
70 const char *pe = data + len;
71 const char *eof = isEof ? pe : 0;
74 if ( cs == GotoCallRet_error )
76 if ( cs >= GotoCallRet_first_final )
89 while ( fgets( buf, sizeof(buf), stdin ) != 0 )
90 gcr.execute( buf, strlen(buf), false );
92 gcr.execute( 0, 0, true );
93 if ( gcr.cs < GotoCallRet_first_final )
94 cerr << "gotocallret: error: parsing input" << endl;