Skip to content

Commit 07e63c0

Browse files
Handle null GroupingDirection
1 parent 208609e commit 07e63c0

File tree

1 file changed

+26
-11
lines changed
  • src/main/java/net/marcellperger/mathexpr/parser

1 file changed

+26
-11
lines changed

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

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,20 @@ public MathSymbol parseInfixPrecedenceLevel(int level) throws ExprParseException
8383
PrecedenceLevelInfo precInfo = SymbolInfo.PREC_LEVELS_INFO.get(level);
8484
if (precInfo == null) return parseInfixPrecedenceLevel(level - 1);
8585
MathSymbol left = parseInfixPrecedenceLevel(level - 1);
86-
if(precInfo.dirn == GroupingDirection.RightToLeft) {
87-
return parseInfixPrecedenceLevel_RTL(left, precInfo);
88-
}
89-
return parseInfixPrecedenceLevel_LTR(left, precInfo);
90-
// TODO what if dirn == null? Maybe just disallow the ambiguous case of > 2 operands in same level
86+
return switch (precInfo.dirn) {
87+
case LeftToRight -> parseInfixPrecedenceLevel_LTR(left, precInfo);
88+
case RightToLeft -> parseInfixPrecedenceLevel_RTL(left, precInfo);
89+
case null -> parseInfixPrecedenceLevel_noDirn(left, precInfo);
90+
};
9191
}
9292

9393
private MathSymbol parseInfixPrecedenceLevel_RTL(MathSymbol left, PrecedenceLevelInfo precInfo) throws ExprParseException {
9494
String op;
9595
List<Pair<SymbolInfo, MathSymbol>> otherOps = new ArrayList<>();
96-
discardWhitespace();
97-
while((op = discardMatchesNextAny_optionsSorted(precInfo.sortedInfixes)) != null) {
96+
while((op = discardMatchesNextAny_optionsSorted_removeWs(precInfo.sortedInfixes)) != null) {
9897
otherOps.add(new Pair<>(
9998
Util.getNotNull(precInfo.infixToSymbolMap, op),
10099
parseInfixPrecedenceLevel(precInfo.precedence - 1)));
101-
discardWhitespace();
102100
}
103101
return otherOps.reversed().stream().reduce((rightpair, leftpair) ->
104102
leftpair.asVars((preOp, argL) ->
@@ -108,15 +106,24 @@ private MathSymbol parseInfixPrecedenceLevel_RTL(MathSymbol left, PrecedenceLeve
108106

109107
private MathSymbol parseInfixPrecedenceLevel_LTR(MathSymbol left, PrecedenceLevelInfo precInfo) throws ExprParseException {
110108
String op;
111-
discardWhitespace();
112-
while((op = discardMatchesNextAny_optionsSorted(precInfo.sortedInfixes)) != null) {
109+
while((op = discardMatchesNextAny_optionsSorted_removeWs(precInfo.sortedInfixes)) != null) {
113110
left = BinaryOperation.construct(
114111
left, Util.getNotNull(precInfo.infixToSymbolMap, op), parseInfixPrecedenceLevel(precInfo.precedence - 1));
115-
discardWhitespace();
116112
}
117113
return left;
118114
}
119115

116+
private MathSymbol parseInfixPrecedenceLevel_noDirn(MathSymbol left, PrecedenceLevelInfo precInfo) throws ExprParseException {
117+
String op;
118+
if((op = discardMatchesNextAny_optionsSorted_removeWs(precInfo.sortedInfixes)) == null) return left;
119+
MathSymbol result = BinaryOperation.construct(
120+
left, Util.getNotNull(precInfo.infixToSymbolMap, op), parseInfixPrecedenceLevel(precInfo.precedence - 1));
121+
if(matchesNextAny_optionsSorted_removeWs(precInfo.sortedInfixes) != null) {
122+
throw new ExprParseException("Error: parens are required for precedence levels without a GroupingDirection");
123+
}
124+
return result;
125+
}
126+
120127
// region utils
121128
protected CharSequence strFromHere() {
122129
return CharBuffer.wrap(src, idx, src.length());
@@ -175,11 +182,19 @@ protected boolean matchesNext(@NotNull String expected) {
175182
private @Nullable String matchesNextAny_optionsSorted(@NotNull List<@NotNull String> expected) {
176183
return expected.stream().filter(this::matchesNext).findFirst().orElse(null);
177184
}
185+
private @Nullable String matchesNextAny_optionsSorted_removeWs(@NotNull List<@NotNull String> expected) {
186+
discardWhitespace();
187+
return matchesNextAny_optionsSorted(expected);
188+
}
178189
private @Nullable String discardMatchesNextAny_optionsSorted(@NotNull List<@NotNull String> expected) {
179190
String s = matchesNextAny_optionsSorted(expected);
180191
if(s != null) discardN(s.length());
181192
return s;
182193
}
194+
private @Nullable String discardMatchesNextAny_optionsSorted_removeWs(@NotNull List<@NotNull String> expected) {
195+
discardWhitespace();
196+
return discardMatchesNextAny_optionsSorted(expected);
197+
}
183198
@SuppressWarnings("unused")
184199
protected @Nullable String matchesNextAny(@NotNull List<@NotNull String> expected) {
185200
// Try to longer ones first, then shorter ones.

0 commit comments

Comments
 (0)