CanonSharp/CanonSharp.Tests/ScannerTest/LexicalTokenParserTest.cs
jackfiled 3ed8bf5d36
All checks were successful
Run unit test / Unit-Test (push) Successful in 41s
feat: Parser Combinator库和词法分析器 (#2)
Reviewed-on: https://git.bupt-hpc.cn/jackfiled/CanonSharp/pulls/2
Co-authored-by: jackfiled <xcrenchangjun@outlook.com>
Co-committed-by: jackfiled <xcrenchangjun@outlook.com>
2024-08-13 14:46:11 +08:00

178 lines
5.4 KiB
C#

using CanonSharp.Combinator;
using CanonSharp.Combinator.Abstractions;
using CanonSharp.Combinator.Extensions;
using CanonSharp.Common.Scanner;
using CanonSharp.Tests.Utils;
namespace CanonSharp.Tests.ScannerTest;
public class LexicalTokenParserTest : LexicalTestBase
{
[Theory]
[InlineData("program")]
[InlineData("const")]
[InlineData("var")]
[InlineData("procedure")]
[InlineData("function")]
[InlineData("begin")]
[InlineData("end")]
[InlineData("array")]
[InlineData("of")]
[InlineData("if")]
[InlineData("then")]
[InlineData("else")]
[InlineData("for")]
[InlineData("to")]
[InlineData("do")]
[InlineData("true")]
[InlineData("false")]
[InlineData("while")]
public void KeywordParserTest(string literalValue)
{
Parser<char, LexicalToken> keyword = LexicalScanner.KeywordParser();
ValidateSuccessfulParser(keyword, LexicalTokenType.Keyword, literalValue, literalValue);
}
[Theory]
[InlineData("andOne")]
[InlineData("program1")]
[InlineData("todo")]
public void FailedKeywordParserTest(string input)
{
Parser<char, LexicalToken> keyword = LexicalScanner.KeywordParser();
ValidateFailedParser(keyword, input);
}
[Theory]
[InlineData(",")]
[InlineData(".")]
[InlineData(";")]
[InlineData(":")]
[InlineData("(")]
[InlineData(")")]
[InlineData("[")]
[InlineData("]")]
[InlineData("..")]
public void DelimiterParserTest(string literalValue)
{
Parser<char, LexicalToken> delimiter = LexicalScanner.DelimiterParser();
ValidateSuccessfulParser(delimiter, LexicalTokenType.Delimiter, literalValue, literalValue);
}
[Theory]
[InlineData(":=")]
public void FailedDelimiterParserTest(string input)
{
Parser<char, LexicalToken> delimiter = LexicalScanner.DelimiterParser();
ValidateFailedParser(delimiter, input);
}
[Theory]
[InlineData("=")]
[InlineData("!=")]
[InlineData(">")]
[InlineData(">=")]
[InlineData("<")]
[InlineData("<=")]
[InlineData("+")]
[InlineData("-")]
[InlineData("*")]
[InlineData("/")]
[InlineData(":=")]
public void OperatorParserTest(string literalValue)
{
Parser<char, LexicalToken> operatorParser = LexicalScanner.OperatorParser();
ValidateSuccessfulParser(operatorParser, LexicalTokenType.Operator, literalValue, literalValue);
}
[Theory]
[InlineData("identifier")]
[InlineData("_identifier")]
[InlineData("identifier123")]
[InlineData("identifier_with_underscore")]
[InlineData("CamelCase")]
[InlineData("andand")]
public void IdentifierParserTest(string literalValue)
{
Parser<char, LexicalToken> identifier = LexicalScanner.IdentifierParser();
ValidateSuccessfulParser(identifier, LexicalTokenType.Identifier, literalValue, literalValue);
}
[Theory]
[InlineData(123, "123")]
[InlineData(0, "0")]
public void ConstIntegerTest(int value, string input)
{
StringReadState state = new(input);
ParseResult<char, LexicalToken> result = LexicalScanner.ConstIntegerParser().Parse(state);
Assert.Equal(LexicalTokenType.ConstInteger, result.Value.TokenType);
Assert.Equal(value, int.Parse(result.Value.LiteralValue));
}
[Theory]
[InlineData(123.456, "123.456")]
[InlineData(0, "0.0")]
public void ConstFloatTest(double value, string input)
{
StringReadState state = new(input);
ParseResult<char, LexicalToken> result = LexicalScanner.ConstFloatParser().Parse(state);
Assert.Equal(LexicalTokenType.ConstFloat, result.Value.TokenType);
Assert.Equal(value, double.Parse(result.Value.LiteralValue));
}
[Theory]
[InlineData('a', "'a'")]
[InlineData('Z', "'Z'")]
public void CharTest(char value, string input)
{
StringReadState state = new(input);
ParseResult<char, LexicalToken> result = LexicalScanner.CharParser().Parse(state);
Assert.Equal(LexicalTokenType.Character, result.Value.TokenType);
Assert.Equal(value, char.Parse(result.Value.LiteralValue));
}
[Theory]
[InlineData("hello, world!", "'hello, world!'")]
public void StringTest(string value, string input)
{
StringReadState state = new(input);
ParseResult<char, LexicalToken> result = LexicalScanner.CharParser().Parse(state);
Assert.Equal(LexicalTokenType.String, result.Value.TokenType);
Assert.Equal(value, result.Value.LiteralValue);
}
[Theory]
[InlineData("{comment}")]
[InlineData("{}")]
public void CommentTest(string input)
{
StringReadState state = new(input);
ParseResult<char, Unit> result = LexicalScanner.CommentParser().Parse(state);
Assert.Equal(Unit.Instance, result.Value);
}
[Theory]
[InlineData(" {comment} program")]
[InlineData("""
{comment}
{comment}
{}{}{}{}
program
""")]
public void JunkTest(string input)
{
StringReadState state = new(input);
Parser<char, LexicalToken> parser = LexicalScanner.JunkParser().SkipTill(LexicalScanner.KeywordParser());
ParseResult<char, LexicalToken> result = parser.Parse(state);
Assert.Equal(LexicalTokenType.Keyword, result.Value.TokenType);
Assert.Equal("program", result.Value.LiteralValue);
}
}