CSE 413 Winter 2001

Assignment 4 -- Compiler I/O

Electronic turnin of programming part due Tuesday, Feb. 13, by 10:00 pm.
Turnin receipt, test output, and written problems due in class Wednesday, Feb. 14.

Overview

This is the first of a sequence of assignments that will produce a small, but complete compiler.  You are free to work with a partner on this project - in fact, we encourage you to do so.  However, if you do work with a partner, you should plan on working with the same person for the entire compiler project.

Written problems

Here are a few problems involving regular expressions and finite automata.  These are a warmup for the next part of the compiler, the scanner.  Do these problems individually, even if you have a partner for the programming part. 

  1. For each of the following regular expressions, (i) give an example of two strings that can be generated by the expression and two that cannot be generated but use the same alphabet (if possible), and (ii) give an English description of the set of strings generated (for example, "all strings consisting of 1 or more w's followed by xyz").
    1. (a* | b*) a
    2. (0 | 11)*
    3. (a | ε) b
    4. b (ob)*
  2. Give regular expressions that will generate the following strings.
    1. All strings containing a's, and c's with at least 3 a's.
    2. All strings of a's and b's that either start with a and have an even length or start with b and have an odd length.
  3. Write a set of regular expressions that describe integer constants in C.  This set includes:
  4. (Optional) Give the diagram of a finite automata (state diagram) that recognizes the regular expressions for C integers as defined in your answer to question 3.

Programming project - Compiler I/O

For this part of the assignment, implement and test a Java class EchoIO that will handle input and output for the compiler.  Here is a skeleton for this class.  Some details are given below.

public class EchoIO {

   // Constructors:
   
   // Open input and output files whose names are given as arguments
   public EchoIO(String inFile, String outFile) { ... }
   
   // Open named input file.  Open an output file with the same name,
   // but with an extension of ".asm"
   public EchoIO(String inFile) { ... }
   
   // This one is optional:
   // Use a FileDialog to select an input file and open it.  Open an
   // output file with the same but with an extension of ".asm"
   public EchoIO() { ... }
   
   // Methods:
   
   // Return the next line from the input file or null if no more input
   // is available (i.e., eof reached or I/O error of some kind).
   public String readLine() { ... }
   
   // print line to output file
   public void println(String line) { ... }
   
   // properties and set/get methods to access their values:
   
   private boolean echoing;	// true when echoing input to output
   public  void    setEchoing(boolean val) { ...}
   public  boolean getEchoing() { ... }
   
   private String echoPrefix;	// string to concatenate to front of
                                // lines automatically echoed to output
   public  void   setEchoPrefix(String val) { ... }
   public  String getEchoPrefix() { ... }
   
   // additional private instance variables and methods as needed
   ...
   
   // Test program
   // create an EchoIO object and test it.  Main should accept 1 or 2
   // filename arguments, and, optionally no arguments if you've 
   // implemented the optional 0-argument constructor.
   public static void main(string [] args) { ... }
}

The idea behind this class is that the compiler will use a single EchoIO object to manage input and output, which will shield the rest of the compiler from the details of file handling.  The input and output files are ordinary text files.

When the compiler starts, it should create an instance of EchoIO, and the EchoIO object's constructor should open the input and output files.  The scanner will then use this object's readLine() method to read the source program text.  The code generation parts of the compiler will use println() to write the generated x86 assembly code to the output file.  EchoIO.readLine() should handle any exceptions generated during input so the rest of the compiler doesn't see them; otherwise its interface should be the same as BufferedReader.readLine().

In addition to the generated x86 code, we will want to include lines from the source program in the output file as assembly-language comments (it makes the output much easier to read).  So, besides providing simple input, EchoIO.readLine() should be able to copy (echo) each input line to the output file as it is read, if requested by the user.

Variables echoing and echoPrefix should control whether the input lines are printed to the output file, and how.  If echoing is true, then each input line should be written to the output file at the time it is read, with the echoPrefix string concatenated to the front of it.  The idea behind echoPrefix is that we can set it to something appropriate so the echoed source program lines are treated as comments in the generated x86 program (more details in a future assignment).  The set and get methods for these properties can be used to turn echoing on and off and change the prefix string.

EchoIO is required to have two constructors, and a third is optional.  The two-argument constructor parameters are the names of the input and output files. The single-argument constructor should treat its argument as the name of the input file.  It should create the output file name by taking the input file name (say test.txt) and replacing the extension with ".asm" (test.asm).  Don't make assumptions about the length of the extension in the input file name.  It might be ".txt", but it might also be ".stuff", or ".d" or something else.  (Implementation hint: class String includes methods that locate the first or last occurrence of a character or substring in a String.)

The third, optional constructor should have no arguments.  It should let the user to pick the input file with a regular file dialog box, then create a name and open an output file just like the 1-argument constructor. 

Class EchoIO should include its own test program (method main).  The test program should accept one or two file names as command line arguments and use the appropriate constructors to create an EchoIO object.  If you implemented the optional 0-argument constructor, then your test program should be runnable with no arguments, and should call the 0-argument constructor to open the files.  Once the files are open, the test program should verify that the input and output methods of EchoIO work properly, both with and without automatic echoing of input lines, and with different values of the echoPrefix when lines are echoed..

Project Turnin

Use this turnin page to submit your homework.

You should hand in the turnin page, some examples of test input and output that demonstrate that your code works, and your answers to the writtine problems in class on February 14.