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

advanced the project structure & implemented the lexer test class

parent 105444dc
No related branches found
No related tags found
1 merge request!12advanced the project structure & implemented the lexer test class
1+(x^2)-(3*x) 1+(x^2)-(3*x)
2*x+0.5*(x^2)-1 2*x+0.5*(x^2+4)-1
\ No newline at end of file \ No newline at end of file
package Exceptions;
public class LexerException extends Exception {
public LexerException(String message) {
super(message);
}
}
package Exceptions;
public class ParserException extends Exception{ public class ParserException extends Exception{
public ParserException(String message) { public ParserException(String message) {
super(message); super(message);
......
package main;
public class ASTPrinter implements Visitor<String>{ public class ASTPrinter implements Visitor<String>{
@Override @Override
public String visit(final Parser.BinaryOperation binaryOP) { public String visit(final Parser.BinaryOperation binaryOP) {
......
package main;
import Exceptions.LexerException;
import Exceptions.ParserException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -6,34 +12,47 @@ import java.util.List; ...@@ -6,34 +12,47 @@ import java.util.List;
public class Application { public class Application {
public static void main(String[] args) { public static void main(String[] args) {
//A list that will contain a String for each line of the "expressions.txt" file
List<String> expressions = new LinkedList<>(); List<String> expressions = new LinkedList<>();
//Reads the file "expressions.txt" and adds its values to a list //Reads the file "expressions.txt" and adds its values to the list expressions
BufferedReader reader; BufferedReader reader;
String dataPath = "expressions.txt"; String datapath = "expressions.txt";
try { try {
System.out.println("Reading the file...\n"); System.out.println("Reading the file...\n");
reader = new BufferedReader(new FileReader(dataPath)); reader = new BufferedReader(new FileReader(datapath));
String line = reader.readLine(); String currentLine = reader.readLine();
while(line != null) { while(currentLine !=null) {
expressions.add(line); expressions.add(currentLine);
line = reader.readLine(); currentLine = reader.readLine();
} }
reader.close(); reader.close();
} }
catch (IOException e ) { catch(IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
//Iterate through every String
for (String expression: expressions) {
System.out.println("Expression: " + expression);
//Usage of the lexer, parser & evaluator
try {
//Create a list of tokens with the lexer
List<Lexer.Token> tokens = Lexer.lex(expression);
System.out.println("Lexer created tokens:");
//prints out each token to the console
for(Lexer.Token token: tokens) {
System.out.println(token.toString());
}
}
catch (Exception e) {
e.printStackTrace();
}
}
/*
//Iterates through every String and parses them into multiple tokens //Iterates through every String and parses them into multiple tokens
for (String value: expressions) { for (String value: expressions) {
System.out.println(value);
//creates a list of tokens out of the String
List<Lexer.Token> tokens = Lexer.lex(value);
//prints each token out (with .toString())
for(Lexer.Token singleToken: tokens) {
System.out.println(singleToken.toString());
}
Parser parser = new Parser(); Parser parser = new Parser();
try { try {
Parser.Expression exp = parser.parse(tokens); Parser.Expression exp = parser.parse(tokens);
...@@ -48,6 +67,6 @@ public class Application { ...@@ -48,6 +67,6 @@ public class Application {
System.out.println(e.getMessage()); System.out.println(e.getMessage());
} }
System.out.println(); System.out.println();
} }*/
} }
} }
package main;
public class Evaluator implements Visitor<Double>{ public class Evaluator implements Visitor<Double>{
@Override @Override
...@@ -16,6 +18,7 @@ public class Evaluator implements Visitor<Double>{ ...@@ -16,6 +18,7 @@ public class Evaluator implements Visitor<Double>{
result -= rOperand; result -= rOperand;
break; break;
case '*': case '*':
rOperand *= rOperand;
result *= rOperand; result *= rOperand;
break; break;
case '/': case '/':
......
package main;
import Exceptions.LexerException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -9,7 +13,7 @@ public class Lexer { ...@@ -9,7 +13,7 @@ public class Lexer {
} }
//tokens with a TokenType that represents their type and a String with the actual data //tokens with a TokenType that represents their type and a String with the actual data
//has for both values a getter method and overrides toString with it's fitting values //has for both values a getter method and overrides toString with its fitting values
public static class Token { public static class Token {
protected TokenType type; protected TokenType type;
protected String data; protected String data;
...@@ -33,15 +37,19 @@ public class Lexer { ...@@ -33,15 +37,19 @@ public class Lexer {
} }
//creates a list of tokens from a given String //creates a list of tokens from a given String
public static List<Token> lex(String input) { public static List<Token> lex(String input) throws Exception{
if(input.isEmpty()) {
throw new LexerException("SyntaxError: lexer received empty String");
}
//the list that will be returned at the end //the list that will be returned at the end
List<Token> result = new LinkedList<Token>(); List<Token> result = new LinkedList<Token>();
//for-loop that iterates through each character of the String //for-loop that iterates through each character of the String
for(int index=0; index < input.length();) { for(int index=0; index < input.length();) {
char current = input.charAt(index); char current = input.charAt(index);
//checks if a character is a digit, then creates a token with one or multiple numbers //checks if a character is a digit, then creates a token with one or multiple
//with TokenType=NUMBER //numbers with TokenType=NUMBER
if(Character.isDigit(current)) { if(Character.isDigit(current)) {
int endIndex = index; int endIndex = index;
if(endIndex<input.length()) { if(endIndex<input.length()) {
......
package main;
import Exceptions.ParserException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
...@@ -21,6 +25,10 @@ public class Parser { ...@@ -21,6 +25,10 @@ public class Parser {
public <T> T accept(Visitor<T> visitor) { public <T> T accept(Visitor<T> visitor) {
return visitor.visit(this); return visitor.visit(this);
} }
public <T> T accept(Visitor<T> vistor, String operator) {
return vistor.visit(this);
}
} }
public class Variable extends Expression { public class Variable extends Expression {
......
package main;
import com.mindfusion.charting.FunctionSeries; import com.mindfusion.charting.FunctionSeries;
import com.mindfusion.charting.swing.LineChart; import com.mindfusion.charting.swing.LineChart;
......
package main;
public interface Visitor<T>{ public interface Visitor<T>{
public T visit(final Parser.BinaryOperation binOp); public T visit(final Parser.BinaryOperation binOp);
public T visit(final Parser.Variable variable); public T visit(final Parser.Variable variable);
......
package test;
import org.junit.Test;
import main.*;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class LexerTest {
@Test
void disassembleFirstStringWithLexer() {
String s = "3+x*(2^4)";
List<Lexer.Token> tokens = new LinkedList<>();
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"3"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"+"));
tokens.add(new Lexer.Token(Lexer.TokenType.VARIABLE,"x"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"*"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"("));
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"2"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"^"));
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"4"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,")"));
try {
assertEquals(Lexer.lex(s),tokens);
}
catch(Exception e) {
e.printStackTrace();
}
}
@Test
void disassembleSecondStringWithLexer() {
String s = "1 + (x^2 )- (3*x)";
List<Lexer.Token> tokens = new LinkedList<>();
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"1"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"+"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"("));
tokens.add(new Lexer.Token(Lexer.TokenType.VARIABLE,"x"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"^"));
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"2"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,")"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"-"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"("));
tokens.add(new Lexer.Token(Lexer.TokenType.NUMBER,"3"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,"*"));
tokens.add(new Lexer.Token(Lexer.TokenType.VARIABLE,"x"));
tokens.add(new Lexer.Token(Lexer.TokenType.SPECIAL,")"));
try {
assertEquals(Lexer.lex(s),tokens);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
\ No newline at end of file
package test;
public class ParserTest {
}
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