      PROGRAM LEX
*********************************************************************
* This program implements a simple lexical analyzer for FORTRAN     *
* integer constants.  A finite automaton that recognizes integer    *
* constants was used in designing the program.   Identifiers used:  *
*     DEAD   : dead state                                           *
*     STATE  : current state                                        *
*     I      : index                                                *
*     STRING : input string to be checked                           *
*     SYMBOL : a character in STRING                                *
*     MARK   : end-of-string mark                                   *
*     RESPON : user response                                        *
*                                                                   *
* Input:  STRING, RESPON                                            *
* Output: User prompt, message indicating if string is a valid      *
*         integer                                                   *
*********************************************************************

      INTEGER DEAD
      PARAMETER (DEAD = 99)
      INTEGER STATE, I
      CHARACTER*1 SYMBOL, MARK, RESPON, STRING*80
      DATA MARK /';'/ 

* Repeat the following until no more strings to check

10    CONTINUE
         PRINT *, 'Enter the string to be checked (end with ', MARK, ')'
         READ '(A)', STRING
         I = 1

*        Begin in initial state 
         STATE = 0

*        While Ith symbol in STRING is not the end-of-line mark do
20       IF (STRING(I:I) .NE. MARK) THEN

             SYMBOL = STRING(I:I)
             IF (STATE .EQ. 0) THEN
                 IF (SYMBOL .EQ. ' ') THEN
                     STATE = 0
                 ELSE IF (SYMBOL .EQ. '+' .OR. SYMBOL .EQ.  '-') THEN
                     STATE = 1
                 ELSE IF (SYMBOL .GE. '0' .AND. SYMBOL .LE. '9') THEN
                     STATE = 2
                 ELSE
                     STATE = DEAD
                 END IF
 
             ELSE IF (STATE .EQ. 1 .OR. STATE .EQ. 2) THEN
                 IF (SYMBOL .GE. '0' .AND. SYMBOL .LE. '9') THEN
                     STATE = 2
                 ELSE
                     STATE = DEAD
                 END IF
             END IF

             I = I + 1
         GO TO 20
         END IF

         IF (STATE .EQ. 2) THEN
             PRINT *, 'VALID INTEGER'
         ELSE
             PRINT *, 'NOT A VALID INTEGER'
         END IF

         PRINT *
         PRINT *, 'MORE DATA (Y OR N)'
         READ '(A)', RESPON
      IF (RESPON .EQ. 'Y') GO TO 10
    
      END
