State Machines (was Re: gotos)

Peter da Silva peter at sugar.UUCP
Sat May 7 23:50:09 AEST 1988


I submit that there is one case where gotos are no worse and possibly better
than the alternative. And that is state machine type code, as is found in
lexers. It's rather a narrow category, but I feel it's a valid one. I don't
know if you're arguing against having a goto in a language at all, but here's
one reason to leave it in...

Objection #1 I'll cover immediately: "Use Lex".

	You can't always get lex.

	In fact, for most machines and languages there is no lex or anything
like it. Say, Fortran on a Unisys 1100. Most machines *aren't* UNIX.

	Even using Lex on a UNIX box and massaging the tables doesn't help
when the program has to be maintained in the non-UNIX environment. Even when
you have all the UNIX tools, it's not always cool. I once wrote a recursive-
descent parser in Forth for a real-time applications language in something like 
two months, including a line-oriented language-oriented editor. The guy in
charge of the job didn't like this, and went away for 6 months playing with
doing it with Yacc and massaging the tables. Eventually he and the project were
canned.

Objection #2 is something like: "Write a table-driven scanner". It's also
expressed in terms of using a big while loop and a case statement to do the
state machine.

	You still have to maintain the state machine. The table-driven one
has to be generated somehow, and unless you have Lex or its equivalent it's
going to be expressed in terms of states and transitions... just like the
goto-based version. The same can be said of the case statement. All you're
doing here is hiding the gotos. They're still there:

	ENDSTMT:
		IF(TOKEN .EQ. NEWLINE) THEN
			CALL OUTPUT(SCANNEDLINE)
			GOTO NEWSTMT
		ELSE IF(TOKEN .EQ. COMMENT) THEN
			GOTO ENDSTMT
		ELSE
			GOTO SYNERR
		ENDIF

Is no worse than (and is in fact equivalent to):

	ELSE IF(STATE .EQ. ENDSTMT) THEN
		IF(TOKEN .EQ. NEWLINE) THEN
			CALL OUTPUT(SCANNEDLINE)
			STATE = NEWSTMT
		ELSE IF(TOKEN .EQ. COMMENT) THEN
			STATE = ENDSTMT
		ELSE
			STATE = SYNERR
		ENDIF

And is much better than:

	DATA STATABL(1,ENDSTMT) /NEWLINE, ACTIONOUT, NEWSTMT/
	DATA STATABL(2,ENDSTMT) /COMMENT, 0, ENDSTMT/
	DATA STATABL(3,ENDSTMT) /0, 0, SYNERR/

with some special code to decode the actions.
-- 
-- Peter da Silva      `-_-'      ...!hoptoad!academ!uhnix1!sugar!peter
-- "Have you hugged your U wolf today?" ...!bellcore!tness1!sugar!peter
-- Disclaimer: These aren't mere opinions, these are *values*.



More information about the Comp.lang.c mailing list