feat: 语法树的访问者和类型检测访问者 (#56)

Reviewed-on: PostGuard/Canon#56
This commit is contained in:
2024-04-26 10:18:49 +08:00
parent b20c3234c5
commit 17dbcccb59
63 changed files with 2757 additions and 704 deletions

View File

@@ -5,9 +5,9 @@ namespace Canon.Generator.Extensions;
public static class RootCommandExtension
{
public static void AddGenerateCommand(this RootCommand rootCommand)
public static void AddGrammarCommand(this RootCommand rootCommand)
{
Command generateCommand = new("generate", "Generate source files.");
Command generateCommand = new("grammar", "Generate grammar parser source files.");
Argument<string> filenameArgument = new(name: "filename",
description: "determines the generated file name.",
@@ -37,4 +37,16 @@ public static class RootCommandExtension
rootCommand.AddCommand(generateCommand);
}
public static void AddSyntaxVisitorCommand(this RootCommand rootCommand)
{
Command syntaxCommand = new("syntax", "Generate syntax visitor source code.");
syntaxCommand.SetHandler(async () =>
{
await SyntaxVisitorGenerator.SyntaxVisitorGenerator.Generate();
});
rootCommand.AddCommand(syntaxCommand);
}
}

View File

@@ -3,6 +3,7 @@ using Canon.Generator.Extensions;
RootCommand rootCommand = new("Canon Compiler Source Generator");
rootCommand.AddGenerateCommand();
rootCommand.AddGrammarCommand();
rootCommand.AddSyntaxVisitorCommand();
await rootCommand.InvokeAsync(args);

View File

@@ -0,0 +1,78 @@
using System.Text;
namespace Canon.Generator.SyntaxVisitorGenerator;
public static class SyntaxVisitorGenerator
{
private static readonly List<string> s_nodes =
[
"AddOperator",
"BasicType",
"CompoundStatement",
"ConstDeclaration",
"ConstDeclarations",
"ConstValue",
"ElsePart",
"Expression",
"ExpressionList",
"Factor",
"FormalParameter",
"IdentifierList",
"IdentifierVarPart",
"MultiplyOperator",
"Parameter",
"ParameterList",
"Period",
"ProcedureCall",
"ProgramBody",
"ProgramHead",
"ProgramStruct",
"RelationOperator",
"SimpleExpression",
"Statement",
"StatementList",
"Subprogram",
"SubprogramBody",
"SubprogramDeclarations",
"SubprogramHead",
"Term",
"TypeSyntaxNode",
"ValueParameter",
"VarDeclaration",
"VarDeclarations",
"Variable",
"VarParameter"
];
public static async Task Generate()
{
FileInfo output = new(Path.Combine(Environment.CurrentDirectory, "SyntaxNodeVisitor.cs"));
StringBuilder builder = new();
builder.Append("using Canon.Core.SyntaxNodes;\n").Append('\n');
builder.Append("namespace Canon.Core.Abstractions;\n").Append('\n');
builder.Append("public abstract class SyntaxNodeVisitor\n").Append("{\n");
foreach (string node in s_nodes)
{
string nodeName = node.Substring(0, 1).ToLower() + node.Substring(1);
builder.Append($" public virtual void PreVisit({node} {nodeName})\n")
.Append(" {\n")
.Append(" }\n")
.Append('\n');
builder.Append($" public virtual void PostVisit({node} {nodeName})\n")
.Append(" {\n")
.Append(" }\n")
.Append('\n');
}
builder.Append('}');
await using StreamWriter writer = output.CreateText();
await writer.WriteAsync(builder.ToString());
}
}