UQ Students should read the Disclaimer & Warning

Note: This page dates from 2005, and is kept for historical purposes.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>COMP2500 - Assignment Five</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
<!--
.wrong {
    background: #FF9999;
}
body {
    background: url(_img/DSC04989.jpg) fixed center;
    font-family: "Arial Unicode MS", Arial, Helvetica, sans-serif;
}
th, td, textarea {
    border: 1px solid #000000;
    padding: 0 1ex;
    background: transparent;
    overflow: hidden;
}
table {
    border: none;
}
-->
</style>
</head>
<body>
<h1>COMP2500 &#8211; Programming in the Large &#8211; Assignment Five</h1>
<table  border="1" summary="Criteria and results achieved for COMP2500 assignment one">
    <thead>
        <tr> 
            <th colspan="3">Criteria and Results</th>
        </tr>
    </thead>
    <tfoot>
        <tr> 
            <td colspan="2">Average class result</td>
            <td>&#8212;</td>
        </tr>
    </tfoot>
    <tbody>
        <tr> 
            <th colspan="3" scope="col">Adherence to code format rules (0-4)<br />
                (including quantity and quality of comments)</th>
        </tr>
        <tr> 
            <td>no violation of code format rules/comments</td>
            <td>4</td>
            <td>4 &#x2714;</td>
        </tr>
        <tr> 
            <td>a number of problems with code format rules/comments</td>
            <td>2</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>work with little or no academic merit</td>
            <td>0</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <th colspan="3" scope="col">Quality of code (0-6)</th>
        </tr>
        <tr> 
            <td>code that is correct, clear and succint</td>
            <td>4</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>code with small number of minor problems</td>
            <td>3</td>
            <td>3 &#x2714;</td>
        </tr>
        <tr> 
            <td>code that is clearly incorrect, too complex or hard to understand</td>
            <td>1</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>work with little or no academic merit</td>
            <td>0</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <th colspan="3" scope="col">Adherence to recursive descent paring 
                rules (0-2)</th>
        </tr>
        <tr> 
            <td>an elegant recursive descent parser that matches the grammar provided</td>
            <td>2</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>a recursive descent parser that mostly matches the grammar provided</td>
            <td>1</td>
            <td>1 &#x2714;</td>
        </tr>
        <tr> 
            <td>work with little or no academic merit</td>
            <td>0</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <th colspan="3" scope="col">Our testing of Parser.java (0-4)</th>
        </tr>
        <tr> 
            <td>no errors detected</td>
            <td>4</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>one or two minor problems detected</td>
            <td>3</td>
            <td>3&frac12; &#x2714;</td>
        </tr>
        <tr> 
            <td>substantial number or problems detected</td>
            <td>1</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>work with little or no academic merit</td>
            <td>0</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <th colspan="3" scope="col">Our testing of RETRAN expression classes 
                (0-4)</th>
        </tr>
        <tr> 
            <td>no errors detected</td>
            <td>4</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>one or two minor problems detected</td>
            <td>3</td>
            <td>3 &#x2714;</td>
        </tr>
        <tr> 
            <td>substantial number of problems detected</td>
            <td>1</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <td>work with little or no academic merit</td>
            <td>0</td>
            <td>&nbsp;</td>
        </tr>
        <tr> 
            <th scope="row">Total Possible Marks</th>
            <td>15</td>
            <td>14&frac12;/18</td>
        </tr>
    </tbody>
</table>
<h2>Submitted Code</h2>
<p> Parser.java<br />
    View the <a href="JavaDoc/Parser" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea" cols="82" rows="364" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">
import java.io.*;

/**
* A parser for RETRAN-2.
 * @author Paul Bailes, modified from another parser by Phil Cook
 * @author Ned Martin, modified 02-Nov-2003
 * @version 2.0 Oct 2003
 */
public class Parser
{
    // Constants used to define the types of terminal symbols

    // Constant corresponding to a lexical error
    public static final int NO_SYM = 0;

