gpt4 book ai didi

c# - 有没有办法在 C# 中实现自定义语言功能?

转载 作者:IT王子 更新时间:2023-10-29 03:55:32 37 4
gpt4 key购买 nike

我已经对这个问题感到困惑了一段时间,我环顾四周,找不到关于这个主题的任何讨论。

假设我想实现一个简单的例子,比如一个新的循环结构:do..until

写的很像do..while

do {
//Things happen here
} until (i == 15)

这样做可以将其转换为有效的 csharp:

do {
//Things happen here
} while (!(i == 15))

这显然是一个简单的例子,但是有什么办法可以添加这种性质的东西吗?理想情况下作为 Visual Studio 扩展来启用语法突出显示等。

最佳答案

Microsoft 提议将 Rolsyn API 作为具有公共(public) API 的 C# 编译器的实现。它包含用于每个编译器管道阶段的单独 API:语法分析、符号创建、绑定(bind)、MSIL 发射。您可以提供自己的语法分析器实现或扩展现有语法分析器,以获得具有您想要的任何功能的 C# 编译器。

Roslyn CTP

让我们使用 Roslyn 扩展 C# 语言吧!在我的示例中,我正在用相应的 do-while 替换 do-until 语句:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Roslyn.Compilers.CSharp;

namespace RoslynTest
{

class Program
{
static void Main(string[] args)
{

var code = @"

using System;

class Program {
public void My() {
var i = 5;
do {
Console.WriteLine(""hello world"");
i++;
}
until (i > 10);
}
}
";



//Parsing input code into a SynaxTree object.
var syntaxTree = SyntaxTree.ParseCompilationUnit(code);

var syntaxRoot = syntaxTree.GetRoot();

//Here we will keep all nodes to replace
var replaceDictionary = new Dictionary<DoStatementSyntax, DoStatementSyntax>();

//Looking for do-until statements in all descendant nodes
foreach (var doStatement in syntaxRoot.DescendantNodes().OfType<DoStatementSyntax>())
{
//Until token is treated as an identifier by C# compiler. It doesn't know that in our case it is a keyword.
var untilNode = doStatement.Condition.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault((_node =>
{
return _node.Identifier.ValueText == "until";
}));

//Condition is treated as an argument list
var conditionNode = doStatement.Condition.ChildNodes().OfType<ArgumentListSyntax>().FirstOrDefault();

if (untilNode != null && conditionNode != null)
{

//Let's replace identifier w/ correct while keyword and condition

var whileNode = Syntax.ParseToken("while");

var condition = Syntax.ParseExpression("(!" + conditionNode.GetFullText() + ")");

var newDoStatement = doStatement.WithWhileKeyword(whileNode).WithCondition(condition);

//Accumulating all replacements
replaceDictionary.Add(doStatement, newDoStatement);

}

}

syntaxRoot = syntaxRoot.ReplaceNodes(replaceDictionary.Keys, (node1, node2) => replaceDictionary[node1]);

//Output preprocessed code
Console.WriteLine(syntaxRoot.GetFullText());

}
}
}
///////////
//OUTPUT://
///////////
// using System;

// class Program {
// public void My() {
// var i = 5;
// do {
// Console.WriteLine("hello world");
// i++;
// }
//while(!(i > 10));
// }
// }

现在我们可以使用 Roslyn API 编译更新的语法树或将 syntaxRoot.GetFullText() 保存到文本文件并将其传递给 csc.exe。

关于c# - 有没有办法在 C# 中实现自定义语言功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11749222/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com