Parser: Plus and Minus with numbers.
This commit is contained in:
40
VAR.ExpressionEvaluator.Tests/ParserTests.cs
Normal file
40
VAR.ExpressionEvaluator.Tests/ParserTests.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace VAR.ExpressionEvaluator.Tests
|
||||||
|
{
|
||||||
|
[TestClass()]
|
||||||
|
public class ParserTests
|
||||||
|
{
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__Ten_EqualsTen()
|
||||||
|
{
|
||||||
|
string expression = "10";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(10m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__OnePlusTwo_EqualsThree()
|
||||||
|
{
|
||||||
|
string expression = "1 + 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(3m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__OneMinusTwo_EqualsMinusOne()
|
||||||
|
{
|
||||||
|
string expression = "1 - 2";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(-1m, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod()]
|
||||||
|
public void ParseString__OneMillionMinusHundredThousands_EqualsNineHundredThousands()
|
||||||
|
{
|
||||||
|
string expression = "1000000 - 100000";
|
||||||
|
object result = Parser.EvaluateString(expression);
|
||||||
|
Assert.AreEqual(900000m, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
<Compile Include="ExpressionBinaryNodeTests.cs" />
|
<Compile Include="ExpressionBinaryNodeTests.cs" />
|
||||||
<Compile Include="ExpressionNumberNodeTests.cs" />
|
<Compile Include="ExpressionNumberNodeTests.cs" />
|
||||||
<Compile Include="ExpressionStringNodeTests.cs" />
|
<Compile Include="ExpressionStringNodeTests.cs" />
|
||||||
|
<Compile Include="ParserTests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="TokenizerTests.cs" />
|
<Compile Include="TokenizerTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
15
VAR.ExpressionEvaluator/ExpressionMinusNode.cs
Normal file
15
VAR.ExpressionEvaluator/ExpressionMinusNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace VAR.ExpressionEvaluator
|
||||||
|
{
|
||||||
|
public class ExpressionMinusNode : ExpressionBinaryNode
|
||||||
|
{
|
||||||
|
public ExpressionMinusNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||||
|
base(leftNode, rightNode, MinusOp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object MinusOp(object leftValue, object rightValue)
|
||||||
|
{
|
||||||
|
return (decimal)leftValue - (decimal)rightValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
VAR.ExpressionEvaluator/ExpressionPlusNode.cs
Normal file
15
VAR.ExpressionEvaluator/ExpressionPlusNode.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
namespace VAR.ExpressionEvaluator
|
||||||
|
{
|
||||||
|
public class ExpressionPlusNode : ExpressionBinaryNode
|
||||||
|
{
|
||||||
|
public ExpressionPlusNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||||
|
base(leftNode, rightNode, PlusOp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static object PlusOp(object leftValue, object rightValue)
|
||||||
|
{
|
||||||
|
return (decimal)leftValue + (decimal)rightValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
77
VAR.ExpressionEvaluator/Parser.cs
Normal file
77
VAR.ExpressionEvaluator/Parser.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace VAR.ExpressionEvaluator
|
||||||
|
{
|
||||||
|
public class Parser
|
||||||
|
{
|
||||||
|
private ITokenizer _tokenizer;
|
||||||
|
|
||||||
|
public Parser(ITokenizer tokenizer)
|
||||||
|
{
|
||||||
|
_tokenizer = tokenizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IExpressionNode ParseExpression()
|
||||||
|
{
|
||||||
|
var expr = ParsePlusAndMinus();
|
||||||
|
|
||||||
|
if (_tokenizer.Token != Token.EOF)
|
||||||
|
{
|
||||||
|
throw new Exception("Unexpected characters at end of expression");
|
||||||
|
}
|
||||||
|
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IExpressionNode ParsePlusAndMinus()
|
||||||
|
{
|
||||||
|
IExpressionNode leftNode = ParseTerminus();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (_tokenizer.Token == Token.Plus)
|
||||||
|
{
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
IExpressionNode rightNode = ParseTerminus();
|
||||||
|
leftNode = new ExpressionPlusNode(leftNode, rightNode);
|
||||||
|
}
|
||||||
|
else if (_tokenizer.Token == Token.Minus)
|
||||||
|
{
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
IExpressionNode rightNode = ParseTerminus();
|
||||||
|
leftNode = new ExpressionMinusNode(leftNode, rightNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return leftNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IExpressionNode ParseTerminus()
|
||||||
|
{
|
||||||
|
if (_tokenizer.Token == Token.Number)
|
||||||
|
{
|
||||||
|
var node = new ExpressionNumberNode(_tokenizer.Number ?? 0m);
|
||||||
|
_tokenizer.NextToken();
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception(string.Format("Unexpected token: {0}", _tokenizer.Token.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IExpressionNode ParseString(string str)
|
||||||
|
{
|
||||||
|
TextReader textReader = new StringReader(str);
|
||||||
|
ITokenizer tokenizer = new Tokenizer(textReader);
|
||||||
|
Parser parser = new Parser(tokenizer);
|
||||||
|
return parser.ParseExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static object EvaluateString(string str)
|
||||||
|
{
|
||||||
|
IExpressionNode node = ParseString(str);
|
||||||
|
return node.Eval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,10 +42,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ExpressionBinaryNode.cs" />
|
<Compile Include="ExpressionBinaryNode.cs" />
|
||||||
|
<Compile Include="ExpressionMinusNode.cs" />
|
||||||
|
<Compile Include="ExpressionPlusNode.cs" />
|
||||||
<Compile Include="ExpressionStringNode.cs" />
|
<Compile Include="ExpressionStringNode.cs" />
|
||||||
<Compile Include="ExpressionNumberNode.cs" />
|
<Compile Include="ExpressionNumberNode.cs" />
|
||||||
<Compile Include="IExpressionNode.cs" />
|
<Compile Include="IExpressionNode.cs" />
|
||||||
<Compile Include="ITokenizer.cs" />
|
<Compile Include="ITokenizer.cs" />
|
||||||
|
<Compile Include="Parser.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Token.cs" />
|
<Compile Include="Token.cs" />
|
||||||
<Compile Include="Tokenizer.cs" />
|
<Compile Include="Tokenizer.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user