Skip to content

Commit 0074b2b

Browse files
author
Dominic Beger
committed
Fix parsing not working correctly with all terms
1 parent 29e490e commit 0074b2b

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

SharpMath/Algorithms.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System.Collections.Generic;
44
using SharpMath.Expressions;
5+
using SharpMath.Expressions.Exceptions;
56

67
namespace SharpMath
78
{
@@ -20,8 +21,28 @@ public static IEnumerable<Token> ShuntingYard(List<Token> infixTokens)
2021
var opStack = new Stack<Token<string>>();
2122
var output = new List<Token>(infixTokens.Count);
2223

24+
Token lastToken = null;
2325
foreach (var token in infixTokens)
2426
{
27+
if (lastToken != null)
28+
{
29+
// A constant value or number must be followed by an operator or closing bracket...
30+
if ((lastToken.Type == TokenType.Constant || lastToken.Type == TokenType.Number) &&
31+
(token.Type != TokenType.Operator && !token.IsClosingBracket()))
32+
{
33+
throw new ParserException(
34+
"Cannot calculate the postfix tokens of the given input as the term is invalid. A constant or number must be followed by an operator or a closing bracket.");
35+
}
36+
37+
// A closing bracket must be followed by an operator or another closing bracket...
38+
if (lastToken.IsClosingBracket() && (token.Type != TokenType.Operator && !token.IsClosingBracket()))
39+
{
40+
throw new ParserException(
41+
"Cannot calculate the postfix tokens of the given input as the term is invalid. A closing bracket must be followed by an operator or another closing bracket.");
42+
}
43+
}
44+
45+
lastToken = token;
2546
switch (token.Type)
2647
{
2748
case TokenType.Number:
@@ -33,8 +54,8 @@ public static IEnumerable<Token> ShuntingYard(List<Token> infixTokens)
3354
case TokenType.Operator:
3455
Token<string> currentOperatorToken = (Token<string>) token;
3556
while (opStack.Count > 0 && opStack.Peek().Type == TokenType.Operator &&
36-
!opStack.Peek().IsRightAssociative &&
37-
currentOperatorToken.Priority <= opStack.Peek().Priority)
57+
(!currentOperatorToken.IsRightAssociative &&
58+
(currentOperatorToken.Priority == opStack.Peek().Priority) || currentOperatorToken.Priority < opStack.Peek().Priority))
3859
output.Add(opStack.Pop());
3960
opStack.Push(currentOperatorToken);
4061
break;

SharpMath/Expressions/TokenEx.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace SharpMath.Expressions
2+
{
3+
public static class TokenEx
4+
{
5+
public static bool IsOpeningBracket(this Token token)
6+
{
7+
return token.Type == TokenType.Bracket && ((Token<string>)token).Value == "(";
8+
}
9+
10+
public static bool IsClosingBracket(this Token token)
11+
{
12+
return token.Type == TokenType.Bracket && ((Token<string>) token).Value == ")";
13+
}
14+
}
15+
}

SharpMath/SharpMath.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<Compile Include="Expressions\Exceptions\ParserException.cs" />
4646
<Compile Include="Expressions\Parser.cs" />
4747
<Compile Include="Expressions\Token.cs" />
48+
<Compile Include="Expressions\TokenEx.cs" />
4849
<Compile Include="Expressions\TokenType.cs" />
4950
<Compile Include="Extensions.cs" />
5051
<Compile Include="Algorithms.cs" />

0 commit comments

Comments
 (0)