From f6a4ad4a44a1a73f54d091ef97c209dbfafb2f74 Mon Sep 17 00:00:00 2001 From: jackfiled Date: Sat, 9 Mar 2024 21:16:44 +0800 Subject: [PATCH] add: SemanticToken --- Canon.Core/Enums/SemanticEnums.cs | 42 +++++++ Canon.Core/LexicalParser/SemanticToken.cs | 143 ++++++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 Canon.Core/Enums/SemanticEnums.cs create mode 100644 Canon.Core/LexicalParser/SemanticToken.cs diff --git a/Canon.Core/Enums/SemanticEnums.cs b/Canon.Core/Enums/SemanticEnums.cs new file mode 100644 index 0000000..9b3669c --- /dev/null +++ b/Canon.Core/Enums/SemanticEnums.cs @@ -0,0 +1,42 @@ +namespace Canon.Core.Enums; + +public enum SemanticTokenType +{ + Keyword, + Number, + Operator, + Delimiter, + Identifier, + Character, +} + +public enum DelimiterType +{ + Comma, + Period, + Colon, + Semicolon, + LeftParenthesis, + RightParenthesis, + LeftSquareBracket, + RightBracket +} + +public enum KeywordType +{ + Program, + Const, + Var, + Procedure, + Function, + Begin, + End, + Array, + Of, + If, + Then, + Else, + For, + To, + Do, +} diff --git a/Canon.Core/LexicalParser/SemanticToken.cs b/Canon.Core/LexicalParser/SemanticToken.cs new file mode 100644 index 0000000..ded67ec --- /dev/null +++ b/Canon.Core/LexicalParser/SemanticToken.cs @@ -0,0 +1,143 @@ +namespace Canon.Core.LexicalParser; + +using Enums; + +public abstract class SemanticToken +{ + public abstract SemanticTokenType TokenType { get; } + + public required uint LinePos { get; init; } + + public required uint CharacterPos { get; init; } + + public required string LiteralValue { get; init; } +} + +public class CharacterSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Character; + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, out CharacterSemanticToken? token) + { + token = null; + return false; + } +} + +public class DelimiterSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Delimiter; + + public required DelimiterType DelimiterType { get; init; } + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, + out DelimiterSemanticToken? token) + { + switch (now.Value) + { + case ',': + token = new DelimiterSemanticToken + { + LinePos = linePos, CharacterPos = characterPos, + LiteralValue = ",", DelimiterType = DelimiterType.Comma + }; + return true; + default: + token = null; + return false; + } + } +} + +public class KeywordSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Keyword; + + public required KeywordType KeywordType { get; init; } + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, + out KeywordSemanticToken? token) + { + string buffer = new([now.Value]); + + if (now.Next is null) + { + // As there is now keyword shorter than 2 characters. + token = null; + return false; + } + + now = now.Next; + buffer += now.Value; + + switch (buffer) + { + case "do": + token = new KeywordSemanticToken + { + LinePos = linePos, + CharacterPos = characterPos, + LiteralValue = "do", + KeywordType = KeywordType.Do + }; + return true; + case "Of": + token = new KeywordSemanticToken + { + LinePos = linePos, + CharacterPos = characterPos, + LiteralValue = "of", + KeywordType = KeywordType.Of + }; + return true; + case "If": + token = new KeywordSemanticToken + { + LinePos = linePos, + CharacterPos = characterPos, + LiteralValue = "if", + KeywordType = KeywordType.If + }; + return true; + } + + token = null; + return false; + } +} + +public class OperatorSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Operator; + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, + out OperatorSemanticToken? token) + { + token = null; + return false; + } +} + +public class NumberSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Number; + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, + out NumberSemanticToken? token) + { + token = null; + return false; + } +} + +public class IdentifierSemanticToken : SemanticToken +{ + public override SemanticTokenType TokenType => SemanticTokenType.Identifier; + + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, + out IdentifierSemanticToken? token) + { + token = null; + return false; + } +}