CanonSharp/CanonSharp.Tests/ParserTests/ExpressionParserTests.cs
jackfiled cf19f8197e feat: Grammar Parser (#3)
Reviewed-on: https://git.bupt-hpc.cn/jackfiled/CanonSharp/pulls/3
Co-authored-by: jackfiled <xcrenchangjun@outlook.com>
Co-committed-by: jackfiled <xcrenchangjun@outlook.com>
2024-08-18 12:01:27 +08:00

298 lines
13 KiB
C#

using CanonSharp.Pascal.Parser;
using CanonSharp.Pascal.SyntaxTree;
using CanonSharp.Tests.Utils;
namespace CanonSharp.Tests.ParserTests;
public sealed class ExpressionParserTests : GrammarParserTestBase
{
[Fact]
public void BoolTest()
{
BooleanValueNode node = RunParser<BooleanValueNode>(GrammarParser.FactorParser(), "false");
Assert.False(node.Value);
node = RunParser<BooleanValueNode>(GrammarParser.FactorParser(), "true");
Assert.True(node.Value);
}
[Fact]
public void NumberTest()
{
IntegerValueNode integerValueNode = RunParser<IntegerValueNode>(GrammarParser.FactorParser(), "123456");
Assert.Equal(123456, integerValueNode.Value);
FloatValueNode floatValueNode = RunParser<FloatValueNode>(GrammarParser.FactorParser(), "123.456");
Assert.Equal(123.456, floatValueNode.Value);
}
[Fact]
public void UnaryOperatorTest()
{
UnaryOperatorNode node = RunParser<UnaryOperatorNode>(GrammarParser.FactorParser(), "- 123");
Assert.Equal(UnaryOperatorType.Minus, node.OperatorType);
Assert.Equal(123, node.Node.Convert<IntegerValueNode>().Value);
node = RunParser<UnaryOperatorNode>(GrammarParser.FactorParser(), "+ 100.5");
Assert.Equal(UnaryOperatorType.Plus, node.OperatorType);
Assert.Equal(100.5, node.Node.Convert<FloatValueNode>().Value);
}
[Fact]
public void IdentifierTest()
{
VariableNode node = RunParser<VariableNode>(GrammarParser.VariableParser(), "temp");
Assert.Equal("temp", node.Identifier.LiteralValue);
}
[Fact]
public void ArrayIdentifierTest()
{
VariableNode node = RunParser<VariableNode>(GrammarParser.VariableParser(), "a[0]");
Assert.Equal("a", node.Identifier.LiteralValue);
Assert.Single(node.Indexers);
Assert.Equal(0, node.Indexers.First().Convert<IntegerValueNode>().Value);
node = RunParser<VariableNode>(GrammarParser.VariableParser(), "a[i + 1]");
Assert.Equal("a", node.Identifier.LiteralValue);
Assert.Single(node.Indexers);
BinaryOperatorNode binaryOperatorNode = node.Indexers.First().Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Add, binaryOperatorNode.OperatorType);
Assert.Equal("i", binaryOperatorNode.Left.Convert<VariableNode>().Identifier.LiteralValue);
Assert.Equal(1, binaryOperatorNode.Right.Convert<IntegerValueNode>().Value);
node = RunParser<VariableNode>(GrammarParser.VariableParser(), "a[b[i + 1] - 10, c]");
Assert.Equal("a", node.Identifier.LiteralValue);
Assert.Equal(2, node.Indexers.Count);
VariableNode secondNode = node.Indexers[1].Convert<VariableNode>();
Assert.Equal("c", secondNode.Identifier.LiteralValue);
Assert.Empty(secondNode.Indexers);
BinaryOperatorNode firstNode = node.Indexers[0].Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Subtract, firstNode.OperatorType);
Assert.Equal(10, firstNode.Right.Convert<IntegerValueNode>().Value);
VariableNode variableNode = firstNode.Left.Convert<VariableNode>();
Assert.Equal("b", variableNode.Identifier.LiteralValue);
Assert.Single(variableNode.Indexers);
binaryOperatorNode = variableNode.Indexers[0].Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Add, binaryOperatorNode.OperatorType);
Assert.Equal("i", binaryOperatorNode.Left.Convert<VariableNode>().Identifier.LiteralValue);
Assert.Equal(1, binaryOperatorNode.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void ProcedureCallTest()
{
ProcedureCallNode node = RunParser<ProcedureCallNode>(GrammarParser.FactorParser(), "test(1)");
Assert.Equal("test", node.Identifier.LiteralValue);
Assert.Single(node.Parameters);
Assert.Equal(1, node.Parameters[0].Convert<IntegerValueNode>().Value);
node = RunParser<ProcedureCallNode>(GrammarParser.FactorParser(), "test()");
Assert.Equal("test", node.Identifier.LiteralValue);
Assert.Empty(node.Parameters);
VariableNode variableNode = RunParser<VariableNode>(GrammarParser.FactorParser(), "test");
Assert.Equal("test", variableNode.Identifier.LiteralValue);
Assert.Empty(variableNode.Indexers);
}
[Fact]
public void SingleTermTest()
{
VariableNode node = RunParser<VariableNode>(GrammarParser.TermParser(), "temp");
Assert.Equal("temp", node.Identifier.LiteralValue);
UnaryOperatorNode unaryOperatorNode = RunParser<UnaryOperatorNode>(GrammarParser.TermParser(), "- 123");
Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType);
Assert.Equal(123, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
unaryOperatorNode = RunParser<UnaryOperatorNode>(GrammarParser.TermParser(), "+ 100.5");
Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType);
Assert.Equal(100.5, unaryOperatorNode.Node.Convert<FloatValueNode>().Value);
}
[Fact]
public void MultiplyTermTest1()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.TermParser(), "10 / 2");
Assert.Equal(BinaryOperatorType.Divide, node.OperatorType);
Assert.Equal(10, node.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(2, node.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void MultiplyTermTest2()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.TermParser(), "10 div 2");
Assert.Equal(BinaryOperatorType.IntegerDivide, node.OperatorType);
Assert.Equal(10, node.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(2, node.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void MultiplyTermTest3()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.TermParser(), "temp * 2 div 3");
Assert.Equal(BinaryOperatorType.IntegerDivide, node.OperatorType);
Assert.Equal(3, node.Right.Convert<IntegerValueNode>().Value);
BinaryOperatorNode leftNode = node.Left.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Multiply, leftNode.OperatorType);
Assert.Equal("temp", leftNode.Left.Convert<VariableNode>().Identifier.LiteralValue);
Assert.Equal(2, leftNode.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void SimpleExpressionTest1()
{
VariableNode node = RunParser<VariableNode>(GrammarParser.SimpleExpressionParser(), "temp");
Assert.Equal("temp", node.Identifier.LiteralValue);
UnaryOperatorNode unaryOperatorNode =
RunParser<UnaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "- 123");
Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType);
Assert.Equal(123, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
unaryOperatorNode = RunParser<UnaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "+ 100.5");
Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType);
Assert.Equal(100.5, unaryOperatorNode.Node.Convert<FloatValueNode>().Value);
}
[Fact]
public void SimpleExpressionTest2()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "1 + 1");
Assert.Equal(BinaryOperatorType.Add, node.OperatorType);
Assert.Equal(1, node.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(1, node.Right.Convert<IntegerValueNode>().Value);
node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "1 + 1 - 2");
Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType);
Assert.Equal(2, node.Right.Convert<IntegerValueNode>().Value);
BinaryOperatorNode leftNode = node.Left.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Add, leftNode.OperatorType);
Assert.Equal(1, leftNode.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(1, leftNode.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void SimpleExpressionTest3()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "1 - 2 * 5");
Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType);
Assert.Equal(1, node.Left.Convert<IntegerValueNode>().Value);
BinaryOperatorNode rightNode = node.Right.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Multiply, rightNode.OperatorType);
Assert.Equal(2, rightNode.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(5, rightNode.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void SimpleExpressionTest4()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "1 + +1");
Assert.Equal(BinaryOperatorType.Add, node.OperatorType);
Assert.Equal(1, node.Left.Convert<IntegerValueNode>().Value);
UnaryOperatorNode unaryOperatorNode = node.Right.Convert<UnaryOperatorNode>();
Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType);
Assert.Equal(1, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "1 - -1");
Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType);
Assert.Equal(1, node.Left.Convert<IntegerValueNode>().Value);
unaryOperatorNode = node.Right.Convert<UnaryOperatorNode>();
Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType);
Assert.Equal(1, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(), "+ 1 - - 1");
Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType);
unaryOperatorNode = node.Left.Convert<UnaryOperatorNode>();
Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType);
Assert.Equal(1, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
unaryOperatorNode = node.Right.Convert<UnaryOperatorNode>();
Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType);
Assert.Equal(1, unaryOperatorNode.Node.Convert<IntegerValueNode>().Value);
}
[Fact]
public void SimpleExpressionTest5()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.SimpleExpressionParser(),
"true and temp or temp and false");
Assert.Equal(BinaryOperatorType.Or, node.OperatorType);
BinaryOperatorNode left = node.Left.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.And, left.OperatorType);
BinaryOperatorNode right = node.Right.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.And, right.OperatorType);
}
[Fact]
public void ExpressionTest1()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.ExpressionParser(),
"true and temp or temp and false");
Assert.Equal(BinaryOperatorType.Or, node.OperatorType);
BinaryOperatorNode left = node.Left.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.And, left.OperatorType);
BinaryOperatorNode right = node.Right.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.And, right.OperatorType);
}
[Fact]
public void ExpressionTest2()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.ExpressionParser(), "2 >= 1");
Assert.Equal(BinaryOperatorType.GreaterEqual, node.OperatorType);
Assert.Equal(2, node.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(1, node.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void ExpressionTest3()
{
BinaryOperatorNode node = RunParser<BinaryOperatorNode>(GrammarParser.ExpressionParser(), "(1 + 1) * 2");
Assert.Equal(BinaryOperatorType.Multiply, node.OperatorType);
Assert.Equal(2, node.Right.Convert<IntegerValueNode>().Value);
node = node.Left.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Add, node.OperatorType);
Assert.Equal(1, node.Left.Convert<IntegerValueNode>().Value);
Assert.Equal(1, node.Right.Convert<IntegerValueNode>().Value);
}
[Fact]
public void ExpressionsTest1()
{
List<BinaryOperatorNode> nodes =
RunParser<BinaryOperatorNode>(GrammarParser.ExpressionsParser(), "1 + 1, 2 * 3");
Assert.Equal(BinaryOperatorType.Add, nodes[0].OperatorType);
Assert.Equal(BinaryOperatorType.Multiply, nodes[1].OperatorType);
}
[Fact]
public void VariableTest1()
{
VariableNode node = RunParser<VariableNode>(GrammarParser.VariableParser(), "temp");
Assert.Equal("temp", node.Identifier.LiteralValue);
}
}