Skip to content

Instantly share code, notes, and snippets.

@FraserLee
Created July 25, 2017 16:37
Show Gist options
  • Save FraserLee/abf078777a8bf1950f00b873ecad47c7 to your computer and use it in GitHub Desktop.
Save FraserLee/abf078777a8bf1950f00b873ecad47c7 to your computer and use it in GitHub Desktop.
Compiler
import java.util.ArrayList;
import java.util.List;
enum types {
NUMBER, PLUS, HYPHEN, ASTERIX, SLASH, OBRACKET, CBRACKET, CARET, NO_VALUE
}
/**
* Created by Fraser Lee on 2017-07-24.
*/
public class Main {
static String expression = "1+2^8-(6/2*3)*4";
static ArrayList<Token> tokens = new ArrayList<>();
public static void main(String[] args) {
Tokenizer tokenizer = new Tokenizer(expression);
while (!tokenizer.endOfData()) {
tokens.add(tokenizer.getNext());
printItAll(tokens);
}
//start math thing
System.out.println(sum(tokens));
}
static int sum(List<Token> tokens) {
if (tokens.size() == 1) {
return Integer.parseInt(tokens.get(0).text);
} else if (tokens.size() > 2) {
switch (tokens.get(1).type) {
case PLUS:
return prod(tokens.subList(0, 1)) + sum(tokens.subList(2, tokens.size()));
case HYPHEN:
return prod(tokens.subList(0, 1)) - sum(tokens.subList(2, tokens.size()));
default:
return prod(tokens);
}
} else {
System.out.println("Failure Point 2 reached with input:");
printItAll(tokens);
return 0;
}
}
static int prod(List<Token> tokens) {
if (tokens.size() == 1) {
return Integer.parseInt(tokens.get(0).text);
} else if (tokens.size() > 2) {
switch (tokens.get(1).type) {
case ASTERIX:
return pow(tokens.subList(0, 1)) * prod(tokens.subList(2, tokens.size()));
case SLASH:
return pow(tokens.subList(0, 1)) / prod(tokens.subList(2, tokens.size()));
default:
return pow(tokens);
}
} else {
System.out.println("Failure Point 3 reached with input:");
printItAll(tokens);
return 0;
}
}
static int pow(List<Token> tokens) {
if (tokens.size() == 1) {
return Integer.parseInt(tokens.get(0).text);
} else if (tokens.size() > 2) {
switch (tokens.get(1).type) {
case CARET:
return (int) Math.pow(paren(tokens.subList(0, 1)), pow(tokens.subList(2, tokens.size())));
default:
return paren(tokens);
}
} else {
System.out.println("Failure Point 3 reached with input:");
printItAll(tokens);
return 0;
}
}
static int paren(List<Token> tokens) {
if (tokens.get(0).text.charAt(0) == '(') {
int layers = 1;
int i;
for (i = 1; i < tokens.size(); i++) {
if (tokens.get(i).text.charAt(0) == '(')
layers++;
if (tokens.get(i).text.charAt(0) == ')')
layers--;
if (layers == 0)
break;
}
if (layers != 0)
System.out.println("Unbalanced parentheses");
tokens.set(i, new Token(types.NUMBER, String.valueOf(sum(tokens.subList(1, i))), -1));
return sum(tokens.subList(i, tokens.size()));
} else {
return sum(tokens);
}
}
static void printItAll(List<Token> tokens) {
for (Token i : tokens)
System.out.print(i.text);
System.out.println();
}
}
class Token {
types type;
String text;
int pos = 0;
public Token(types type, String text, int pos) {
this.type = type;
this.text = text;
this.pos = pos;
}
}
/**
* Created by Fraser Lee on 2017-07-25.
*/
public class Tokenizer {
private String data;
private int pos = 0;
public Tokenizer(String data) {
this.data = data;
skipWhiteSpace();
}
public boolean endOfData() {
return pos >= data.length();
}
public Token getNext() {
assert !endOfData();
Token t = new Token(types.NO_VALUE, String.valueOf(data.charAt(pos)), pos);
if (data.charAt(pos) >= '0' && data.charAt(pos) <= '9') {
StringBuilder num = new StringBuilder("");
while (!endOfData() && data.charAt(pos) >= '0' && data.charAt(pos) <= '9') {
num.append(String.valueOf(data.charAt(pos)));
pos++;
}
t.type=types.NUMBER;
t.text= num.toString();
} else {
char type = data.charAt(pos);
switch (type) {
case '+':
t.type = types.PLUS;
break;
case '-':
t.type = types.HYPHEN;
break;
case '*':
t.type = types.ASTERIX;
break;
case '/':
t.type = types.SLASH;
break;
case '^':
t.type = types.CARET;
break;
case '(':
t.type = types.OBRACKET;
break;
case ')':
t.type = types.CBRACKET;
break;
default:
System.out.println("UNKNOWN TOKEN AT POSITION " + pos);
System.out.println("DATA AROUND TOKEN: " + data.substring(Math.max(0,pos - 5), Math.min(data.length(),pos + 5)));
}
pos++;
}
skipWhiteSpace();
return t;
}
private void skipWhiteSpace() {
while (pos < data.length() && (data.charAt(pos) == ' ' || data.charAt(pos) == '\t' || data.charAt(pos) == '\n'))
pos++;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment