CS 3723
 Programming Languages 
Simulating DFAs:
(a|b)*abb


DFA for (a|b)abb

The programs below (two in C and one in Java) recognize the language described by the regular expression (a|b)abb.

C program with gotos: This program almost directly mirrors the FSM. Each labeled location in the program corresponds to a state with a label. Each transition from one state to another corresponds to a goto between the associated locations, conditional on the symbol that is on the transition. This code is straightforward. It can't written this way in Java or Python because these languages don't have a goto.

C and Java programs using a while loop: These use a while loop to simulate the actions of the program with gotos. You have to study the code to understand it. The integer variable state keeps track of the current state. Of course it is initially 0 which is the start state here. Each iteration of the while loop corresponds to a single transition. The inner case handles each state separately.

C and Python programs using a while, and an extended if-else in place of a case: Many people feel that the case as it is in C or Java is perhaps the worst feature of these languages: terribly error-prone. Python has no case, so the extended if-else is the only option. Thus the middle program on the second row it the recommended model for you to use.

C Program, with gotos C Program, no gotos Java Program
// abb0.c: recognize (a|b)*abb
#include <stdio.h>
void printit(int state, char ch);
int main() {
   char ch;
   L0: ch = getchar();
     printit(0, ch);
     if (ch == '$') goto L4;
     if (ch == 'a') goto L1;
     else if (ch == 'b') goto L0;
   L1: ch = getchar();
     printit(1, ch);
     if (ch == '$') goto L4;
     if (ch == 'a') goto L1;
     else if (ch == 'b') goto L2;
   L2: ch = getchar();
     printit(2, ch);
     if (ch == '$') goto L4;
     if (ch == 'a') goto L1;
     else if (ch == 'b') goto L3;
   L3: ch = getchar();
     printit(3, ch);
     if (ch == '$') goto L5;
     if (ch == 'a') goto L1;
     else if (ch == 'b') goto L0;
   L4: printf("Reject\n");
     return;
   L5: printf("Accept\n");
}

