Parser: Relations
This commit is contained in:
@@ -256,5 +256,73 @@ namespace VAR.ExpressionEvaluator.Tests
|
||||
|
||||
#endregion Strings
|
||||
|
||||
#region Relations
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_1GreatherThan2_EqualsFalse()
|
||||
{
|
||||
string expression = "1>2";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(false, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_1Equals1_EqualsTrue()
|
||||
{
|
||||
string expression = "1=1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(true, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_10NotEquals1_EqualsTrue()
|
||||
{
|
||||
string expression = "10!=1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(true, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_10LessThan1_EqualsFalse()
|
||||
{
|
||||
string expression = "10<1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(false, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_1GreaterOrEqualThan1_EqualsTrue()
|
||||
{
|
||||
string expression = "1>=1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(true, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_1LessOrEqualThan1_EqualsTrue()
|
||||
{
|
||||
string expression = "1<=1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(true, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_1GreaterOrEqualThan10_EqualsFalse()
|
||||
{
|
||||
string expression = "1>=10";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(false, result);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void Relations_10LessOrEqualThan1_EqualsFalse()
|
||||
{
|
||||
string expression = "10<=1";
|
||||
object result = Parser.EvaluateString(expression);
|
||||
Assert.AreEqual(false, result);
|
||||
}
|
||||
|
||||
#endregion Relations
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionEqualsNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionEqualsNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, EqualsOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object EqualsOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) == 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't compare non decimal values");
|
||||
}
|
||||
return (decimal)leftValue == (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionGreaterOrEqualThanNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionGreaterOrEqualThanNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, GreaterOrEqualThanOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object GreaterOrEqualThanOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) >= 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't compare non decimal values");
|
||||
}
|
||||
return (decimal)leftValue >= (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionGreaterThanNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionGreaterThanNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, GreaterThanOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object GreaterThanOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) > 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't compare non decimal values");
|
||||
}
|
||||
return (decimal)leftValue > (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionLessOrEqualThanNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionLessOrEqualThanNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, LessOrEqualThanOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object LessOrEqualThanOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) <= 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't substract non decimal values");
|
||||
}
|
||||
return (decimal)leftValue <= (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionLessThanNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionLessThanNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, LessThanOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object LessThanOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) < 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't compare non decimal values");
|
||||
}
|
||||
return (decimal)leftValue < (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
|
||||
namespace VAR.ExpressionEvaluator
|
||||
{
|
||||
public class ExpressionNotEqualsNode : ExpressionBinaryNode
|
||||
{
|
||||
public ExpressionNotEqualsNode(IExpressionNode leftNode, IExpressionNode rightNode) :
|
||||
base(leftNode, rightNode, NotEqualsOp)
|
||||
{
|
||||
}
|
||||
|
||||
private static object NotEqualsOp(object leftValue, object rightValue)
|
||||
{
|
||||
if (leftValue is string && rightValue is string)
|
||||
{
|
||||
return string.Compare((string)leftValue, (string)rightValue) != 0;
|
||||
}
|
||||
|
||||
if (leftValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)leftValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)leftValue));
|
||||
}
|
||||
leftValue = dec;
|
||||
}
|
||||
if (rightValue is string)
|
||||
{
|
||||
if (decimal.TryParse((string)rightValue, out decimal dec) == false)
|
||||
{
|
||||
throw new Exception(string.Format("Can't convert to decimal string value \"{0}\"", (string)rightValue));
|
||||
}
|
||||
rightValue = dec;
|
||||
}
|
||||
|
||||
if ((leftValue is decimal) == false || (rightValue is decimal) == false)
|
||||
{
|
||||
throw new Exception("Can't compare non decimal values");
|
||||
}
|
||||
return (decimal)leftValue != (decimal)rightValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace VAR.ExpressionEvaluator
|
||||
|
||||
public IExpressionNode ParseExpression()
|
||||
{
|
||||
var expr = ParsePlusAndMinus();
|
||||
var expr = ParseRelations();
|
||||
|
||||
if (_tokenizer.Token != Token.EOF)
|
||||
{
|
||||
@@ -25,7 +25,55 @@ namespace VAR.ExpressionEvaluator
|
||||
return expr;
|
||||
}
|
||||
|
||||
public IExpressionNode ParsePlusAndMinus()
|
||||
private IExpressionNode ParseRelations()
|
||||
{
|
||||
IExpressionNode leftNode = ParsePlusAndMinus();
|
||||
while (true)
|
||||
{
|
||||
if (_tokenizer.Token == Token.Equals || _tokenizer.Token == Token.ExclusiveEquals)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionEqualsNode(leftNode, rightNode);
|
||||
}
|
||||
else if (_tokenizer.Token == Token.NotEquals)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionNotEqualsNode(leftNode, rightNode);
|
||||
}
|
||||
else if (_tokenizer.Token == Token.LessThan)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionLessThanNode(leftNode, rightNode);
|
||||
}
|
||||
else if (_tokenizer.Token == Token.LessOrEqualThan)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionLessOrEqualThanNode(leftNode, rightNode);
|
||||
}
|
||||
else if (_tokenizer.Token == Token.GreaterThan)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionGreaterThanNode(leftNode, rightNode);
|
||||
}
|
||||
else if (_tokenizer.Token == Token.GreaterOrEqualThan)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode rightNode = ParsePlusAndMinus();
|
||||
leftNode = new ExpressionGreaterOrEqualThanNode(leftNode, rightNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return leftNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IExpressionNode ParsePlusAndMinus()
|
||||
{
|
||||
IExpressionNode leftNode = ParseMultiplyDivision();
|
||||
while (true)
|
||||
@@ -155,7 +203,7 @@ namespace VAR.ExpressionEvaluator
|
||||
if (_tokenizer.Token == Token.ParenthesisStart)
|
||||
{
|
||||
_tokenizer.NextToken();
|
||||
IExpressionNode node = ParsePlusAndMinus();
|
||||
IExpressionNode node = ParseRelations();
|
||||
if (_tokenizer.Token != Token.ParenthesisEnd)
|
||||
{
|
||||
throw new Exception("Missing close parenthesis");
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
Minus,
|
||||
Division,
|
||||
Multiply,
|
||||
ParenthesisStart,
|
||||
ParenthesisEnd,
|
||||
Not,
|
||||
NotEquals,
|
||||
Equals,
|
||||
ExclusiveEquals,
|
||||
GreaterThan,
|
||||
GreaterOrEqualThan,
|
||||
LessThan,
|
||||
LessOrEqualThan,
|
||||
ParenthesisStart,
|
||||
ParenthesisEnd,
|
||||
Comma,
|
||||
Identifier,
|
||||
String,
|
||||
|
||||
@@ -101,6 +101,15 @@ namespace VAR.ExpressionEvaluator
|
||||
_currentToken = Token.ParenthesisEnd;
|
||||
return;
|
||||
|
||||
case '!':
|
||||
NextChar();
|
||||
_currentToken = Token.Not;
|
||||
if (_currentChar == '=')
|
||||
{
|
||||
NextChar();
|
||||
_currentToken = Token.NotEquals;
|
||||
}
|
||||
return;
|
||||
case '=':
|
||||
NextChar();
|
||||
_currentToken = Token.Equals;
|
||||
|
||||
@@ -44,8 +44,14 @@
|
||||
<Compile Include="EvaluationContext.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionBooleanNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionDivisionNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionEqualsNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionFunctionNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionGreaterOrEqualThanNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionGreaterThanNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionLessOrEqualThanNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionLessThanNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionMultiplyNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionNotEqualsNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionUnaryNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionBinaryNode.cs" />
|
||||
<Compile Include="ExpressionNodes\ExpressionMinusNode.cs" />
|
||||
|
||||
Reference in New Issue
Block a user