Skip to content

Commit

Permalink
Add initial template
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasNorlinder committed Nov 9, 2021
1 parent 9386b34 commit 8ae998d
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
73 changes: 73 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.ioopm.calculator</groupId>
<artifactId>symbolic-calculator</artifactId>
<version>1.0-SNAPSHOT</version>

<name>symbolic-calculator</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
25 changes: 25 additions & 0 deletions src/main/java/org/ioopm/calculator/ParserDriver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.ioopm.calculator;

import org.ioopm.calculator.parser.Parser;
import org.ioopm.calculator.parser.SyntaxErrorException;

import java.io.IOException;

class ParserDriver {
public static void main(String[] args) {
Parser p = new Parser();

System.out.println("Welcome to the parser!");
System.out.print("Please enter an expression: ");

try {
double result = p.expression();
System.out.println("result: " + result);
} catch(SyntaxErrorException e) {
System.out.print("Syntax Error: ");
System.out.println(e.getMessage());
} catch(IOException e) {
System.err.println("IO Exception!");
}
}
}
74 changes: 74 additions & 0 deletions src/main/java/org/ioopm/calculator/parser/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.ioopm.calculator.parser;

import java.io.StreamTokenizer;
import java.io.IOException;

public class Parser {
private final StreamTokenizer st = new StreamTokenizer(System.in);

public Parser() {
/// We want to treat - and end of line as an ordinary tokens
this.st.ordinaryChar('-'); /// parse object-oriented as "object" - "oriented" :)
this.st.eolIsSignificant(true);
}

/// This is the top-level expression -- the "entry point"
public double expression() throws IOException {
/// Read a term and make it the current sum
double sum = term();
/// Read the next token and put it in sval/nval/ttype depending on the token
this.st.nextToken();
/// If the token read was + or -, go into the loop
while (this.st.ttype == '+' || this.st.ttype == '-') {
if(this.st.ttype == '+'){
/// If we are adding things, read a term and add it to the current sum
sum += term();
} else {
/// If we are adding things, read a term and subtract it from the current sum
sum -= term();
}
/// Read the next token into sval/nval/ttype so we can go back in the loop again
this.st.nextToken();
}
/// If we came here, we read something which was not a + or -, so we need to put
/// that back again (whatever it was) so that we did not accidentally ate it up!
this.st.pushBack();
/// We are done, return sum
return sum;
}

/// This method works like expression, but with factors and * instead of terms and +/-
private double term() throws IOException {
double prod = factor();
while (this.st.nextToken() == '*') {
prod *= factor();
}
this.st.pushBack();
return prod;
}

private double factor() throws IOException {
double result;
/// If we encounter a (, we know we are reading a full expression, so we call back up
/// to that method, and then try to read a closing ) at the end
if (this.st.nextToken() == '('){
result = expression();
/// This captures unbalanced parentheses!
if (this.st.nextToken() != ')') {
throw new SyntaxErrorException("expected ')'");
}
} else {
this.st.pushBack();
result = number();
}
return result;
}

private double number() throws IOException {
if (this.st.nextToken() == this.st.TT_NUMBER) {
return this.st.nval;
} else {
throw new SyntaxErrorException("Expected number");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.ioopm.calculator.parser;

public class SyntaxErrorException extends RuntimeException {
public SyntaxErrorException() {
super();
}
public SyntaxErrorException(String msg) {
super(msg);
}
}
20 changes: 20 additions & 0 deletions src/test/java/org/ioopm/calculator/ParserDriverTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.ioopm.calculator;

import static org.junit.Assert.assertTrue;

import java.io.StreamTokenizer;
import java.lang.reflect.Field;

import org.ioopm.calculator.parser.Parser;
import org.junit.Test;

public class ParserDriverTest {
@Test
public void checkFieldsAreInitalized() throws NoSuchFieldException, IllegalAccessException {
Parser p = new Parser();
// Field is private so need to use reflection!
Field streamTokenizerField = Parser.class.getDeclaredField("st");
streamTokenizerField.setAccessible(true);
assertTrue((StreamTokenizer)streamTokenizerField.get(p) != null);
}
}

0 comments on commit 8ae998d

Please sign in to comment.