Project 1: Pretty Printing
Due: Sunday, February 8, 2015 at 11:59pm

Description

In class, we have discussed the use of regular expressions to express the lexical tokens that make up a programming language. In this project, we will use the JFlex tool to express the tokens that comprise the MiniJava language presented in Appendix A of the textbook and then simply print the program back out in a nicely formatted way.

A pretty printer is a program that formats a source code file according to some standard rules. Our program should take an arbitrary MiniJava program as input and produce a nicely-formatted source code file as output.

Pretty Printing Rules

1.       Curly braces should follow the Java convention where the opening curly brace is the last character on the line the block structure begins (class, method, if, else, while, …) and the closing curly brace is on a separate line by itself, indented to the same level as the line that opened the block was. The opening curly brace should be preceded by one space.

2.       Indentation should be done with tabs, not spaces, with one tab per level of nesting.

3.       Binary operators (+, -, *, etc.) should be surrounded by one space.

4.       Commas should be attached to the previous identifier and followed by a single space.

5.       Unary operators should be directly attached to the expression they precede.

6.       Parenthesis () and brackets [] should have no spaces before and one space following the opening one and one space prior to the closing one, except when empty. There should be no space between empty parentheses or brackets.

7.       Data types should be separated by one space from the identifier they precede.

8.       Block comments should be indented to the current indentation level and their text wrapped at the end of the word preceding column 80, unless this is impossible (one long “word” that is greater than the remaining space can spill over, but the next “word” must be on the next line).

9.       Line comments should be discarded. (This is crazy for a pretty printer, but will be useful for using this lexer in our compiler later).

10.   Method signatures should all be on one line ending with an opening curly brace as per rule 1.

11.   Class declarations should all be on one line ending with an opening curly brace as per rule 1.

Requirements

·         You may assume that the input programs are all valid, compiling MiniJava programs.

·         Your output program must also be a valid MiniJava program and be functionally equivalent to the input program.

·         You may not use or write a parser. All of this must be done using the built-in capabilities of JFlex plus some additional code that you will need to track indentation level, etc. You will want to look at the lexer states and lookahead operators to help.

·         You will find that because of the previous requirement, this project is impossible to do perfectly for any complex language, but you might be able to do it anyway.

Organization

Our ultimate goal for this project is to leverage and reuse the lexer code for an eventual MiniJava compiler. To that end, making the reuse easier will be a good idea. The parser will simply require the lexer to return a token object with a type and an optional value. The parser will create these token types from the grammar and we will alter the code you write to return a new object with the proper token type.

Anything you want to do to assist the conversion of your action block to one that simply returns a token to the parser will make your life easier later in the class.

Example

Input

class Factorial {

public static void main(String[] a) {

System.out.println(new Fac().ComputeFac(10));

}}

class Fac {

public int ComputeFac(int num) {

int num_aux;if (num < 1)num_aux = 1;

else num_aux = num* (this.ComputeFac(num-1));

return num_aux;

}}

 

Output

class Factorial {

      public static void main( String[] a ) {

            System.out.println( new Fac().ComputeFac( 10 ) );

      }

}

 

class Fac {

      public int ComputeFac( int num ) {

            int num_aux;

            if( num < 1 )

                  num_aux = 1;

            else

                  num_aux = num * ( this.ComputeFac( num – 1 ) );

            return num_aux;

      }

}

Impossible?

The regular expressions that JFlex recognizes are not powerful enough to do everything that we might need to do without using or writing a parser. However, with JFlex’s actions, we can call code that is more complex than the regular expressions themselves, and this may be sufficient to solve some of the problems you encounter. However, if you find something that you cannot express in JFlex, please write up what structure you cannot deal with and why in a README text file to be submitted with your project.

Submission

By the deadline, you need to submit:

1.       Your JFlex file containing your parser

2.       Your java files containing main() and any auxiliary java files you have used

3.       Your README text file describing what was impossible to do

4.       Any examples that you have tested your program on

Create a zip file of the above files. Use SFTP to copy your zipfile to unixs.cis.pitt.edu and then copy your file to:

     ~jrmst106/submit/1622