CanonSharp/CanonSharp.Tests/ScannerTests/LexicalParserTests.cs

183 lines
6.7 KiB
C#
Raw Normal View History

using CanonSharp.Pascal.Scanner;
using CanonSharp.Tests.Utils;
namespace CanonSharp.Tests.ScannerTests;
public class LexicalParserTests : LexicalTestBase
{
[Fact]
public void LexicalParserTest1()
{
const string pascalProgram = """
program HelloWorld;
var
message: char;
begin
message := 'h';
writeln(message);
end.
""";
ValidateLexicalTokens(LexicalScanner.PascalParser(), pascalProgram, [
(LexicalTokenType.Keyword, "program"),
(LexicalTokenType.Identifier, "HelloWorld"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "var"),
(LexicalTokenType.Identifier, "message"),
(LexicalTokenType.Delimiter, ":"),
(LexicalTokenType.Keyword, "char"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "begin"),
(LexicalTokenType.Identifier, "message"),
(LexicalTokenType.Operator, ":="),
(LexicalTokenType.Character, "h"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Identifier, "writeln"),
(LexicalTokenType.Delimiter, "("),
(LexicalTokenType.Identifier, "message"),
(LexicalTokenType.Delimiter, ")"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "end"),
(LexicalTokenType.Delimiter, ".")
]);
}
[Fact]
public void LexicalParserTest2()
{
const string program = """
program main;
var
ab: integer;
begin
ab := 3;
write(ab);
end.
""";
ValidateLexicalTokens(LexicalScanner.PascalParser(), program, [
(LexicalTokenType.Keyword, "program"),
(LexicalTokenType.Identifier, "main"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "var"),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Delimiter, ":"),
(LexicalTokenType.Keyword, "integer"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "begin"),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Operator, ":="),
(LexicalTokenType.ConstInteger, "3"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Identifier, "write"),
(LexicalTokenType.Delimiter, "("),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Delimiter, ")"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "end"),
(LexicalTokenType.Delimiter, ".")
]);
}
[Fact]
public void LexicalParserTest3()
{
const string pascalProgram = """
{test}
program main;
var
ab, ba: integer;
begin
ab := 3;
ba := 5;
ab := 5;
write(ab + ba);
end.
""";
ValidateLexicalTokens(LexicalScanner.PascalParser(), pascalProgram, [
(LexicalTokenType.Keyword, "program"),
(LexicalTokenType.Identifier, "main"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "var"),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Delimiter, ","),
(LexicalTokenType.Identifier, "ba"),
(LexicalTokenType.Delimiter, ":"),
(LexicalTokenType.Keyword, "integer"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "begin"),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Operator, ":="),
(LexicalTokenType.ConstInteger, "3"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Identifier, "ba"),
(LexicalTokenType.Operator, ":="),
(LexicalTokenType.ConstInteger, "5"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Operator, ":="),
(LexicalTokenType.ConstInteger, "5"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Identifier, "write"),
(LexicalTokenType.Delimiter, "("),
(LexicalTokenType.Identifier, "ab"),
(LexicalTokenType.Operator, "+"),
(LexicalTokenType.Identifier, "ba"),
(LexicalTokenType.Delimiter, ")"),
(LexicalTokenType.Delimiter, ";"),
(LexicalTokenType.Keyword, "end"),
(LexicalTokenType.Delimiter, ".")
]);
}
[Fact]
public void LexicalParserTest4()
{
ValidateLexicalTokens(LexicalScanner.PascalParser(), "array [0..9] of integer", [
(LexicalTokenType.Keyword, "array"),
(LexicalTokenType.Delimiter, "["),
(LexicalTokenType.ConstInteger, "0"),
(LexicalTokenType.Delimiter, ".."),
(LexicalTokenType.ConstInteger, "9"),
(LexicalTokenType.Delimiter, "]"),
(LexicalTokenType.Keyword, "of"),
(LexicalTokenType.Keyword, "integer")
]);
}
[Theory]
[InlineData("""
program exFunction;
var
a, b, ret : integer;
begin
a := 100;
b := 200;
{ calling a function to get max valued }
ret := a - b;
end.
""", 29)]
[InlineData("""
{
This is a block comment that does closed.
}
program CommentClosed;
""", 3)]
[InlineData("""
{}
program CommentClosed;
""", 3)]
public void LexicalParserTest(string input, int count)
{
LexicalScanner scanner = new();
List<LexicalToken> tokens = scanner.Tokenize(new StringReadState(input)).ToList();
Assert.Equal(count, tokens.Count);
}
}