    // Constant corresponding to a left parenthesis ('(')
    public static final int LEFT_PAREN_SYM = 1;

    // Constant corresponding to a right parenthesis (')')
    public static final int RIGHT_PAREN_SYM = 2;

    // Constant corresponding to a number
    public static final int NUMBER_SYM = 3;

    // Constant corresponding to a name
    public static final int NAME_SYM = 4;

    // Constant corresponding to an equal sign
    public static final int EQUAL_SYM = 5;

    // Constant corresponding to a semicolon
    public static final int SEMICOLON_SYM = 6;

    // Constant corresponding to the keyword 'if' - CHANGED FROM RETRAN-1
    public static final int IF_SYM = 7;

    // Constant corresponding to the keyword 'then'
    public static final int THEN_SYM = 8;

    // Constant corresponding to the keyword 'else'
    public static final int ELSE_SYM = 9;

    // Constant corresponding to the keyword 'where'
    public static final int WHERE_SYM = 10;

    // Constant corresponding to a plus sign
    public static final int PLUS_SYM = 11;

    // Constant corresponding to a minus sign
    public static final int MINUS_SYM = 12;

    // Constant corresponding to a multiply sign
    public static final int MULT_SYM = 13;

    // Constant corresponding to a divide sign
    public static final int DIV_SYM = 14; 

    // NEW SYMBOLS FOR RETRAN-2

    // Constant corresponding to a less than sign
    public static final int LT_SYM = 15;

    // Constant corresponding to a greater than sign
    public static final int GT_SYM = 16;

    // Constant corresponding to a double equals (comparison) sign
    public static final int EQEQ_SYM = 17;

    // Constant corresponding to a not equals sign
    public static final int NEQ_SYM = 18;

    // Constant corresponding to a less than or equals sign
    public static final int LE_SYM = 19;

    // Constant corresponding to a greater than or equals sign
    public static final int GE_SYM = 20;

    // Constant corresponding to a comma
    public static final int COMMA_SYM = 21;

    // The current symbol being used by the parser
    private int currentSym;

    // The number corresponding to a NUMBER_SYM - only valid when
    // currentSym == NUMBER_SYM
    private int currentNumber;

    // The number corresponding to a NAME_SYM - only valid when
    // currentSym == NAME_SYM
    private String currentName;

    // The scanner to use to do lexical analysis
    private Scanner scanner;

    // Main lexical analysis routine
    // Gets the next symbol from the input.  Returns false if the end of
    // input has been reached.
    private boolean getNextSym()
    {
        boolean result = scanner.getNextSym();
        currentSym = scanner.getCurrentSym();
        currentNumber = scanner.getCurrentNumber();
        currentName = scanner.getCurrentName();

        return result;
    }

    /** Constructs a Parser.
     *  @param br BufferedReader to use as input stream
     */
    public Parser(BufferedReader br)
    {
        scanner = new Scanner(br);
        currentSym = scanner.getCurrentSym();
        currentNumber = scanner.getCurrentNumber();
        currentName = scanner.getCurrentName();
    }

    /** Parses the input and returns Program object corresponding to
     *  the input parsed.
     */
    public Program parseProgram()
    {
        Expression e = parseExpression();

        if (currentSym == WHERE_SYM) // where
        {
            getNextSym();
            return new Program (e, parseDeclarationList());
        }
            else
        {
            return new Program (e, null);
        }
    }

    /** Parses an Expression */
    private Expression parseExpression()
    {
        switch (currentSym)
        {
            case IF_SYM: // CHANGED FROM RETRAN-1
                getNextSym();
                Expression c = parseExpression();
                getNextSym();
                Expression t = parseExpression();
                getNextSym();
                Expression f = parseExpression();

                return new CondExpression (c, t, f);

            default:
                Expression result = parseArithExpression();

                // while any RelOp
                while (currentSym == LT_SYM || 
                    currentSym == GT_SYM ||
                    currentSym == EQEQ_SYM ||
                    currentSym == NEQ_SYM ||
                    currentSym == LE_SYM ||
                    currentSym == GE_SYM)
                {
                    switch (currentSym)
                    {
                        case LT_SYM:    // &lt;
                        getNextSym();
                        result = new LtExpression(
                            result,
                            parseArithExpression());
                        break;

                        case GT_SYM:    // >
                        getNextSym();
                        result = new GeExpression(
                            result,
                            parseArithExpression());
                        break;

                        case EQEQ_SYM:    // ==
                        getNextSym();
                        result = new EqExpression(
                            result,
                            parseArithExpression());
                        break;

                        case NEQ_SYM:    // != or &lt;>
                        getNextSym();
                        result = new NeqExpression(
                            result,
                            parseArithExpression());
                        break;

                        case LE_SYM:    // &lt;=
                        getNextSym();
                        result = new LeExpression(
                            result,
                            parseArithExpression());
                        break;

                        case GE_SYM:    // >=
                        getNextSym();
                        result = new GeExpression(
                            result,
                            parseArithExpression());
                        break;
                    }
                }
            return result;
        }
    }

    /** Parses an ArithExpression */
    private Expression parseArithExpression()
    {
        Expression result = parseTerm();

        // while any addOp
        while (currentSym == PLUS_SYM || currentSym == MINUS_SYM)
        {
            switch (currentSym)
            {
                case PLUS_SYM:        // +
                    getNextSym();
                    result = new AddExpression(
                        result,
                        parseTerm());
                    break;

                case MINUS_SYM:        // -
                    getNextSym();
                    result = new SubExpression(
                        result,
                        parseTerm());
                    break;
            }
        }
        return result;
    }

    /** Parses a Term */
    private Expression parseTerm()
    {
        Expression result = parseFactor();

        // while any multOp
        while (currentSym == MULT_SYM || currentSym == DIV_SYM)
        {
            switch (currentSym)
            {
                case MULT_SYM:        // *
                    getNextSym();
                    result = new MulExpression(
                        result,
                        parseFactor());
                    break;

                case DIV_SYM:        // /
                    getNextSym();
                    result = new DivExpression(
                        result,
                        parseFactor());
                    break;
            }
        }
        return result;
    }

    /** Parses a Factor */
    private Expression parseFactor()
    {
        Expression result = null;

        switch (currentSym)
        {
            case NUMBER_SYM:    // is number
                result = new NumberExpression(currentNumber);
                getNextSym();
                break;

            case NAME_SYM:        // is name
                String name = currentName;
                getNextSym();

                if (currentSym == LEFT_PAREN_SYM) // (
                {
                    getNextSym();
                    ExpressionList args =
                        parseExpressionList();
                    result =
                        new CallExpression(name, args);
                    getNextSym();
                }
                else
                {
                    result = new NameExpression(name);
                }
                break;

            case LEFT_PAREN_SYM:    // (
                getNextSym();
                result = parseExpression();
                getNextSym();
                break;
        }
        return result;
    }

    /** Parses an ExpressionList */
    private ExpressionList parseExpressionList()
    {
        Expression e = parseExpression();
        ExpressionList es = null;

        if (currentSym == COMMA_SYM) // ,
        {
            getNextSym();
            es = parseExpressionList();
        }
        return new ExpressionList(e, es);
    }

    /** Parses a DeclarationList */
    private DeclarationList parseDeclarationList()
    {
        Declaration d = parseDeclaration();
        DeclarationList ds =
            (currentSym == NAME_SYM ? parseDeclarationList(): null);

        return new DeclarationList(d, ds);
    }

    /** Parses a Declaration */
    private Declaration parseDeclaration()
    {
        String funcName = currentName;
        getNextSym();
        getNextSym();
        NameList paramNames = parsenameList();
        getNextSym();
        getNextSym();
        Expression body = parseExpression();
        Declaration r = new Declaration(funcName, paramNames, body);
        getNextSym();

        return r;
    }

    /** Parses a nameList */
    private NameList parsenameList()
    {
        String n = currentName;
        getNextSym();
        NameList nl = null;

        if (currentSym == COMMA_SYM) // ,
        {
            getNextSym();
            nl = parsenameList();
        }
        return new NameList (n, nl);
    }
}
</textarea>
</p>
<p>NameList.java<br />
    View the <a href="JavaDoc/NameList" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea2" cols="82" rows="39" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * A recursive list of (parameter) names.
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 October 2003
 */
public class NameList extends RETRAN
{
    // The name stored at the head of the list
    private String pname;

    // The tail of the list
    private NameList tail;

    /**
    * Constructs a NameList.
     * @param n the name to store at the head of the list
     * @param tail the NameList to use as the tail of the list
     */
    public NameList(String n, NameList tail)
    {
            this.pname = n;
            this.tail = tail;
    }

    /**
    * generates java source code for the declarations stored in the list.
     */
    public void JGen()
    {
        System.out.print ("int RETRAN_" + pname);
        if (tail != null)
        {
            System.out.print(", ");
            tail.JGen();
        }
    }
}
</textarea>
</p>
<p>Declaration.java<br />
    View the <a href="JavaDoc/Declaration" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea5" cols="82" rows="42" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * A RETRAN-2 declaration.
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 2.0 Oct 2003
 */

public class Declaration extends RETRAN
{
    // The function name
    private String fname;

    //The list of parameter names
    private NameList pnames;

    // The body
    private Expression body;

    /**
    * Constructs a Declaration
     * @param fn the function name
     * @param ps the parameter names
     * @param fb the function body
     */
    public Declaration (String fn, NameList ps, Expression fb)
    {
        fname = fn;
        pnames = ps;
        body = fb;
    }

    /** Generates java source code for the declaration. */
    public void JGen()
    {
        System.out.print ("static private int RETRAN_" + fname + "(");
        pnames.JGen();
        System.out.print (") {\nreturn ");
        body.JGen();
        System.out.println (";\n}");
    }
}
</textarea>
</p>
<p>CondExpression.java<br />
    View the <a href="JavaDoc/CondExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea6" cols="82" rows="43" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * A conditional expression - modified for RETRAN-2
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 2.0 October 2003
 */

public class CondExpression extends Expression
{
    // The test
    private Expression testCond;

    // The true branch
    private Expression trueBranch;

    // The false branch
    private Expression falseBranch;

    /** Constructs a CondExpression.
     *  @param c the test condition
     *  @param t the true branch
     *  @param f the false branch
     */  
    public CondExpression(Expression c, Expression t, Expression f)
    {
        testCond = c;
        trueBranch = t;
        falseBranch = f;
    }

    /** Generates java source code for the conditional expression. */
    public void JGen()
    {
        System.out.print("(");
        testCond.JGen();
        System.out.print("==1?");
        trueBranch.JGen();
        System.out.print(":");
        falseBranch.JGen();
        System.out.print(")");
    }
}

</textarea>
</p>
<p>CallExpression.java<br />
    View the <a href="JavaDoc/CallExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea7" cols="82" rows="34" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * A function call expression (modofied for RETRAN-2)
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 2.0 October 2003
 */
public class CallExpression extends Expression
{
    // The function name
    private String fname;

    // The parameter expression
    private ExpressionList params;

    /**
    * Constructs a CallExpression.
     * @param fn the function name
     * @param ps the parameters
     */
    public CallExpression(String fn, ExpressionList ps)
    {
        fname = fn;
        params = ps;
    }

    /** Generates java source code for the function call expression. */
    public void JGen()
    {
        System.out.print("RETRAN_" + fname + "(");
        params.JGen();
        System.out.print(")");
    }
}
</textarea>
</p>
<p>LtExpression.java<br />
    View the <a href="JavaDoc/LtExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea8" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '&lt;'
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class LtExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs an LtExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public LtExpression(Expression l, Expression r)
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the less than expression. */
    public void JGen()
    {
        System.out.print("(");
        left.JGen();
        System.out.print("&lt;");
        right.JGen();
        System.out.print("?1:0)");
    }
}

</textarea>
</p>
<p>GTExpression.java<br />
    View the <a href="JavaDoc/GTExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea9" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '>'
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class GtExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs a GtExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public GtExpression(Expression l, Expression r)
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the greater than expression. */
    public void JGen()
    {
        System.out.print("(");
        left.JGen();
        System.out.print(">");
        right.JGen();
        System.out.print("?1:0)");
    }
}
</textarea>
</p>
<p>EqExpression.java<br />
    View the <a href="JavaDoc/EqExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea10" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '=='
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class EqExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs an EqExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public EqExpression(Expression l, Expression r)
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the equals expression. */
    public void JGen ()
    {
        System.out.print("(");
        left.JGen();
        System.out.print("==");
        right.JGen();
        System.out.print("?1:0)");
    }
}
</textarea>
</p>
<p>NeqExpression.java<br />
    View the <a href="JavaDoc/NeqExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea11" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '&lt;>'
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class NeqExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs an NeqExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public NeqExpression(Expression l, Expression r) 
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the not equal expression. */
    public void JGen()
    {
        System.out.print("(");
        left.JGen();
        System.out.print("!=");
        right.JGen();
        System.out.print("?1:0)");
    }
}
</textarea>
</p>
<p>LeExpression.java<br />
    View the <a href="JavaDoc/LeExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea12" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '&lt;='
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class LeExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs an LeExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public LeExpression(Expression l, Expression r)
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the not equal expression. */
    public void JGen()
    {
        System.out.print("(");
        left.JGen();
        System.out.print("&lt;=");
        right.JGen();
        System.out.print("?1:0)");
    }
}
</textarea>
</p>
<p>GeExpression.java<br />
    View the <a href="JavaDoc/GeExpression" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea13" cols="82" rows="36" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * An expression that relates two operands under '>='
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 Oct 2003
 */
public class GeExpression extends Expression
{
    // The left operand
    private Expression left;

    // The right operand
    private Expression right;

    /**
    * Constructs a GeExpression.
     * @param l the left operand
     * @param r the right operand
     */
    public GeExpression(Expression l, Expression r)
    {
        left = l;
        right = r;
    }

    /** Generates java source code for the not equal expression. */
    public void JGen()
    {
        System.out.print("(");
        left.JGen();
        System.out.print(">=");
        right.JGen();
        System.out.print("?1:0)");
    }
}
</textarea>
</p>
<p>ExpressionList.java<br />
    View the <a href="JavaDoc/ExpressionList" title="JavaDoc documentation for this code">JavaDoc</a><br />
    <textarea name="textarea14" cols="82" rows="39" readonly="readonly" title="Java Code - Copyright 2003 Ned Martin">/**
 * A recursive list of expressions.
 * @author Paul Bailes
 * @author Ned Martin, modified 02-Nov-2003
 * @version 1.0 October 2003
 */
public class ExpressionList extends RETRAN
{
    // The exprerssion stored at the head of the list
    private Expression expression;

    // The tail of the list
    private ExpressionList tail;

    /**
    * Constructs an ExpressionList.
     * @param expression the declaration to store at the head of the list
     * @param tail the DeclarationList to use as the tail of the list
     */
    public ExpressionList(Expression expression, ExpressionList tail)
    {
        this.expression = expression;
        this.tail = tail;
    }

    /**
    * generates java source code for the expressions stored in the list.
     */
    public void JGen ()
    {
        expression.JGen();
        if (tail != null)
        {
            System.out.print(", ");
            tail.JGen();
        }
    }
}
</textarea>
</p>
<p> Code &copy; Copyright 2003 Ned Martin</p>
<p>12-Nov-2003</p>
</body>
</html>