add: SemanticToken

This commit is contained in:
jackfiled 2024-03-09 21:16:44 +08:00
parent 01cbcac8ef
commit f6a4ad4a44
2 changed files with 185 additions and 0 deletions

View File

@ -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,
}

View File

@ -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<char> 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<char> 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<char> 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<char> 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<char> 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<char> now,
out IdentifierSemanticToken? token)
{
token = null;
return false;
}
}