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。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)