void printit(int state,char ch){
   printf("In state: %i,
      char=%c", state, ch);
   if (state == 3)
      printf(" Terminal");
   printf("\n");
}
// abb1.c: recognize (a|b)*abb
#include <stdio.h>

int main() {


  char ch;
  int state = 0;

  while (1) {
    ch = getchar();
    if (ch == '$') break; // while
    switch (state) {
    case 0: if (ch == 'a') state = 1;
       else if (ch == 'b') state = 0;
       break;
    case 1: if (ch == 'a') state = 1;
       else if (ch == 'b') state = 2;
       break;
    case 2: if (ch == 'a') state = 1;
       else if (ch == 'b') state = 3;
       break;
    case 3: if (ch == 'a') state = 1;
       else if (ch == 'b') state = 0;
       break;
    }
    printf("ch: %c, next state: %i",
       ch, state);
    if (state == 3)
       printf(" Terminal");
    printf("\n");
  }
  if (state == 3) printf("Accept\n");
  else printf("Reject\n");
}
// Abb0.java: recognize (a|b)*abb
import java.io.*;
public class Abb0 {
  public static void main(String[]
       args){
    GetChar getChar = new GetChar();
    char ch;
    int state = 0;
  
    while (true) {
      ch = getChar.getNextChar();
      if (ch == '$') break; // while
      switch (state) {
      case 0: if (ch == 'a') state = 1;
         else if (ch == 'b') state = 0;
         break;
      case 1: if (ch == 'a') state = 1;
         else if (ch == 'b') state = 2;
         break;
      case 2: if (ch == 'a') state = 1;
         else if (ch == 'b') state = 3;
         break;
      case 3: if (ch == 'a') state = 1;
         else if (ch == 'b') state = 0;
         break;
      }
      System.out.print("ch: " + ch + ",
         next state: " + state);
      if (state == 3)
         System.out.print(" Terminal");
      System.out.print("\n");
    }
    if (state == 3)
      System.out.print("Accept\n");
    else System.out.print("Reject\n");
  }
}
// GetChar.java for input
// Version without everything in main

C , no case but if-then-else Python Python (not using stdin)
// aab.C: simulate aab fsm
#include <stdio.h> 

int main() {
   char ch;
   int state = 0;
   while (1) {
      ch = getchar();
      if (ch == '$')
         break;
      if (state == 0) {
         if (ch == 'a')
            state = 1;
         else if (ch == 'b')
            state = 0;
      }
      else if (state == 1) {
         if (ch == 'a') 
            state = 1;
         else if (ch == 'b') 
            state = 2;
      }
      else if (state == 2) {
         if (ch == 'a') 
            state = 1;
         else if (ch == 'b') 
            state = 3;
      }
      else if (state == 3) {
         if (ch == 'a') 
            state = 1;
         else if (ch == 'b') 
            state = 0;
      }
      printf("ch: %c, next state: %i",
          ch, state);
      if (state == 3)
         printf(" Terminal");
      printf("\n");
   }
   if (state == 3)
      printf("Accept\n");
   else
      printf("Reject\n");
}
# aab.py: simulate aab fsm
import sys
def getch():
    c = sys.stdin.read(1)
    if len(c) > 0:
        return c
    else:
        return None



state = 0
while True:
    ch = getch()
    if ch == '$':
        break
    if state == 0:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 0
    elif state == 1:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 2
    elif state == 2:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 3
    elif state == 3:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 0
    sys.stdout.write("ch: " + ch +
      ", next state: " + str(state))
    if state == 3:
        sys.stdout.write(" Terminal")
    sys.stdout.write("\n")
    
if state == 3:
    sys.stdout.write("Accept\n")
else:
    sys.stdout.write("Reject\n")
# aab.py: simulate getch
import sys
def getch():
    global i
    s = "ababaabbaababba$"
    if i >= len(s) - 1:
        return None
    i = i + 1
    return s[i]

i = -1
state = 0
while True:
    ch = getch()
    if ch == '$':
        break
    if state == 0:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 0
    elif state == 1:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 2
    elif state == 2:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 3
    elif state == 3:
        if ch == 'a':
            state = 1
        elif ch == 'b':
            state = 0
    sys.stdout.write("ch: " + ch +
      ", next state: " + str(state))
    if state == 3:
        sys.stdout.write(" Terminal")
    sys.stdout.write("\n")
    
if state == 3:
    sys.stdout.write("Accept\n")
else:
    sys.stdout.write("Reject\n")

Common Output
% python abb.py
ababaabbaababba$
ch: a, next state: 1
ch: b, next state: 2
ch: a, next state: 1
ch: b, next state: 2
ch: a, next state: 1
ch: a, next state: 1
ch: b, next state: 2
ch: b, next state: 3 Terminal
ch: a, next state: 1
ch: a, next state: 1
ch: b, next state: 2
ch: a, next state: 1
ch: b, next state: 2
ch: b, next state: 3 Terminal
ch: a, next state: 1
Reject
     Each of the 6 programs above produce exactly the same output, which is shown at the left. The first 5 run at the command line using ababaabbaababba$ as command line input. The compile and run lines for C and Java are (% = command line prompt) as follows. (Of course you might use a development environment for Java, such as DrJava or Eclipse.)

       
% cc -o abb1 -Wall abb1.c
% ./abb1
ababaabbaababba$
           
% javac Abb.java
% java Abb
ababaabbaababba$
The sixth program (directly above at the right) would also run if there was a problem using stdin. Runs:

  • Both Python programs ran using the compileonline Python 3 simulator. In the first Python program I was able to specify the input from stdin.
  • Both Python programs ran using the ideone Python 3 simulator. In the first Python program I was able to specify the input from stdin.
  • The second Python program ran using the appspot Python 3 simulator and the tutorialspoint Python 2.7.4 simulator. (Neither one allows for stdin.)

( Revision date: 2014-08-20. (Please use ISO 8601, the International Standard.)