refact: 将编译中各个阶段接口化 (#35)

Reviewed-on: PostGuard/Canon#35
This commit is contained in:
2024-04-12 19:01:37 +08:00
parent f1c569ee0e
commit 67deb0aa2c
15 changed files with 748 additions and 615 deletions

View File

@@ -0,0 +1,11 @@
using Canon.Core.CodeGenerators;
namespace Canon.Core.Abstractions;
/// <summary>
/// 支持生成C语言代码的接口
/// </summary>
public interface ICCodeGenerator
{
public void GenerateCCode(CCodeBuilder builder);
}

View File

@@ -8,13 +8,19 @@ namespace Canon.Core.Abstractions;
/// <summary>
/// 语法分析器接口
/// </summary>
public abstract class GrammarParserBase
public interface IGrammarParser
{
public abstract ITransformer BeginTransformer { get; }
public ITransformer BeginTransformer { get; }
public abstract NonTerminator Begin { get; }
public NonTerminator Begin { get; }
public SyntaxNodeBase Analyse(IEnumerable<SemanticToken> tokens)
/// <summary>
/// 分析指定的词法记号流并构建对应的语法树
/// </summary>
/// <param name="tokens">输入的词法记号流</param>
/// <returns>语法树的根节点</returns>
/// <exception cref="InvalidOperationException">语法分析错误</exception>
public ProgramStruct Analyse(IEnumerable<SemanticToken> tokens)
{
Stack<AnalyseState> stack = [];
stack.Push(new AnalyseState(BeginTransformer, SyntaxNodeBase.Create(SemanticToken.End)));
@@ -36,7 +42,7 @@ public abstract class GrammarParserBase
{
// 如果是归约到起始符
// 那么就直接返回不继续进行归约
return top.Node;
return top.Node.Convert<ProgramStruct>();
}
List<SyntaxNodeBase> children = [];

View File

@@ -0,0 +1,11 @@
using Canon.Core.LexicalParser;
namespace Canon.Core.Abstractions;
/// <summary>
/// 词法分析器接口
/// </summary>
public interface ILexer
{
public IEnumerable<SemanticToken> Tokenize(ISourceReader reader);
}

View File

@@ -0,0 +1,31 @@
using System.Diagnostics.CodeAnalysis;
namespace Canon.Core.Abstractions;
/// <summary>
/// 读取源代码的接口
/// </summary>
public interface ISourceReader
{
/// <summary>
/// 尝试读取下一个字符
/// </summary>
/// <param name="c">读取到的字符</param>
/// <returns>是否成功读取</returns>
public bool TryReadChar([NotNullWhen(true)] out char? c);
/// <summary>
/// 源文件名称
/// </summary>
public string FileName { get; }
/// <summary>
/// 当前读取字符的行号
/// </summary>
public uint Line { get; }
/// <summary>
/// 当前读取字符的列号
/// </summary>
public uint Pos { get; }
}