diff --git a/Canon.Core/Enums/SemanticEnums.cs b/Canon.Core/Enums/SemanticEnums.cs index b4c0427..270c329 100644 --- a/Canon.Core/Enums/SemanticEnums.cs +++ b/Canon.Core/Enums/SemanticEnums.cs @@ -19,7 +19,9 @@ public enum DelimiterType LeftParenthesis, RightParenthesis, LeftSquareBracket, - RightSquareBracket + RightSquareBracket, + SingleQuotation, + DoubleQuotation } public enum KeywordType @@ -40,3 +42,21 @@ public enum KeywordType To, Do, } + +public enum OperatorType +{ + Equal, + NotEqual, + Less, + LessEqual, + Greater, + GreaterEqual, + Plus, + Minus, + Multiply, + Divide, + Mod, + And, + Or, + Assign +} diff --git a/Canon.Core/GrammarParser/Terminator.cs b/Canon.Core/GrammarParser/Terminator.cs index 0ff1257..7bd9216 100644 --- a/Canon.Core/GrammarParser/Terminator.cs +++ b/Canon.Core/GrammarParser/Terminator.cs @@ -8,38 +8,68 @@ public abstract class TerminatorBase } /// -/// A terminator in grammar and it always represents a semantic token. +/// 语法中的一个终结符 +/// 终结符标识词法分析中得到的一个记号 /// public class Terminator : TerminatorBase, IEquatable { public override bool IsTerminated => true; - private readonly bool _isKeyword; + private readonly SemanticTokenType _terminatorType; private readonly KeywordType _keywordType; private readonly DelimiterType _delimiterType; + private readonly OperatorType _operatorType; public Terminator(KeywordType keywordType) { - _isKeyword = true; + _terminatorType = SemanticTokenType.Keyword; _keywordType = keywordType; } public Terminator(DelimiterType delimiterType) { - _isKeyword = false; + _terminatorType = SemanticTokenType.Delimiter; _delimiterType = delimiterType; } + public Terminator(OperatorType operatorType) + { + _terminatorType = SemanticTokenType.Operator; + _operatorType = operatorType; + } + + private Terminator(SemanticTokenType type) + { + _terminatorType = type; + } + + /// + /// 标识符终结符单例 + /// 鉴于在语法中不关心标识符具体内容,因此可以使用单例对象 + /// + public static Terminator IdentifierTerminator => new(SemanticTokenType.Identifier); + + /// + /// 字符终结符单例 + /// 鉴于在语法中不关心具体字符,因此可以使用单例对象 + /// + public static Terminator CharacterTerminator => new(SemanticTokenType.Character); + public override int GetHashCode() { - if (_isKeyword) + int hash = _terminatorType.GetHashCode(); + + switch (_terminatorType) { - return _keywordType.GetHashCode(); - } - else - { - return _delimiterType.GetHashCode(); + case SemanticTokenType.Keyword: + return hash ^ _keywordType.GetHashCode(); + case SemanticTokenType.Delimiter: + return hash ^ _delimiterType.GetHashCode(); + case SemanticTokenType.Operator: + return hash ^ _operatorType.GetHashCode(); + default: + return hash; } } @@ -50,18 +80,21 @@ public class Terminator : TerminatorBase, IEquatable return false; } - if (_isKeyword != other._isKeyword) + if (_terminatorType != other._terminatorType) { return false; } - if (_isKeyword) + switch (_terminatorType) { - return _keywordType == other._keywordType; - } - else - { - return _delimiterType == other._delimiterType; + case SemanticTokenType.Keyword: + return _keywordType == other._keywordType; + case SemanticTokenType.Delimiter: + return _delimiterType == other._delimiterType; + case SemanticTokenType.Operator: + return _operatorType == other._operatorType; + default: + return true; } } @@ -87,7 +120,7 @@ public class Terminator : TerminatorBase, IEquatable } /// -/// A non-terminator in grammar like the 'ProgramStruct'. +/// 语法中的非终结符 /// public class NonTerminator : TerminatorBase, IEquatable { diff --git a/Canon.Core/LexicalParser/SemanticToken.cs b/Canon.Core/LexicalParser/SemanticToken.cs index ae49933..66a57ea 100644 --- a/Canon.Core/LexicalParser/SemanticToken.cs +++ b/Canon.Core/LexicalParser/SemanticToken.cs @@ -2,28 +2,47 @@ 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) + 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; @@ -42,7 +61,9 @@ public class DelimiterSemanticToken : SemanticToken { '(', DelimiterType.LeftParenthesis }, { ')', DelimiterType.RightParenthesis }, { '[', DelimiterType.LeftSquareBracket }, - { ']', DelimiterType.RightSquareBracket } + { ']', DelimiterType.RightSquareBracket }, + { '\'', DelimiterType.SingleQuotation }, + { '\"', DelimiterType.DoubleQuotation } }; if (!delimiterMap.TryGetValue(now.Value, out DelimiterType value)) @@ -62,6 +83,9 @@ public class DelimiterSemanticToken : SemanticToken } } +/// +/// 关键字类型记号 +/// public class KeywordSemanticToken : SemanticToken { public override SemanticTokenType TokenType => SemanticTokenType.Keyword; @@ -75,7 +99,7 @@ public class KeywordSemanticToken : SemanticToken if (now.Next is null) { - // As there is now keyword shorter than 2 characters. + // 没有比两个字符更短的关键字 token = null; return false; } @@ -119,10 +143,15 @@ public class KeywordSemanticToken : SemanticToken } } +/// +/// 操作数类型记号 +/// public class OperatorSemanticToken : SemanticToken { public override SemanticTokenType TokenType => SemanticTokenType.Operator; + public required OperatorType OperatorType { get; init; } + public static bool TryParse(uint linePos, uint characterPos, LinkedListNode now, out OperatorSemanticToken? token) { @@ -131,6 +160,9 @@ public class OperatorSemanticToken : SemanticToken } } +/// +/// 数值类型记号 +/// public class NumberSemanticToken : SemanticToken { public override SemanticTokenType TokenType => SemanticTokenType.Number; @@ -143,6 +175,9 @@ public class NumberSemanticToken : SemanticToken } } +/// +/// 标识符类型记号 +/// public class IdentifierSemanticToken : SemanticToken { public override SemanticTokenType TokenType => SemanticTokenType.Identifier;