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 keyword = LexicalScanner.KeywordParser(); ValidateSuccessfulParser(keyword, LexicalTokenType.Keyword, literalValue, literalValue); } [Theory] [InlineData("andOne")] [InlineData("program1")] [InlineData("todo")] public void FailedKeywordParserTest(string input) { Parser keyword = LexicalScanner.KeywordParser(); ValidateFailedParser(keyword, input); } [Theory] [InlineData(",")] [InlineData(".")] [InlineData(";")] [InlineData(":")] [InlineData("(")] [InlineData(")")] [InlineData("[")] [InlineData("]")] [InlineData("..")] public void DelimiterParserTest(string literalValue) { Parser delimiter = LexicalScanner.DelimiterParser(); ValidateSuccessfulParser(delimiter, LexicalTokenType.Delimiter, literalValue, literalValue); } [Theory] [InlineData(":=")] public void FailedDelimiterParserTest(string input) { Parser delimiter = LexicalScanner.DelimiterParser(); ValidateFailedParser(delimiter, input); } [Theory] [InlineData("=")] [InlineData("!=")] [InlineData(">")] [InlineData(">=")] [InlineData("<")] [InlineData("<=")] [InlineData("+")] [InlineData("-")] [InlineData("*")] [InlineData("/")] [InlineData(":=")] public void OperatorParserTest(string literalValue) { Parser 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 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 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 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 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 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 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 parser = LexicalScanner.JunkParser().SkipTill(LexicalScanner.KeywordParser()); ParseResult result = parser.Parse(state); Assert.Equal(LexicalTokenType.Keyword, result.Value.TokenType); Assert.Equal("program", result.Value.LiteralValue); } }