Parser: Multiplication, division and parenthesis.
This commit is contained in:
@@ -5,6 +5,8 @@ namespace VAR.ExpressionEvaluator.Tests
|
|||||||
[TestClass()]
|
[TestClass()]
|
||||||
public class ParserTests
|
public class ParserTests
|
||||||
{
|
{
|
||||||
|
#region Plus and Minus
|
||||||
|
|
||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
public void ParseString__Ten_EqualsTen()
|
public void ParseString__Ten_EqualsTen()
|
||||||
{
|
{
|
||||||
@@ -37,6 +39,10 @@ namespace VAR.ExpressionEvaluator.Tests
|
|||||||
Assert.AreEqual(900000m, result);
|
Assert.AreEqual(900000m, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Plus and minus
|
||||||
|
|
||||||
|
#region Number signs
|
||||||
|
|
||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
public void ParseString__MinusTen()
|
public void ParseString__MinusTen()
|
||||||
{
|
{
|
||||||
@@ -77,5 +83,67 @@ namespace VAR.ExpressionEvaluator.Tests
|
|||||||
Assert.AreEqual(-40m, result);
|
Assert.AreEqual(-40m, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Number signs
|
||||||
|
|
||||||
|
#region Multiplication and division
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__10MutiplyBy2()
|
||||||
|
{
|
||||||
|
string expression = "10 * 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(20m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__10DividedBy2()
|
||||||
|
{
|
||||||
|
string expression = "10 / 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(5m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__5DividedBy2()
|
||||||
|
{
|
||||||
|
string expression = "5 / 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(2.5m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__5DividedBy2Plus1()
|
||||||
|
{
|
||||||
|
string expression = "5 / 2 + 1";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(3.5m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__1Plus5DividedBy2()
|
||||||
|
{
|
||||||
|
string expression = "1 + 5 / 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(3.5m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__5DividedByParen1Plus1()
|
||||||
|
{
|
||||||
|
string expression = "5 / (1 + 1)";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(2.5m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__Paren2Plus2DividedByParen1Plus1()
|
||||||
|
{
|
||||||
|
string expression = "(2 + 2) / (1 + 1)";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(2m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Multiplication and division
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ namespace VAR.ExpressionEvaluator.Tests
|
|||||||
var t = new Tokenizer(new StringReader(testString));
|
var t = new Tokenizer(new StringReader(testString));
|
||||||
|
|
||||||
// "("
|
// "("
|
||||||
Assert.AreEqual(t.Token, Token.ParentesisStart);
|
Assert.AreEqual(t.Token, Token.ParenthesisStart);
|
||||||
t.NextToken();
|
t.NextToken();
|
||||||
|
|
||||||
// "10"
|
// "10"
|
||||||
@@ -138,7 +138,7 @@ namespace VAR.ExpressionEvaluator.Tests
|
|||||||
t.NextToken();
|
t.NextToken();
|
||||||
|
|
||||||
// ")"
|
// ")"
|
||||||
Assert.AreEqual(t.Token, Token.ParentesisEnd);
|
Assert.AreEqual(t.Token, Token.ParenthesisEnd);
|
||||||
t.NextToken();
|
t.NextToken();
|
||||||
|
|
||||||
// "*"
|
// "*"
|
||||||
|
|||||||
15
VAR.ExpressionEvaluator/ExpressionDivisionNode.cs
Normal file
15
VAR.ExpressionEvaluator/ExpressionDivisionNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace VAR.ExpressionEvaluator
|
||||||
|
{
|
||||||
|
public class ExpressionDivisionNode : ExpressionBinaryNode
|
||||||
|
{
|
||||||
|
public ExpressionDivisionNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||||
|
base(leftNode, rightNode, DivisionOp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object DivisionOp(object leftValue, object rightValue)
|
||||||
|
{
|
||||||
|
return (decimal)leftValue / (decimal)rightValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
VAR.ExpressionEvaluator/ExpressionMultiplyNode.cs
Normal file
15
VAR.ExpressionEvaluator/ExpressionMultiplyNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace VAR.ExpressionEvaluator
|
||||||
|
{
|
||||||
|
public class ExpressionMultiplyNode : ExpressionBinaryNode
|
||||||
|
{
|
||||||
|
public ExpressionMultiplyNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||||
|
base(leftNode, rightNode, MultiplyOp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object MultiplyOp(object leftValue, object rightValue)
|
||||||
|
{
|
||||||
|
return (decimal)leftValue * (decimal)rightValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,19 +26,19 @@ namespace VAR.ExpressionEvaluator
|
|||||||
|
|
||||||
public IExpressionNode ParsePlusAndMinus()
|
public IExpressionNode ParsePlusAndMinus()
|
||||||
{
|
{
|
||||||
IExpressionNode leftNode = ParseUnary();
|
IExpressionNode leftNode = ParseMultiplyDivision();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (_tokenizer.Token == Token.Plus)
|
if (_tokenizer.Token == Token.Plus)
|
||||||
{
|
{
|
||||||
_tokenizer.NextToken();
|
_tokenizer.NextToken();
|
||||||
IExpressionNode rightNode = ParseUnary();
|
IExpressionNode rightNode = ParseMultiplyDivision();
|
||||||
leftNode = new ExpressionPlusNode(leftNode, rightNode);
|
leftNode = new ExpressionPlusNode(leftNode, rightNode);
|
||||||
}
|
}
|
||||||
else if (_tokenizer.Token == Token.Minus)
|
else if (_tokenizer.Token == Token.Minus)
|
||||||
{
|
{
|
||||||
_tokenizer.NextToken();
|
_tokenizer.NextToken();
|
||||||
IExpressionNode rightNode = ParseUnary();
|
IExpressionNode rightNode = ParseMultiplyDivision();
|
||||||
leftNode = new ExpressionMinusNode(leftNode, rightNode);
|
leftNode = new ExpressionMinusNode(leftNode, rightNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -48,6 +48,31 @@ namespace VAR.ExpressionEvaluator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IExpressionNode ParseMultiplyDivision()
|
||||||
|
{
|
||||||
|
IExpressionNode lhs = ParseUnary();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (_tokenizer.Token == Token.Multiply)
|
||||||
|
{
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
IExpressionNode rhs = ParseUnary();
|
||||||
|
lhs = new ExpressionMultiplyNode(lhs, rhs);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (_tokenizer.Token == Token.Division)
|
||||||
|
{
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
IExpressionNode rhs = ParseUnary();
|
||||||
|
lhs = new ExpressionDivisionNode(lhs, rhs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IExpressionNode ParseUnary()
|
private IExpressionNode ParseUnary()
|
||||||
{
|
{
|
||||||
if (_tokenizer.Token == Token.Plus)
|
if (_tokenizer.Token == Token.Plus)
|
||||||
@@ -73,6 +98,18 @@ namespace VAR.ExpressionEvaluator
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_tokenizer.Token == Token.ParenthesisStart)
|
||||||
|
{
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
var node = ParsePlusAndMinus();
|
||||||
|
if (_tokenizer.Token != Token.ParenthesisEnd)
|
||||||
|
{
|
||||||
|
throw new Exception("Missing close parenthesis");
|
||||||
|
}
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
throw new Exception(string.Format("Unexpected token: {0}", _tokenizer.Token.ToString()));
|
throw new Exception(string.Format("Unexpected token: {0}", _tokenizer.Token.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
GreaterOrEqualThan,
|
GreaterOrEqualThan,
|
||||||
LessThan,
|
LessThan,
|
||||||
LessOrEqualThan,
|
LessOrEqualThan,
|
||||||
ParentesisStart,
|
ParenthesisStart,
|
||||||
ParentesisEnd,
|
ParenthesisEnd,
|
||||||
Keyword,
|
Keyword,
|
||||||
String,
|
String,
|
||||||
Number,
|
Number,
|
||||||
|
|||||||
@@ -93,12 +93,12 @@ namespace VAR.ExpressionEvaluator
|
|||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
NextChar();
|
NextChar();
|
||||||
_currentToken = Token.ParentesisStart;
|
_currentToken = Token.ParenthesisStart;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ')':
|
case ')':
|
||||||
NextChar();
|
NextChar();
|
||||||
_currentToken = Token.ParentesisEnd;
|
_currentToken = Token.ParenthesisEnd;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="ExpressionDivisionNode.cs" />
|
||||||
|
<Compile Include="ExpressionMultiplyNode.cs" />
|
||||||
<Compile Include="ExpressionUnaryNode.cs" />
|
<Compile Include="ExpressionUnaryNode.cs" />
|
||||||
<Compile Include="ExpressionBinaryNode.cs" />
|
<Compile Include="ExpressionBinaryNode.cs" />
|
||||||
<Compile Include="ExpressionMinusNode.cs" />
|
<Compile Include="ExpressionMinusNode.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user