Skip to content
Snippets Groups Projects

implemented the parser with basic functionality for values, numbers and decimals

2 files
+ 172
0
Compare changes
  • Side-by-side
  • Inline

Files

src/Parser.java 0 → 100644
+ 167
0
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
public class Parser {
private abstract interface Expression {
}
private abstract class Value implements Expression {
}
private class Number extends Value {
public String original;
public Number(String i) {
this.original = i;
}
}
private class Decimal extends Value {
public Number beforeDot;
public char dot;
public Number afterDot;
public Decimal(Number i1, Number i2) {
this.beforeDot = i1;
dot = '.';
this.afterDot = i2;
}
}
//starting method of the parser
//parses a list of tokens
public Expression parse(List<Lexer.Token> list) throws ParserException {
if(list.isEmpty()) {
throw new ParserException("empty token list");
}
List<Lexer.Token> ts = new LinkedList<>(list);
Expression ast = parseExpression(ts);
if(!ts.isEmpty()) {
throw new ParserException("SyntaxError: " + ts.size() + " Token(s) left");
}
return ast;
}
//called by method parse(...)
//parses a list of tokens into an expression
private Expression parseExpression(List<Lexer.Token> ts) throws ParserException {
if(ts.isEmpty()) {
throw new ParserException("empty token list");
}
return parseValue(ts).orElseGet(() -> null);
}
//checks if a String only contains an allowed operator with parseCharacter(...)
private void parseOperator(String operator) throws ParserException {
if(operator.length()>1) {
throw new ParserException("RuntimeException: invalid length for an operator: " + operator);
}
parseCharacter(operator, "+-*/^");
}
//called by methods parseOperator(...), parseDigit(...), parseDigitWithoutZero(...)
//checks if a certain string can be found in a string of allowed character
//if yes: return true
//if not: a ParserException is thrown
private Boolean parseCharacter(String data, String allowedCharacters) throws ParserException {
if(!allowedCharacters.contains(data)) {
throw new ParserException("SyntaxError: Invalid character: " + data);
}
if(data.isEmpty()) {
throw new ParserException("RuntimeException: empty String");
}
return true;
}
//called by method parseException(...)
//parses a list of tokens into a value
private Optional<Expression> parseValue(List<Lexer.Token> ts) throws ParserException {
if (ts.isEmpty()) {
throw new ParserException("SyntaxError: expected a number");
}
if (ts.get(0).getType() != Lexer.TokenType.NUMBER) {
return Optional.empty();
}
String data = ts.remove(0).getData();
if (data.isEmpty()) {
throw new ParserException("RuntimeException: empty token");
}
if (ts.size()>0) {
//if the next token is of TokenType.SPECIAL, check if it's a comma
//if it is, create a decimal
if(ts.get(0).getType() == Lexer.TokenType.SPECIAL) {
if(ts.size()>1) {
if(parseComma(ts.get(0).getData())) {
return Optional.of(parseDecimal(ts, data));
}
}
}
}
//if the next token wasn't a comma, create a number
return Optional.of(parseNumber(data));
}
//called by method parseValue(...)
//parses a decimal of a list of tokens & a string
private Expression parseDecimal(List<Lexer.Token> ts, String data) throws ParserException {
if(ts.size()<1) {
throw new ParserException("SyntaxError: ");
}
if(ts.get(0).getType() != Lexer.TokenType.SPECIAL) {
throw new ParserException("");
}
if(ts.get(1).getType() != Lexer.TokenType.NUMBER) {
throw new ParserException("");
}
Number beforeDot = (Number) parseNumber(data);
ts.remove(0);
data = ts.remove(0).getData();
Number afterDot = (Number) parseNumber(data);
return new Decimal(beforeDot, afterDot);
}
//called by method parseValue(...)
//parses a String into a number
private Expression parseNumber(String data) throws ParserException{
if (data.isEmpty()) {
throw new ParserException("RuntimeException: empty token");
}
if (data.startsWith("0") && data.length() == 1) {
return new Number(data);
}
parseDigitWithoutZero(data);
parseDigit(data);
return new Number(data);
}
//called by method parseNumber(...)
//checks if a String only contains numbers(including zero) with parseCharacter(...)
private void parseDigit(String data) throws ParserException {
for(int index=1; index<data.length(); index++) {
parseCharacter(Character.toString(data.charAt(index)), "0123456789");
}
}
//called by method parseNumber(...)
//checks if a String only contains numbers(excluding zero) with parseCharacter(...)
private void parseDigitWithoutZero(String data) throws ParserException {
for(int index=1; index<data.length(); index++) {
parseCharacter(Character.toString(data.charAt(index)),"123456789");
}
}
private Boolean parseComma(String data) throws ParserException {
return true;
}
}
Loading