The goal of this assignment is to write a MacroJava to MiniJava translator using Flex and Bison.

Installation

Ubuntu

$ sudo apt install flex bison

macOS

I recommend installing through Homebrew. Install Homebrew first using the instructions on the Homebrew website and then:

$ brew install flex bison

Windows

Install

Then follow instructions for Ubuntu.

Submission details

Your submission should be named <YOUR-ROLLNO>_P0.tar.gz compressed file. For example, if your roll number is cs20b220, then the file should be named cs20b220_P0.tar.gz. The compressed gzip archive should contain a folder named <YOUR-ROLLNO>_P0 with two files and nothing else. A Flex file named as A1.l and a Bison file named as A1.y.

If X.java is a valid MacroJava program, then the following commands should generate the correct MiniJava code Y.java. Take input from standard input and write to standard output.

$ bison A1.y
$ flex A1.l
$ gcc A1.tab.c -lfl -o A1
$ ./A1 < X.java > Y.java

If the X.java file is not a valid MacroJava program, then output

$ ./A1 < X.java
//Failed to parse input code

Useful commands for assignment submission

Assume that you have a folder called cs20b220_P0 with the solution files. For assignment 1, this will contain just the Flex and the Bison files.

$ ls cs20b220_P0
A1.l A1.y

You can create a compressed archive (specifically a .tar.gz file) as follows:

$ tar cvzf cs20b220_P0.tar.gz cs20b220_P0 
a cs20b220_P0
a cs20b220_P0/A1.y
a cs20b220_P0/A1.l
$ file cs20b220_P0.tar.gz 
cs20b220_P0.tar.gz.: gzip compressed data, last modified: ....

You can uncompress the archive as follows:

tar xvzf cs20b220_P0.tar.gz
x cs20b220_P0/
x cs20b220_P0/A1.y
x cs20b220_P0/A1.l

MacroJava

MacroJava is a subset of Java extended with C style macros. The meaning of a MacroJava program is given by its meaning as a Java program (after macro processing). Overloading is not allowed in MacroJava. The MacroJava statement System.out.println( ... ); can only print integers. The MacroJava expression e1 && e2 is of type boolean, and both e1 and e2 must be of type boolean. MacroJava supports both inline as well as C style comments, but does not support nested comments.

Some sample MacroJava programs can be found here.

Specification

              Goal ::= (MacroDefinition)* MainClass ( TypeDeclaration )* <EOF>
         MainClass ::= class Identifier { public static void main ( String [] Identifier ) { System.out.println ( Expression ); } }
   TypeDeclaration ::= class Identifier { ( Type Identifier ;)* ( MethodDeclaration )* }
                     | class Identifier extends Identifier { ( Type Identifier;)* ( MethodDeclaration )* }
 MethodDeclaration ::= public Type Identifier ( ( Type Identifier (, Type Identifier)*)? ) { ( Type Identifier ;)* ( Statement )* return Expression ; }
             Type  ::= int [ ]
                     | boolean
                     | int
                     | Identifier
         Statement ::= { ( Statement )* }
                     | System.out.println ( Expression );
                     | Identifier = Expression ;
                     | Identifier [ Expression ] = Expression ;
                     | if ( Expression ) Statement
                     | if ( Expression ) Statement else Statement
                     | while ( Expression ) Statement
                     | Identifier ( (Expression (, Expression )*)?); /* Macro stmt call */
        Expression ::= PrimaryExpression && PrimaryExpression
                     | PrimaryExpression || PrimaryExpression
                     | PrimaryExpression != PrimaryExpression
                     | PrimaryExpression <= PrimaryExpression
                     | PrimaryExpression + PrimaryExpression
                     | PrimaryExpression - PrimaryExpression
                     | PrimaryExpression * PrimaryExpression
                     | PrimaryExpression / PrimaryExpression
                     | PrimaryExpression [ PrimaryExpression ]
                     | PrimaryExpression . length
                     | PrimaryExpression
                     | PrimaryExpression . Identifier ( (Expression (, Expression )*)? )
                     | Identifier ( (Expression (, Expression )*)? )/* Macro expr call */
 PrimaryExpression ::= Integer
                     | true
                     | false
                     | Identifier
                     | this
                     | new int [ Expression ]
                     | new Identifier ( )
                     | ! Expression
                     | ( Expression )
   MacroDefinition ::= MacroDefExpression
                     | MacroDefStatement
 MacroDefStatement ::= #defineStmt Identifier (Identifier , Identifier, Identifier (, Identifier )*? ) { ( Statement )* }/* More than 2 arguments */
                     | #defineStmt0 Identifier () { ( Statement )* }
                     | #defineStmt1 Identifier ( Identifier ) { ( Statement )* }
                     | #defineStmt2 Identifier (Identifier , Identifier ) { ( Statement )* }
MacroDefExpression ::= #defineExpr Identifier (Identifier , Identifier, Identifier (, Identifier )*? ) ( Expression ) /* More than 2 arguments */
                     | #defineExpr0 Identifier () ( Expression )
                     | #defineExpr1 Identifier ( Identifier ) ( Expression )
                     | #defineExpr2 Identifier (Identifier , Identifier ) ( Expression )
        Identifier ::= <IDENTIFIER>
           Integer ::= <INTEGER_LITERAL>

MiniJava

MiniJava is a subset of Java. The meaning of a MiniJava program is given by its meaning as a Java program. Overloading is not allowed in MiniJava. The MiniJava statement System.out.println( ... ); can only print integers. The MiniJava expression e1 && e2 is of type boolean, and both e1 and e2 must be of type boolean.

Some sample MiniJava programs can be found here.

Specification

                     Goal ::= MainClass ( TypeDeclaration )* <EOF>
                MainClass ::= "class" Identifier "{" "public" "static" "void" "main" "(" "String" "[" "]" Identifier ")" "{" PrintStatement "}" "}"
          TypeDeclaration ::= ClassDeclaration
                            | ClassExtendsDeclaration
         ClassDeclaration ::= "class" Identifier "{" ( VarDeclaration )* ( MethodDeclaration )* "}"
  ClassExtendsDeclaration ::= "class" Identifier "extends" Identifier "{" ( VarDeclaration )* ( MethodDeclaration )* "}"
           VarDeclaration ::= Type Identifier ";"
        MethodDeclaration ::= AccessType Type Identifier "(" ( FormalParameterList )? ")" "{" ( VarDeclaration )* ( Statement )* "return" Expression ";" "}"
      FormalParameterList ::= FormalParameter ( FormalParameterRest )*
          FormalParameter ::= Type Identifier
      FormalParameterRest ::= "," FormalParameter
                     Type ::= ArrayType
                            | BooleanType
                            | IntegerType
                            | Identifier
               AccessType ::= PublicType
                            | PrivateType
                            | ProtectedType
                ArrayType ::= "int" "[" "]"
              BooleanType ::= "boolean"
              IntegerType ::= "int"
               PublicType ::= "public"
             PrivatedType ::= "private"
            ProtectedType ::= "protected"
                Statement ::= Block
                            | AssignmentStatement
                            | ArrayAssignmentStatement
                            | IfStatement
                            | WhileStatement
                            | PrintStatement
                    Block ::= "{" ( Statement )* "}"
      AssignmentStatement ::= Identifier "=" Expression ";"
 ArrayAssignmentStatement ::= Identifier "[" Expression "]" "=" Expression ";"
              IfStatement ::= IfthenElseStatement
                            | IfthenStatement
          IfthenStatement ::= "if" "(" Expression ")" Statement
      IfthenElseStatement ::= "if" "(" Expression ")" Statement "else" Statement
           WhileStatement ::= "while" "(" Expression ")" Statement
           PrintStatement ::= "System.out.println" "(" Expression ")" ";"
               Expression ::= OrExpression
                            | AndExpression
                            | CompareExpression
                            | neqExpression
                            | PlusExpression
                            | MinusExpression
                            | TimesExpression
                            | DivExpression
                            | ArrayLookup
                            | ArrayLength
                            | MessageSend
                            | TernaryExpression
                            | PrimaryExpression
            AndExpression ::= PrimaryExpression "&&" PrimaryExpression
             OrExpression ::= PrimaryExpression "||" PrimaryExpression
        CompareExpression ::= PrimaryExpression "<=" PrimaryExpression
            neqExpression ::= PrimaryExpression "!=" PrimaryExpression
           PlusExpression ::= PrimaryExpression "+" PrimaryExpression
          MinusExpression ::= PrimaryExpression "-" PrimaryExpression
          TimesExpression ::= PrimaryExpression "*" PrimaryExpression
            DivExpression ::= PrimaryExpression "/" PrimaryExpression
              ArrayLookup ::= PrimaryExpression "[" PrimaryExpression "]"
              ArrayLength ::= PrimaryExpression "." "length"
              MessageSend ::= PrimaryExpression "." Identifier "(" ( ExpressionList )? ")"
        TernaryExpression ::= PrimaryExpression "?" PrimaryExpression ":" PrimaryExpression
           ExpressionList ::= Expression ( ExpressionRest )*
           ExpressionRest ::= "," Expression
        PrimaryExpression ::= IntegerLiteral
                            | TrueLiteral
                            | FalseLiteral
                            | Identifier
                            | ThisExpression
                            | ArrayAllocationExpression
                            | AllocationExpression
                            | NotExpression
                            | BracketExpression
           IntegerLiteral ::= <INTEGER_LITERAL>
              TrueLiteral ::= "true"
             FalseLiteral ::= "false"
               Identifier ::= <IDENTIFIER>
           ThisExpression ::= "this"
ArrayAllocationExpression ::= "new" "int" "[" Expression "]"
     AllocationExpression ::= "new" Identifier "(" ")"
            NotExpression ::= "!" Expression
        BracketExpression ::= "(" Expression ")"
           IdentifierList ::= Identifier ( IdentifierRest )*
           IdentifierRest ::= "," Identifier