CS 3723
 Programming Languages 
   Recitation 6  
   Bare Parser  


"Bare" Parser for the grammar of Recitation 6: Below is C on the right and Java on the left. The Java code also needs a GetChar class printed at the end. These parsers mostly don't do anything, but I put in several extra (non-error) output statements to keep track of the parse and see that it seemed on the right track.

Parser: Java Parser: C
/* Bare.java: parser for Recitation 6
 * grammar:
 *   M  --->  L '$'
 *   L  --->  S { S }
 *   S  --->    A  |  P  |  C 
 *   A  --->  lower-case '=' E ';'
 *   P  --->  '<'  E  ';'
 *   G  --->  '>'  lower-case ';'
 *   C  --->  '<'  upper-case ';'
 *   E  --->  T {('+' | '-') T}
 *   T  --->  U {('*' | '/' ) U}
 *   U  --->  F
 *   F  --->  '(' E ')'  |  lower-case  |  digit
 */
import java.util.Date;
class Bare {
   private GetChar getChar = new GetChar();
   private char next;

   private void M() { 
      scan();
      L();
      if (next != '$') error(0);
      else System.out.println("Success");
   }

   private void L() {
      S();
      while (next == '<' ||
            Character.isLowerCase(next)) {
         S();
      }
   }

   private void S() {
      if (Character.isLowerCase(next)) A();
      else if (next == '<') {  // output
         scan();
         if (Character.isUpperCase(next)) {
            System.out.println("Output, using: "+
               next);
            scan();
            if (next == ';') scan();
            else error(13);
         }
         else { //  now general expression
            System.out.println("Output express");
            E();
            if (next == ';') scan();
            else error(12);
         }
      }
      else error(3);
   }

   private void A() {
      if (Character.isLowerCase(next)) {
         System.out.println("Assign: " +
            next + "= stuff");
         scan();
      }
      else error(9);
      if (next == '=') scan();
      else error(10);
      E();
      if (next == ';') scan();
      else error(11);
   }

   private void E() {
      T();
      while (next == '+' || next == '-') {
         System.out.println("Op: " + next);
         scan();
         T();
      }
   }

   private void T() {
      U();
      while (next == '*' || next == '/' ) {
         System.out.println("Op: " + next);
         scan();
         U();
      }
   }

   private void U() {
      F();
   }

   private void F() {
      if (Character.isLowerCase(next)) {
         System.out.println("Processing: "+next);
         scan();
      }
      else if (Character.isDigit(next)) {
         System.out.println("Processing: "+next);
         scan();
      }
      else if (next == '(') {
         scan();
         E();
         if (next == ')') scan();
         else error(14);
      }
      else {
         error(15);
      }
   }

   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) {
      Bare bare = new Bare();
      bare.M();
   }
}
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
char next;
void L(void);
void S(void);
void A(void);
void E(void);
void T(void);
void U(void);
void F(void);
void error(int);
void scan(void);






int main() {
   scan();
   L();
   if (next != '$') error(1);
   else printf("Success\n");
}

void L(void) {
   S();
   while(next == '<' || islower(next)){
      S();
   }
}


void S(void) {
   if (islower(next)) A(); // assign
   else if (next == '<') {  // output
      scan();
      if (isupper(next)) { // capital
         printf("Output, using: %c\n",
            next);
         scan();
         if (next == ';') scan();
         else error(13);
      }
      else { //  now general expression
         printf("Output expression\n");
         E();
         if (next == ';') scan();
         else error(12);
      }
   }
   else error(3);
}

void A(void) {
   if (islower(next)) {
      printf("Assign: %c = stuff\n",
         next);
      scan();
   }
   else error(9);
   if (next == '=') scan();
   else error(10);
   E();
   if (next == ';') scan();
   else error(11);
}

void E(void) {
   T();
   while (next == '+' || next == '-') {
      printf("Op: %c\n", next);
      scan();
      T();
   }
}

void T(void) {
   U();
   while (next == '*' || next == '/') {
      printf("Op: %c\n", next);
      scan();
      U();
   }
}

void U(void) {
   F();
}

void F(void) {
   if (islower(next)) {
      printf("Processing: %c\n", next);
      scan();
   }
   else if (isdigit(next)) {
      printf("Processing: %c\n", next);
      scan();
   }
   else if (next == '(') {
      scan();
      E();
      if (next == ')') scan();
      else error(2);
   }
   else {
      error(3);
   }
}

void scan(void) {
   while (isspace(next = getchar()))
      ;
}


void error(int n) {
   printf("\n*** ERROR: %i\n", n);
   exit(1);
}

Common Output
f = 7; $
Assign: f= stuff
Processing: 7
Success

f = 7; g = f; $
Assign: f= stuff
Processing: 7
Assign: g= stuff
Processing: f

g = f + 8 ; $
Assign: g= stuff
Processing: f
Op: +
Processing: 8
Success

f = 5 + 8;
g = f + 8;
h = f + g;
< h; < N;
$
Assign: f= stuff
Processing: 5
Op: +
Processing: 8
Assign: g= stuff
Processing: f
Op: +
Processing: 8
Assign: h= stuff
Processing: f
Op: +
Processing: g
Output expression
Processing: h
Output, using: N
Success
f = 5 + 8;
g = f + 8;
h = f + g;
a = f*f + g*g; 
b = g*h + f*g;
c = g*g + h*h;
f = a*a + b*b;
g = b*c + a*b;
h = c*c + b*b;
< h; < N;
$
Assign: f= stuff
Processing: 5
Op: +
Processing: 8
Assign: g= stuff
Processing: f
Op: +
Processing: 8
Assign: h= stuff
Processing: f
Op: +
Processing: g
Assign: a= stuff
Processing: f
Op: *
Processing: f
Op: +
Processing: g
Op: *
Processing: g
Assign: b= stuff
Processing: g
Op: *
Processing: h
Op: +
Processing: f
Op: *
Processing: g
Assign: c= stuff
Processing: g
Op: *
Processing: g
Op: +
Processing: h
Op: *
Processing: h
Assign: f= stuff
Processing: a
Op: *
Processing: a
Op: +
Processing: b
Op: *
Processing: b
Assign: g= stuff
Processing: b
Op: *
Processing: c
Op: +
Processing: a
Op: *
Processing: b
Assign: h= stuff
Processing: c
Op: *
Processing: c
Op: +
Processing: b
Op: *
Processing: b
Output expression
Processing: h
Output, using: N
Success

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

// GetChar: fetch next char 
import java.io.*;
public class GetChar { 
   private Reader in; // internal file name for input stream
  
   // GetChar: constructor  
   public GetChar () { 
      in = new InputStreamReader(System.in);
   }

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


Revision date: 2013-02-27. (Please use ISO 8601, the International Standard.)