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 – Programming in the Large – 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>—</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 ✔</td>
</tr>
<tr>
<td>a number of problems with code format rules/comments</td>
<td>2</td>
<td> </td>
</tr>
<tr>
<td>work with little or no academic merit</td>
<td>0</td>
<td> </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> </td>
</tr>
<tr>
<td>code with small number of minor problems</td>
<td>3</td>
<td>3 ✔</td>
</tr>
<tr>
<td>code that is clearly incorrect, too complex or hard to understand</td>
<td>1</td>
<td> </td>
</tr>
<tr>
<td>work with little or no academic merit</td>
<td>0</td>
<td> </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> </td>
</tr>
<tr>
<td>a recursive descent parser that mostly matches the grammar provided</td>
<td>1</td>
<td>1 ✔</td>
</tr>
<tr>
<td>work with little or no academic merit</td>
<td>0</td>
<td> </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> </td>
</tr>
<tr>
<td>one or two minor problems detected</td>
<td>3</td>
<td>3½ ✔</td>
</tr>
<tr>
<td>substantial number or problems detected</td>
<td>1</td>
<td> </td>
</tr>
<tr>
<td>work with little or no academic merit</td>
<td>0</td>
<td> </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> </td>
</tr>
<tr>
<td>one or two minor problems detected</td>
<td>3</td>
<td>3 ✔</td>
</tr>
<tr>
<td>substantial number of problems detected</td>
<td>1</td>
<td> </td>
</tr>
<tr>
<td>work with little or no academic merit</td>
<td>0</td>
<td> </td>
</tr>
<tr>
<th scope="row">Total Possible Marks</th>
<td>15</td>
<td>14½/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: // <
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 <>
getNextSym();
result = new NeqExpression(
result,
parseArithExpression());
break;
case LE_SYM: // <=
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 '<'
* @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("<");
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 '<>'
* @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 '<='
* @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("<=");
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 © Copyright 2003 Ned Martin</p>
<p>12-Nov-2003</p>
</body>
</html>