CS 3723
 Programming Languages 
   "Bare" R-D Parser   
   (better C version)  


Slight improvement over the "Bare" C Parser for Arithmetic Expressions: Here I included a separate function P(), printed the contents of next in case of an error, and had scan() print each value as it was scanned.

Parser in C Parser in Java
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char next;
void P(void);
void E(void);
void T(void);
void S(void);
void F(void);
void error(int);
void scan(void);

void P() {
   scan();
   E();
   if (next != '$') error(1);
   else printf("Success\n");
}

void E(void) {
   T();
   while (next == '+' || next == '-') {
      scan();
      T();
   }
}

void T(void) {
   S();
   while (next == '*' || next == '/') {
      scan();
      S();
   }
}

void S(void) {
   F();
   if (next == '^') {
      scan();
      S();
   }
}

void F(void) {
   if (isalpha(next)) {
      scan();
   }
   else if (next == '(') {
      scan();
      E();
      if (next == ')') scan();
      else error(2);
   }
   else {
      error(3);
   }
}

void scan(void) {
   while (isspace(next = getchar()))
       ;
   printf("%c", next);
}

void error(int n) {
   printf("\nERR#: %i, next: %c\n",
      n, next);
   exit(1);
}

int main() {
   P();
   printf("\n");
}
/* Arith.java: simple parser -- no output
 * grammar:
 *   P ---> E '$'
 *   E ---> T {('+'|'-') T}
 *   T ---> S {('*'|'/') S}
 *   S ---> F '^' S | F
 *   F ---> char | '(' E ')'
 */
class Arith {
   private GetChar getChar = new GetChar();
   private char next;

   private void P() {
      scan();
      E();
      if (next != '$') error(1);
      else System.out.println("Success");
   }

   private void E() {
      T();
      while (next == '+' || next == '-') {
         scan();
         T();
      }
   }

   private void T() {
      S();
      while (next == '*' || next == '/') {
         scan();
         S();
      }
   }

   private void S() {
      F();
      if (next == '^') {
         scan();
         S();
      }
   }

   private void F() {
      if (Character.isLetter(next)) {
         scan();
      }
      else if (next == '(') {
         scan();
         E();
         if (next == ')') scan();
         else error(2);
      }
      else {
         error(3);
      }
   }

   private void scan() {
      while (Character.isWhitespace(next =
            getChar.getNextChar()))
         ;
   }

   private void error(int n) {
      System.out.println("*** ERROR: " + n);
      System.exit(1);
   }


   public static void main(String[] args) {
      Arith arith = new Arith();
      arith.P();
   }
}

The C program above is complete as it is, but the Java program uses a separate GetChar class printed below.

Run of C Program
% cc -o arith1 -Wall arith1.c
% ./arith1
a+b+c$
a+b+c$
Success
% ./arith1
a++b-c+d$
a++
ERR#: 3, next: +
% ./arith1
a + b + $
a+b+$
ERR#: 3, next: $
% ./arith1
(a+b*c$
(a+b*c$
ERR#: 2, next: $
% /arith1
-b+a*c$
-
ERR#: 3, next: -
 
getchar: Jave class
// GetChar: fetch next char 
import java.io.*;
public class GetChar { 
   private Reader in; // file name for input
  
   // GetChar: constructor  
   public GetChar () { 
      in = new InputStreamReader(System.in);
   }

   // getNextChar: fetches next char
   public char getNextChar() {
      char ch = ' '; // = ' ' for compiler
      try {
         ch = (char)in.read();
      } catch (IOException e) {
         System.out.println("Exception");
      }
      return ch;
   }
}


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