CanonSharp/CanonSharp.Tests/ParserTests/StatementParserTests.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

191 lines
7.1 KiB
C#

using CanonSharp.Pascal.Parser;
using CanonSharp.Pascal.SyntaxTree;
using CanonSharp.Tests.Utils;
namespace CanonSharp.Tests.ParserTests;
public class StatementParserTests : GrammarParserTestBase
{
[Fact]
public void StatementTest1()
{
AssignNode node = RunParser<AssignNode>(GrammarParser.StatementParser(), "temp := 1");
Assert.Equal("temp", node.Variable.Identifier.LiteralValue);
Assert.Equal(1, node.Expression.Convert<IntegerValueNode>().Value);
}
[Fact]
public void IfTest1()
{
IfNode node = RunParser<IfNode>(GrammarParser.IfParser(), """
if i = 1 then
a := a + 1
else
a := a + 2
""");
Assert.NotNull(node.ElseStatement);
BinaryOperatorNode condition = node.Condition.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Equal, condition.OperatorType);
AssignNode statement = node.Statement.Convert<AssignNode>();
Assert.Equal("a", statement.Variable.Identifier.LiteralValue);
AssignNode elseStatement = node.Statement.Convert<AssignNode>();
Assert.Equal("a", elseStatement.Variable.Identifier.LiteralValue);
}
[Fact]
public void IfTest2()
{
IfNode node = RunParser<IfNode>(GrammarParser.IfParser(), """
if i = 1 then
if i = 2 then
a := a + 1
else
a := a + 2
""");
Assert.Null(node.ElseStatement);
IfNode subIfNode = node.Statement.Convert<IfNode>();
Assert.NotNull(subIfNode.ElseStatement);
}
[Fact]
public void ForTest1()
{
ForNode node = RunParser<ForNode>(GrammarParser.ForParser(), """
for i := 1 to 10 do
a := a + i
""");
Assert.Equal("i", node.Identifier.LiteralValue);
Assert.Equal(1, node.LeftCondition.Convert<IntegerValueNode>().Value);
Assert.Equal(10, node.RightCondition.Convert<IntegerValueNode>().Value);
AssignNode assignNode = node.Statement.Convert<AssignNode>();
Assert.Equal("a", assignNode.Variable.Identifier.LiteralValue);
}
[Fact]
public void WhileTest1()
{
WhileNode node = RunParser<WhileNode>(GrammarParser.WhileParser(), """
while c >= 1 do
a := a + 1;
""");
BinaryOperatorNode binaryOperatorNode = node.Condition.Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.GreaterEqual, binaryOperatorNode.OperatorType);
AssignNode assignNode = node.Statement.Convert<AssignNode>();
Assert.Equal("a", assignNode.Variable.Identifier.LiteralValue);
}
[Fact]
public void ProcedureCallTest1()
{
ProcedureCallNode node = RunParser<ProcedureCallNode>(GrammarParser.ProcedureCallParser(), "test()");
Assert.Equal("test", node.Identifier.LiteralValue);
Assert.Empty(node.Parameters);
node = RunParser<ProcedureCallNode>(GrammarParser.ProcedureCallParser(), "test");
Assert.Equal("test", node.Identifier.LiteralValue);
Assert.Empty(node.Parameters);
}
[Fact]
public void ProcedureCallTest2()
{
ProcedureCallNode node = RunParser<ProcedureCallNode>(GrammarParser.ProcedureCallParser(),
"test(1 + 1, true)");
Assert.Equal(2, node.Parameters.Count);
BinaryOperatorNode firstParameter = node.Parameters[0].Convert<BinaryOperatorNode>();
Assert.Equal(BinaryOperatorType.Add, firstParameter.OperatorType);
BooleanValueNode secondParameter = node.Parameters[1].Convert<BooleanValueNode>();
Assert.True(secondParameter.Value);
}
[Fact]
public void ProcedureCallTest3()
{
ProcedureCallNode node =
RunParser<ProcedureCallNode>(GrammarParser.ProcedureCallParser(), "test(1 * + 1, test2[0])");
Assert.Equal(2, node.Parameters.Count);
VariableNode secondParameter = node.Parameters[1].Convert<VariableNode>();
Assert.Equal("test2", secondParameter.Identifier.LiteralValue);
Assert.Single(secondParameter.Indexers);
}
[Theory]
[InlineData("""
begin
temp := 1 + 1;
flag := true and false;
end
""")]
[InlineData("""
begin
temp := 1 + 1;
flag := true and false
end
""")]
public void CompoundStatementTest1(string input)
{
BlockNode node = RunParser<BlockNode>(GrammarParser.CompoundStatementParser(), input);
Assert.Equal(2, node.Statements.Count);
AssignNode assignNode = node.Statements[0].Convert<AssignNode>();
Assert.Equal("temp", assignNode.Variable.Identifier.LiteralValue);
assignNode = node.Statements[1].Convert<AssignNode>();
Assert.Equal("flag", assignNode.Variable.Identifier.LiteralValue);
}
[Fact]
public void CompoundStatementTest2()
{
BlockNode node = RunParser<BlockNode>(GrammarParser.CompoundStatementParser(), "begin end");
Assert.Empty(node.Statements);
}
[Fact]
public void ProgramHeadTest1()
{
ProgramHead head = RunParser<ProgramHead>(GrammarParser.ProgramHeadParser(), "program main");
Assert.Equal("main", head.ProgramName.LiteralValue);
}
[Theory]
[InlineData("""
begin
temp := 1 + 1;
flag := true and false;
end
""")]
[InlineData("""
begin
temp := 1 + 1;
flag := true and false
end
""")]
public void ProgramBodyTest1(string input)
{
BlockNode node = RunParser<ProgramBody>(GrammarParser.ProgramBodyParser(), input).MainBlock;
Assert.Equal(2, node.Statements.Count);
AssignNode assignNode = node.Statements[0].Convert<AssignNode>();
Assert.Equal("temp", assignNode.Variable.Identifier.LiteralValue);
assignNode = node.Statements[1].Convert<AssignNode>();
Assert.Equal("flag", assignNode.Variable.Identifier.LiteralValue);
}
}