summaryrefslogtreecommitdiff
path: root/src/org/unitConverter/math/ExpressionParser.java
diff options
context:
space:
mode:
authorAdrien Hopkins <adrien.p.hopkins@gmail.com>2019-04-14 17:45:16 -0400
committerAdrien Hopkins <adrien.p.hopkins@gmail.com>2019-04-14 17:45:16 -0400
commit2ce65fa76908d77a5e3b045a8eb40c798939b8be (patch)
tree231fcb8f72a467a77efc1e6050de12bd70f7b152 /src/org/unitConverter/math/ExpressionParser.java
parentd7a587694d857fa468c7aae6a5f4fda24f3577fa (diff)
parentb43c399c21bddd3cb8af42c109940564c3890cf7 (diff)
Merge branch 'release-0.2.0' into develop
Diffstat (limited to 'src/org/unitConverter/math/ExpressionParser.java')
-rw-r--r--src/org/unitConverter/math/ExpressionParser.java46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/org/unitConverter/math/ExpressionParser.java b/src/org/unitConverter/math/ExpressionParser.java
index d01afaa..b2261ed 100644
--- a/src/org/unitConverter/math/ExpressionParser.java
+++ b/src/org/unitConverter/math/ExpressionParser.java
@@ -35,8 +35,8 @@ import java.util.function.UnaryOperator;
* @param <T>
* type of object that exists in parsed expressions
* @since 2019-03-14
+ * @since v0.2.0
*/
-// TODO: possibly make this class non-final?
public final class ExpressionParser<T> {
/**
* A builder that can create {@code ExpressionParser<T>} instances.
@@ -45,6 +45,7 @@ public final class ExpressionParser<T> {
* @param <T>
* type of object that exists in parsed expressions
* @since 2019-03-17
+ * @since v0.2.0
*/
public static final class Builder<T> {
/**
@@ -52,6 +53,7 @@ public final class ExpressionParser<T> {
* would use {@code Integer::parseInt}.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Function<String, T> objectObtainer;
@@ -59,6 +61,7 @@ public final class ExpressionParser<T> {
* The function of the space as an operator (like 3 x y)
*
* @since 2019-03-22
+ * @since v0.2.0
*/
private String spaceFunction = null;
@@ -66,6 +69,7 @@ public final class ExpressionParser<T> {
* A map mapping operator strings to operator functions, for unary operators.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Map<String, PriorityUnaryOperator<T>> unaryOperators;
@@ -73,6 +77,7 @@ public final class ExpressionParser<T> {
* A map mapping operator strings to operator functions, for binary operators.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Map<String, PriorityBinaryOperator<T>> binaryOperators;
@@ -84,6 +89,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code objectObtainer} is null
* @since 2019-03-17
+ * @since v0.2.0
*/
public Builder(final Function<String, T> objectObtainer) {
this.objectObtainer = Objects.requireNonNull(objectObtainer, "objectObtainer must not be null.");
@@ -104,6 +110,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code text} or {@code operator} is null
* @since 2019-03-17
+ * @since v0.2.0
*/
public Builder<T> addBinaryOperator(final String text, final BinaryOperator<T> operator, final int priority) {
Objects.requireNonNull(text, "text must not be null.");
@@ -128,6 +135,7 @@ public final class ExpressionParser<T> {
* text of operator to use
* @return this builder
* @since 2019-03-22
+ * @since v0.2.0
*/
public Builder<T> addSpaceFunction(final String operator) {
Objects.requireNonNull(operator, "operator must not be null.");
@@ -152,6 +160,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code text} or {@code operator} is null
* @since 2019-03-17
+ * @since v0.2.0
*/
public Builder<T> addUnaryOperator(final String text, final UnaryOperator<T> operator, final int priority) {
Objects.requireNonNull(text, "text must not be null.");
@@ -171,6 +180,7 @@ public final class ExpressionParser<T> {
/**
* @return an {@code ExpressionParser<T>} instance with the properties given to this builder
* @since 2019-03-17
+ * @since v0.2.0
*/
public ExpressionParser<T> build() {
return new ExpressionParser<>(this.objectObtainer, this.unaryOperators, this.binaryOperators,
@@ -185,11 +195,15 @@ public final class ExpressionParser<T> {
* @param <T>
* type of operand and result
* @since 2019-03-17
+ * @since v0.2.0
*/
private static abstract class PriorityBinaryOperator<T>
implements BinaryOperator<T>, Comparable<PriorityBinaryOperator<T>> {
/**
* The operator's priority. Higher-priority operators are applied before lower-priority operators
+ *
+ * @since 2019-03-17
+ * @since v0.2.0
*/
private final int priority;
@@ -199,6 +213,7 @@ public final class ExpressionParser<T> {
* @param priority
* operator's priority
* @since 2019-03-17
+ * @since v0.2.0
*/
public PriorityBinaryOperator(final int priority) {
this.priority = priority;
@@ -209,6 +224,10 @@ public final class ExpressionParser<T> {
*
* <p>
* {@inheritDoc}
+ * </p>
+ *
+ * @since 2019-03-17
+ * @since v0.2.0
*/
@Override
public int compareTo(final PriorityBinaryOperator<T> o) {
@@ -223,6 +242,7 @@ public final class ExpressionParser<T> {
/**
* @return priority
* @since 2019-03-22
+ * @since v0.2.0
*/
public final int getPriority() {
return this.priority;
@@ -236,11 +256,15 @@ public final class ExpressionParser<T> {
* @param <T>
* type of operand and result
* @since 2019-03-17
+ * @since v0.2.0
*/
private static abstract class PriorityUnaryOperator<T>
implements UnaryOperator<T>, Comparable<PriorityUnaryOperator<T>> {
/**
* The operator's priority. Higher-priority operators are applied before lower-priority operators
+ *
+ * @since 2019-03-17
+ * @since v0.2.0
*/
private final int priority;
@@ -250,6 +274,7 @@ public final class ExpressionParser<T> {
* @param priority
* operator's priority
* @since 2019-03-17
+ * @since v0.2.0
*/
public PriorityUnaryOperator(final int priority) {
this.priority = priority;
@@ -260,6 +285,10 @@ public final class ExpressionParser<T> {
*
* <p>
* {@inheritDoc}
+ * </p>
+ *
+ * @since 2019-03-17
+ * @since v0.2.0
*/
@Override
public int compareTo(final PriorityUnaryOperator<T> o) {
@@ -274,6 +303,7 @@ public final class ExpressionParser<T> {
/**
* @return priority
* @since 2019-03-22
+ * @since v0.2.0
*/
public final int getPriority() {
return this.priority;
@@ -285,6 +315,7 @@ public final class ExpressionParser<T> {
*
* @author Adrien Hopkins
* @since 2019-03-14
+ * @since v0.2.0
*/
private static enum TokenType {
OBJECT, UNARY_OPERATOR, BINARY_OPERATOR;
@@ -294,6 +325,7 @@ public final class ExpressionParser<T> {
* The opening bracket.
*
* @since 2019-03-22
+ * @since v0.2.0
*/
public static final char OPENING_BRACKET = '(';
@@ -301,6 +333,7 @@ public final class ExpressionParser<T> {
* The closing bracket.
*
* @since 2019-03-22
+ * @since v0.2.0
*/
public static final char CLOSING_BRACKET = ')';
@@ -315,6 +348,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if string is null
* @since 2019-03-22
+ * @since v0.2.0
*/
private static int findBracketPair(final String string, final int bracketPosition) {
Objects.requireNonNull(string, "string must not be null.");
@@ -361,6 +395,7 @@ public final class ExpressionParser<T> {
* use {@code Integer::parseInt}.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Function<String, T> objectObtainer;
@@ -368,6 +403,7 @@ public final class ExpressionParser<T> {
* A map mapping operator strings to operator functions, for unary operators.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Map<String, PriorityUnaryOperator<T>> unaryOperators;
@@ -375,6 +411,7 @@ public final class ExpressionParser<T> {
* A map mapping operator strings to operator functions, for binary operators.
*
* @since 2019-03-14
+ * @since v0.2.0
*/
private final Map<String, PriorityBinaryOperator<T>> binaryOperators;
@@ -382,6 +419,7 @@ public final class ExpressionParser<T> {
* The operator for space, or null if spaces have no function.
*
* @since 2019-03-22
+ * @since v0.2.0
*/
private final String spaceOperator;
@@ -397,6 +435,7 @@ public final class ExpressionParser<T> {
* @param spaceOperator
* operator used by spaces
* @since 2019-03-14
+ * @since v0.2.0
*/
private ExpressionParser(final Function<String, T> objectObtainer,
final Map<String, PriorityUnaryOperator<T>> unaryOperators,
@@ -419,6 +458,7 @@ public final class ExpressionParser<T> {
* expression
* @return expression in RPN
* @since 2019-03-17
+ * @since v0.2.0
*/
private String convertExpressionToReversePolish(final String expression) {
Objects.requireNonNull(expression, "expression must not be null.");
@@ -523,6 +563,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if components is null
* @since 2019-03-22
+ * @since v0.2.0
*/
private int findHighestPriorityOperatorPosition(final List<String> components) {
Objects.requireNonNull(components, "components must not be null.");
@@ -572,6 +613,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code expression} is null
* @since 2019-03-14
+ * @since v0.2.0
*/
private TokenType getTokenType(final String token) {
Objects.requireNonNull(token, "token must not be null.");
@@ -593,6 +635,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code expression} is null
* @since 2019-03-14
+ * @since v0.2.0
*/
public T parseExpression(final String expression) {
return this.parseReversePolishExpression(this.convertExpressionToReversePolish(expression));
@@ -607,6 +650,7 @@ public final class ExpressionParser<T> {
* @throws NullPointerException
* if {@code expression} is null
* @since 2019-03-14
+ * @since v0.2.0
*/
private T parseReversePolishExpression(final String expression) {
Objects.requireNonNull(expression, "expression must not be null.");