-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9386b34
commit 8ae998d
Showing
5 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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!"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/org/ioopm/calculator/parser/SyntaxErrorException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} |