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>
		
			
				
	
	
		
			298 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			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);
 | |
|     }
 | |
| }
 |