Skip to content

Commit f04a0bf

Browse files
Allow empty precedence levels
1 parent e77eb30 commit f04a0bf

3 files changed

Lines changed: 19 additions & 13 deletions

File tree

src/main/java/net/marcellperger/mathexpr/parser/Parser.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,10 @@ public MathSymbol parseInfixPrecedenceLevel(int level) throws ExprParseException
8080
if(level == 0) {
8181
return parseParensOrLiteral();
8282
}
83-
// TODO remove this next-line:
84-
if(SymbolInfo.PREC_TO_INFO_MAP.get(level) == null) { return parseInfixPrecedenceLevel(level - 1); }
85-
Set<SymbolInfo> symbols = Util.requireNonEmptyNonNull(SymbolInfo.PREC_TO_INFO_MAP.get(level));
83+
Set<SymbolInfo> symbols = SymbolInfo.PREC_TO_INFO_MAP.get(level);
84+
if(symbols == null || symbols.isEmpty()) return parseInfixPrecedenceLevel(level - 1);
8685
@Nullable GroupingDirection dirn = symbols.stream()
87-
.map(sm -> sm.groupingDirection).distinct().collect(UtilCollectors.singleItem());
86+
.map(sm -> sm.groupingDirection).collect(UtilCollectors.singleDistinctItem());
8887
Map<String, SymbolInfo> infixToSymbolInfo = symbols.stream().collect( // TODO pre-compute/cache these
8988
Collectors.toUnmodifiableMap(
9089
si -> Objects.requireNonNull(si.infix, "null infix not allowed for parseInfixPrecedenceLevel"),

src/main/java/net/marcellperger/mathexpr/util/Util.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package net.marcellperger.mathexpr.util;
22

33

4+
import org.intellij.lang.annotations.Flow;
45
import org.jetbrains.annotations.Contract;
56
import org.jetbrains.annotations.NotNull;
67
import org.jetbrains.annotations.Nullable;
78

8-
import java.util.AbstractMap;
9-
import java.util.Collection;
10-
import java.util.Map;
11-
import java.util.Objects;
9+
import java.util.*;
1210
import java.util.function.Function;
1311
import java.util.function.Predicate;
12+
import java.util.stream.Stream;
1413

1514
@SuppressWarnings("unused")
1615
public class Util {
@@ -168,4 +167,13 @@ public static void realAssert(boolean b, String msg, Throwable cause) {
168167
public static @NotNull <K, V> Map.Entry<K, V> makeEntry(K k, V v) {
169168
return new AbstractMap.SimpleImmutableEntry<>(k, v);
170169
}
170+
171+
public static<T> T getOnlyItem(@Flow(sourceIsContainer = true) @NotNull Collection<T> c) {
172+
if(c.size() != 1) throw new CollectionSizeException("Expected collection to have 1 item");
173+
return c.iterator().next();
174+
}
175+
public static<T> T getOnlyItem(@Flow(sourceIsContainer = true) @NotNull SequencedCollection<T> c) {
176+
if(c.size() != 1) throw new CollectionSizeException("Expected collection to have 1 item");
177+
return c.getFirst();
178+
}
171179
}

src/main/java/net/marcellperger/mathexpr/util/UtilCollectors.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ protected UtilCollectors() {} // prevent instantiation, allow subclassing
1414

1515
@Contract(" -> new")
1616
public static <T> @NotNull Collector<T, ?, T> singleItem() {
17-
return Collectors.collectingAndThen(
18-
Collectors.toList(),
19-
items -> Util.expectOrFail(items, items.size() == 1,
20-
new CollectionSizeException("UtilCollectors.singleItem expected a single item")).getFirst()
21-
);
17+
return Collectors.collectingAndThen(Collectors.toList(), Util::getOnlyItem);
18+
}
19+
public static <T> @NotNull Collector<T, ?, T> singleDistinctItem() {
20+
return Collectors.collectingAndThen(Collectors.toSet(), Util::getOnlyItem);
2221
}
2322

2423
public static <K, V> @NotNull Collector<Entry<K, V>, ?, Map<K, V>> entriesToUnmodifiableMap() {

0 commit comments

Comments
 (0)