From bae1617237f4636a5066d00b761290afbe14539a Mon Sep 17 00:00:00 2001 From: Kraemerd <Dominic_Daniel.Kraemer@Student.Reutlingen-University.de> Date: Mon, 9 Jan 2023 23:20:09 +0100 Subject: [PATCH] implemented that * and / get calculated before + and - (if the next expression is not capsuled) --- expressions.txt | 13 ++++---- src/main/ASTPrinter.java | 3 ++ src/main/Application.java | 6 +++- src/main/Evaluator.java | 64 +++++++++++++++++++++++++++++---------- src/main/Parser.java | 36 +++++++++++++++++++--- src/main/Visitor.java | 2 ++ src/test/LexerTest.java | 8 ++--- src/test/ParserTest.java | 14 ++++----- 8 files changed, 108 insertions(+), 38 deletions(-) diff --git a/expressions.txt b/expressions.txt index bcba895..ba3d614 100644 --- a/expressions.txt +++ b/expressions.txt @@ -1,6 +1,7 @@ -2*(4^2) -(4+2)*4 -(4+2*(4-2)) -((3+2)*(12+2)) -1+(x^2.22)-(3*x) -2*x+0.5*(x^2+4)-1 \ No newline at end of file +1+1 +2*4+x +2*5+2 +2+5*2 +2*(5+2) +20*(5^2) +(x^2)+50*x+2 \ No newline at end of file diff --git a/src/main/ASTPrinter.java b/src/main/ASTPrinter.java index 118fb24..2b7c72b 100644 --- a/src/main/ASTPrinter.java +++ b/src/main/ASTPrinter.java @@ -1,5 +1,7 @@ package main; +import java.util.List; + /** * <h1>The ASTPrinter</h1> * The ASTPrinter class creates a String out of an AST(represented through an Expression object) @@ -15,6 +17,7 @@ public class ASTPrinter implements Visitor<String>{ * Builds a String representation of a given BinaryOperation * It gets a String representation of its left and right Expressions (which may result in a * recursive call) and combines them into one String together with the operator + * * @param binaryOP The BinaryOperation that should be printed into a String * @return String Returns the String that was build */ diff --git a/src/main/Application.java b/src/main/Application.java index 3c5b0cf..dd30e02 100644 --- a/src/main/Application.java +++ b/src/main/Application.java @@ -36,8 +36,10 @@ public class Application { List<Lexer.Token> tokens = Lexer.lex(expressionString); System.out.println("Lexer created tokens:"); //prints out each token to the console + int i = 0; for(Lexer.Token token: tokens) { - System.out.println(token.toString()); + System.out.println("[" + i + "]" + token.toString()); + i++; } //Parse all tokens with the parser and saves the result into the variable 'ast' Parser parser = new Parser(); @@ -46,6 +48,8 @@ public class Application { //the result can later be used to show the ast in a function plotter ASTPrinter printer = new ASTPrinter(); System.out.println("Printing: '" + printer.visit(ast) + "'"); + Evaluator evaluator = new Evaluator(); + System.out.println(evaluator.visit(ast, 20)); System.out.println(); } catch (Exception e) { diff --git a/src/main/Evaluator.java b/src/main/Evaluator.java index 7f51f3c..62a37d8 100644 --- a/src/main/Evaluator.java +++ b/src/main/Evaluator.java @@ -1,50 +1,84 @@ package main; +import java.util.LinkedList; +import java.util.List; + public class Evaluator implements Visitor<Double>{ + private int x; + @Override public Double visit(final Parser.BinaryOperation binaryOP) { - double result = binaryOP.leftExpression.accept(this); - Double rOperand = binaryOP.rightExpression.accept(this); - if(rOperand==null) { + int range = 20; + List<Double> results = new LinkedList<>(); + for(int index=-20; index<=range; index++) { } + double result = binaryOP.leftExpression.accept(this); + double rOperand; + switch (binaryOP.operator.charAt(0)) { case '+': + rOperand = binaryOP.rightExpression.accept(this); result += rOperand; break; case '-': + rOperand = binaryOP.rightExpression.accept(this); result -= rOperand; break; case '*': - rOperand *= rOperand; - result *= rOperand; + if(binaryOP.rightExpression instanceof Parser.BinaryOperation) {; + if(((Parser.BinaryOperation) binaryOP.rightExpression).capsuled) { + rOperand = binaryOP.rightExpression.accept(this); + result *= rOperand; + } + else { + //*************************************************************************************** + result = ((Parser.BinaryOperation) binaryOP.rightExpression).accept(this, result, "*"); + } + } + else { + rOperand = binaryOP.rightExpression.accept(this); + result *= rOperand; + } break; case '/': - if (rOperand != 0) { - result /= rOperand; + if (binaryOP.rightExpression instanceof Parser.BinaryOperation) { + if(binaryOP.capsuled) { + rOperand = binaryOP.rightExpression.accept(this); + result /= rOperand; + } + else { + //*************************************************************************************** + result = ((Parser.BinaryOperation) binaryOP.rightExpression).accept(this, result, "/"); + } } else { - result = result; - //throw new ArithmeticException("Arithmetic Error: division by zero detected"); + rOperand = binaryOP.rightExpression.accept(this); + if(rOperand!=0) { + result /= rOperand; + } + else { + throw new ArithmeticException("Arithmetic Error: division by zero detected"); + } } break; case '^': + rOperand = binaryOP.rightExpression.accept(this); for(int i=1; i<rOperand; i++) { result = result*result; } break; default: - throw new RuntimeException("SematicError: unknown operand found in AST: " - + binaryOP.operator); + throw new RuntimeException("SemanticError: unknown operand found in AST: " + binaryOP.operator); } return result; } @Override public Double visit(final Parser.Variable variable) { - return 0.0; + return variable.value * x; } @Override @@ -57,10 +91,8 @@ public class Evaluator implements Visitor<Double>{ return Double.valueOf(decimal.afterDot.digits + "." + decimal.beforeDot.digits); } - public double visit(final Parser.Expression ast) { - if(ast==null) { - return 0.0; - } + public Double visit(final Parser.Expression ast, int x) { + this.x = x; return ast.accept(this); } } diff --git a/src/main/Parser.java b/src/main/Parser.java index 8b7cb02..73327dd 100644 --- a/src/main/Parser.java +++ b/src/main/Parser.java @@ -22,6 +22,7 @@ public class Parser { */ public abstract class Expression { public abstract <T> T accept(Visitor<T> visitor); + public abstract <T> T accept(Visitor<T> visitor, double leftValue, String operator); } /** @@ -40,11 +41,13 @@ public class Parser { this.rightExpression = rightExpression; this.capsuled = capsuled; } + @Override public <T> T accept(Visitor<T> visitor) { return visitor.visit(this); } - public <T> T accept(Visitor<T> visitor, String operator) { + public <T> T accept(Visitor<T> visitor, double leftValue, String operator) { + leftExpression.accept(visitor, leftValue, operator); return visitor.visit(this); } } @@ -54,13 +57,24 @@ public class Parser { * of the alphabet */ public class Variable extends Expression { + double value; String variableName; - public Variable(String i, Boolean capsuled) { - this.variableName = i; + public Variable(String i) { + this.value = 1.0; + variableName = i; } public <T> T accept(Visitor<T> visitor) { return visitor.visit(this); } + public <T> T accept(Visitor<T> visitor, double leftValue, String operator) { + if(operator.equals("*")) { + this.value = leftValue; + } + else { + this.value = 1/leftValue; + } + return visitor.visit(this); + } } /** @@ -82,6 +96,15 @@ public class Parser { public <T> T accept(Visitor<T> visitor) { return visitor.visit(this); } + public <T> T accept(Visitor<T> visitor, double leftValue, String operator) { + if(operator.equals("*")) { + this.digits = String.valueOf((leftValue * Double.parseDouble(this.digits))); + } + else { + this.digits = String.valueOf((leftValue / Integer.parseInt(this.digits))); + } + return visitor.visit(this); + } } /** @@ -98,6 +121,11 @@ public class Parser { public <T> T accept(Visitor<T> visitor) { return visitor.visit(this); } + public <T> T accept(Visitor<T> visitor, double leftValue, String operator) { + beforeDot.accept(visitor, leftValue, operator); + afterDot.accept(visitor, leftValue, operator); + return visitor.visit(this); + } } /** @@ -298,7 +326,7 @@ public class Parser { if(!parseCharacter(data,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")) { throw new ParserException("Invalid variable character: " + data); } - return new Variable(data, false); + return new Variable(data); } diff --git a/src/main/Visitor.java b/src/main/Visitor.java index 88d87ae..246556f 100644 --- a/src/main/Visitor.java +++ b/src/main/Visitor.java @@ -1,5 +1,7 @@ package main; +import java.util.List; + public interface Visitor<T>{ public T visit(final Parser.BinaryOperation binOp); public T visit(final Parser.Variable variable); diff --git a/src/test/LexerTest.java b/src/test/LexerTest.java index 54356a6..aaceea7 100644 --- a/src/test/LexerTest.java +++ b/src/test/LexerTest.java @@ -3,16 +3,16 @@ package test; import org.junit.Test; import main.*; -import java.io.IOException; import java.util.LinkedList; import java.util.List; +import static org.junit.Assert.assertThat; import static org.junit.jupiter.api.Assertions.*; -class LexerTest { + class LexerTest { @Test - void disassembleFirstStringWithLexer() { + public void disassembleFirstStringWithLexer() { String s = "3+x*(2^4)"; List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"3")); @@ -33,7 +33,7 @@ class LexerTest { } @Test - void disassembleSecondStringWithLexer() { + public void disassembleSecondStringWithLexer() { String s = "1 + (x^2 )- (3*x)"; List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"1")); diff --git a/src/test/ParserTest.java b/src/test/ParserTest.java index 2d70d2e..e58b077 100644 --- a/src/test/ParserTest.java +++ b/src/test/ParserTest.java @@ -7,10 +7,10 @@ import org.junit.Test; import java.util.LinkedList; import java.util.List; -public class ParserTest { +class ParserTest { @Test - void testParseVariable() { + public void testParseVariable() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.VARIABLE,"x")); var parser = new Parser(); @@ -23,7 +23,7 @@ public class ParserTest { } @Test - void testWrongVariableInput() { + public void testWrongVariableInput() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.VARIABLE,"xy")); var parser = new Parser(); @@ -36,7 +36,7 @@ public class ParserTest { } @Test - void testParseNumber() { + public void testParseNumber() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"23")); var parser = new Parser(); @@ -49,7 +49,7 @@ public class ParserTest { } @Test - void testWrongNumberInput() { + public void testWrongNumberInput() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"02.4")); var parser = new Parser(); @@ -62,7 +62,7 @@ public class ParserTest { } @Test - void testParseBinaryOperation() { + public void testParseBinaryOperation() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"(")); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"5")); @@ -81,7 +81,7 @@ public class ParserTest { } @Test - void testParseWrongBinaryOperation() { + public void testParseWrongBinaryOperation() { List<Lexer.Token> tokens = new LinkedList<>(); tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"(")); tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"5")); -- GitLab