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;