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

有没有办法在C#中实现自定义语言功能?,第1张

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

Microsoft提出将Rolsyn
API作为带有公共API的C#编译器的实现。它为每个编译器管道阶段包含单独的API:语法分析,符号创建,绑定,MSIL发出。您可以提供自己的语法解析器实现或扩展现有的语法解析器实现,以便获得具有所需功能的C#编译器。

罗斯林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 pre = @" using System; class Program {     public void My() {         var i = 5;         do {  Console.WriteLine(""hello world"");  i++;         }         until (i > 10);     } } "; //Parsing input pre into a SynaxTree object. var syntaxTree = SyntaxTree.ParseCompilationUnit(pre); 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 pre 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编译更新的语法树,或将语法Root.GetFullText()保存到文本文件并将其传递给csc.exe。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5440865.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存