Skip to content
Snippets Groups Projects
Commit cf603445 authored by Dominic Daniel Krämer's avatar Dominic Daniel Krämer
Browse files

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

parent b7b368c6
No related branches found
No related tags found
1 merge request!4implemented the parser with basic functionality for values, numbers and decimals
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;
}
}
public class ParserException extends Exception{
public ParserException(String message) {
super(message);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment