Administrator approval is now required for registering new accounts. If you are registering a new account, and are external to the University, please ask the repository owner to contact ServiceLine to request your account be approved. Repository owners must include the newly registered email address, and specific repository in the request for approval.

Verified Commit cf21a236 authored by Emily Rowlands's avatar Emily Rowlands
Browse files

Reworked function naming, and it now works!

parent 0547866a
INTEGER = (0|1|2|3|4|5|6|7|8|9)*
SEMICOLON = ;
ADD = +
SUB = -
MUL = *
DIV = /
LPAREN = (
RPAREN = )
factor ::= INTEGER
term ::= factor ((MUL|DIV) factor)*
expr ::= term ((ADD|SUB) term)*
\ No newline at end of file
package jrr1g18.boring;
public class BasicToken extends Token {
public BasicToken(TokenType type) {
super(type);
}
}
package jrr1g18.boring;
import jrr1g18.boring.Token.TokenType;
import jrr1g18.boring.exceptions.IllegalCharacterException;
import jrr1g18.boring.exceptions.IllegalTokenException;
/**
......@@ -15,98 +14,90 @@ public class Interpreter {
private Token m_currentToken;
public Interpreter(Lexer lexer) {
m_lexer = lexer;
try {
m_currentToken = m_lexer.getNextToken();
} catch(IllegalCharacterException e) {
e.printStackTrace();
}
m_lexer = lexer;
m_currentToken = m_lexer.getNextToken();
}
/**
* Compare current token with tt. If they match, then advance the Lexer.
*
* @param tt The expected TokenType
* @throws IllegalTokenException When the token types do not match
*/
public void eat(TokenType tt) throws IllegalTokenException {
if(m_currentToken.getType() == tt) {
try {
m_currentToken = m_lexer.getNextToken();
} catch(IllegalCharacterException e) {
e.printStackTrace();
}
} else {
throw new IllegalTokenException(
"Expected: " + Lib.tokenTypeToString(tt) + " got: "
+ Lib.tokenTypeToString(m_currentToken.getType()));
}
public void eat(TokenType tt) {
try {
if(m_currentToken.getType() == tt) {
m_currentToken = m_lexer.getNextToken();
} else {
throw new IllegalTokenException("Expected: "
+ Lib.tokenTypeToString(tt) + " got: "
+ Lib.tokenTypeToString(m_currentToken.getType()));
}
} catch(IllegalTokenException e) {
e.printStackTrace();
}
}
/**
* number : INTEGER
* factor : INTEGER
*
* @return An integer token value.
* @throws IllegalTokenException
*/
public int number() throws IllegalTokenException {
Integer value = ((ValueToken) m_currentToken).getValue();
eat(TokenType.INTEGER);
return value;
public int factor() {
Integer value = ((ValueToken) m_currentToken).getValue();
eat(TokenType.INTEGER);
return value;
}
/**
* mulDiv : number ((MUL|DIV) number)*
* term : factor ((MUL|DIV) factor)*
*
* @return The expression result.
* @throws IllegalTokenException When an illegal token is enountered.
*/
public int mulDiv() throws IllegalTokenException {
int result = number();
while(m_currentToken.getType() == TokenType.MUL
|| m_currentToken.getType() == TokenType.DIV) {
ValueToken token = (ValueToken) m_currentToken;
switch (token.getType()) {
case MUL:
eat(TokenType.MUL);
result *= number();
break;
case DIV:
eat(TokenType.DIV);
result /= number();
break;
default:
break;
}
}
return result;
public int term() {
int result = factor();
while(m_currentToken.getType() == TokenType.MUL
|| m_currentToken.getType() == TokenType.DIV) {
TokenType operation = m_currentToken.getType();
switch (operation) {
case MUL:
eat(TokenType.MUL);
result *= factor();
break;
case DIV:
eat(TokenType.DIV);
result /= factor();
break;
default:
break;
}
}
return result;
}
/**
* addSub : number ((ADD|SUB) number)*
* expr : term ((ADD|SUB) term)*
*
* @return The expression result.
* @throws IllegalTokenException When an illegal token is enountered.
*/
public int addSub() throws IllegalTokenException {
int result = number();
while(m_currentToken.getType() == TokenType.ADD
|| m_currentToken.getType() == TokenType.SUB) {
ValueToken token = (ValueToken) m_currentToken;
switch (token.getType()) {
case ADD:
eat(TokenType.ADD);
result += number();
break;
case SUB:
eat(TokenType.SUB);
result -= number();
break;
default:
break;
}
}
return result;
public int expr() {
int result = term();
while(m_currentToken.getType() == TokenType.ADD
|| m_currentToken.getType() == TokenType.SUB) {
TokenType operation = m_currentToken.getType();
switch (operation) {
case ADD:
eat(TokenType.ADD);
result += term();
break;
case SUB:
eat(TokenType.SUB);
result -= term();
break;
default:
break;
}
}
return result;
}
}
......@@ -9,83 +9,88 @@ public class Lexer {
private String m_currentChar;
public Lexer(String text) {
m_text = text;
m_text = text;
m_pos = 0;
m_currentChar = "" + m_text.charAt(m_pos);
}
/**
* Advance m_pos and set m_currentChar
*/
private void nextChar() {
m_pos += 1;
if(m_pos > m_text.length() - 1) {
m_currentChar = null;
} else {
m_currentChar = "" + m_text.charAt(m_pos);
}
m_pos += 1;
if(m_pos > m_text.length() - 1) {
m_currentChar = null;
} else {
m_currentChar = "" + m_text.charAt(m_pos);
}
}
/**
* Advance until EOF or end of whitespace
*/
public void skipWhitespace() {
while(m_currentChar != null && Lib.isWhitespace(m_currentChar)) {
nextChar();
}
while(m_currentChar != null && Lib.isWhitespace(m_currentChar)) {
nextChar();
}
}
/**
* @return A multidigit integer generated from input
*/
public int integer() {
String ret = "";
while(m_currentChar != null && Lib.isInt(m_currentChar)) {
ret += m_currentChar;
nextChar();
}
return Integer.parseInt(ret);
String ret = "";
while(m_currentChar != null && Lib.isInt(m_currentChar)) {
ret += m_currentChar;
nextChar();
}
return Integer.parseInt(ret);
}
/**
* Tokeniser
*
* @return The next token
* @throws IllegalCharacterException When an unknown character is found
*/
public Token getNextToken() throws IllegalCharacterException {
while(m_currentChar != null) {
if(Lib.isWhitespace(m_currentChar)) {
skipWhitespace();
continue;
}
public Token getNextToken() {
while(m_currentChar != null) {
if(Lib.isWhitespace(m_currentChar)) {
skipWhitespace();
continue;
}
if(Lib.isInt(m_currentChar)) {
return new ValueToken(TokenType.INTEGER, integer());
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.ADD))) {
nextChar();
return new NamedToken(TokenType.ADD,
Lib.tokenTypeToString(TokenType.ADD));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.SUB))) {
nextChar();
return new NamedToken(TokenType.SUB,
Lib.tokenTypeToString(TokenType.SUB));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.MUL))) {
nextChar();
return new NamedToken(TokenType.MUL,
Lib.tokenTypeToString(TokenType.MUL));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.DIV))) {
nextChar();
return new NamedToken(TokenType.DIV,
Lib.tokenTypeToString(TokenType.DIV));
} else {
throw new IllegalCharacterException(
"Unrecognised thing: " + m_currentChar);
}
}
return new Token(TokenType.EOF);
try {
if(Lib.isInt(m_currentChar)) {
return new ValueToken(TokenType.INTEGER, integer());
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.ADD))) {
nextChar();
return new NamedToken(TokenType.ADD,
Lib.tokenTypeToString(TokenType.ADD));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.SUB))) {
nextChar();
return new NamedToken(TokenType.SUB,
Lib.tokenTypeToString(TokenType.SUB));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.MUL))) {
nextChar();
return new NamedToken(TokenType.MUL,
Lib.tokenTypeToString(TokenType.MUL));
} else if(m_currentChar
.equals(Lib.tokenTypeToString(TokenType.DIV))) {
nextChar();
return new NamedToken(TokenType.DIV,
Lib.tokenTypeToString(TokenType.DIV));
} else {
throw new IllegalCharacterException(
"Unrecognised thing: " + m_currentChar);
}
} catch(IllegalCharacterException e) {
e.printStackTrace();
}
}
return new BasicToken(TokenType.EOF);
}
}
package jrr1g18.boring;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
......@@ -7,6 +10,21 @@ import java.util.Map;
import jrr1g18.boring.Token.TokenType;
public abstract class Lib {
public static String getLine(String prompt) {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
System.out.print(prompt);
String ret;
try {
ret = br.readLine();
} catch(IOException e) {
e.printStackTrace();
ret = "";
}
return ret;
}
/**
* Checks if a string is an integer
*
......@@ -14,7 +32,7 @@ public abstract class Lib {
* @return True if an integer, false otherwise
*/
public static boolean isInt(String string) {
return string.matches("\\d+");
return string.matches("\\d+");
}
/**
......@@ -24,23 +42,23 @@ public abstract class Lib {
* @return True if an integer, false otherwise
*/
public static boolean isWhitespace(String string) {
return string.matches("\\s+");
return string.matches("\\s+");
}
private static final Map<TokenType, String> TOKEN_MAP;
static {
HashMap<TokenType, String> tempMap = new HashMap<TokenType, String>();
tempMap.put(TokenType.EOF, "EOF");
tempMap.put(TokenType.INTEGER, "INTEGER");
tempMap.put(TokenType.SEMICOLON, "SEMICOLON");
tempMap.put(TokenType.DIV, "/");
tempMap.put(TokenType.SUB, "-");
tempMap.put(TokenType.ADD, "+");
tempMap.put(TokenType.MUL, "*");
TOKEN_MAP = Collections.unmodifiableMap(tempMap);
HashMap<TokenType, String> tempMap = new HashMap<TokenType, String>();
tempMap.put(TokenType.EOF, "EOF");
tempMap.put(TokenType.INTEGER, "INTEGER");
tempMap.put(TokenType.SEMICOLON, "SEMICOLON");
tempMap.put(TokenType.DIV, "/");
tempMap.put(TokenType.SUB, "-");
tempMap.put(TokenType.ADD, "+");
tempMap.put(TokenType.MUL, "*");
TOKEN_MAP = Collections.unmodifiableMap(tempMap);
}
public static String tokenTypeToString(final TokenType tt) {
return TOKEN_MAP.get(tt);
return TOKEN_MAP.get(tt);
}
}
......@@ -3,9 +3,23 @@ package jrr1g18.boring;
public class Main {
public static void main(String[] args) throws Exception {
Lexer lexer = new Lexer("1+2");
Interpreter interpreter = new Interpreter(lexer);
System.out.println(interpreter.addSub());
inputLoop();
// Lexer lexer = new Lexer("1+2*3");
// Interpreter interpreter = new Interpreter(lexer);
// System.out.println(interpreter.expr());
}
public static void inputLoop() {
String input;
while(true) {
input = Lib.getLine("> ");
if(input.length() == 0) {
return;
}
Lexer lexer = new Lexer(input);
Interpreter interpreter = new Interpreter(lexer);
System.out.println(interpreter.expr());
}
}
}
package jrr1g18.boring;
public class Token {
public abstract class Token {
public enum TokenType {
EOF, INTEGER, SEMICOLON, ADD, SUB, MUL, DIV,
EOF, INTEGER, SEMICOLON, ADD, SUB, MUL, DIV,
}
private final TokenType m_type;
public Token(TokenType type) {
m_type = type;
m_type = type;
}
public TokenType getType() {
return m_type;
return m_type;
}
public String toString() {
return "Token(" + Lib.tokenTypeToString(m_type) + ")";
return "Token(" + Lib.tokenTypeToString(m_type) + ")";
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment