使用非标准语言功能编译C#

时间:2018-08-26 12:36:44

标签: c# roslyn

我需要将用户类型的表达式编译为可以调用的.NET程序集。表达式语言(从应用程序的版本1继承)非常有限,并且几乎是有效的C#,但它确实具有一些不寻常的属性。

我想在版本2中切换到完整的C#,但是在使用Roslyn将特质转换为可编译的SyntaxTree时遇到问题。此刻,我正试图弄清楚如何获得力量和阶乘进行编译,即

double n = 1.5² / 0.9³ + 6!;

必须转换为类似的内容:

double n = Pow(1.5, 2) / Pow(0.9, 3) + Factorial(6);

但是,当我解析原始表达式时,所有这些立即在²字符处分解:

public static void TestLanguageAdditions()
{
  const string code = "double n = 1.5² / 0.9³ + 6!;";

  var syntaxTree = CSharpSyntaxTree.ParseText(code);
  var syntaxRoot = syntaxTree.GetRoot();

  var sb = new StringBuilder();
  sb.AppendLine(code);
  sb.AppendLine();

  foreach (var node in syntaxRoot.DescendantNodes())
  {
    var span = node.FullSpan;
    var spanLine = 
      new string(' ', span.Start) + 
      new string('●', span.Length);

    spanLine = spanLine.PadRight(30);
    spanLine += ((CSharpSyntaxNode)node).Kind();

    sb.AppendLine(spanLine);
  }

  string report = sb.ToString();
  Console.Write(report);
}

收益:

double n = 1.5² / 0.9³ + 6!;

●●●●●●●●●●●●●●●●●●●●●●●●●●●●  FieldDeclaration
●●●●●●●●●●●●●●                VariableDeclaration
●●●●●●●                       PredefinedType
       ●●●●●●●                VariableDeclarator
         ●●●●●                EqualsValueClause
           ●●●                NumericLiteralExpression

我想知道是否有任何办法哄Roslyn照原样解析字符串的其余部分,否则,准备字符串的好策略是什么?显然,我可以用一些可解析的占位符替换²³字符,但是当这些字符出现在字符串或字符常量中时,则不能。

-----------------------------------编辑----------- ------------------------

将非法字符转换为块注释可以进行解析,尽管奇怪的是,它们在许多节点之后都显示为琐事:

double n = 1.50/*²*/ / (0.90)/*³*/ + 6/*!*/;
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● CompilationUnit
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●● FieldDeclaration
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●· VariableDeclaration
······································●●●●●·  ˃ trivia: /*!*/
●●●●●●●····································· PredefinedType
·······●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●· VariableDeclarator
······································●●●●●·  ˃ trivia: /*!*/
·········●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●· EqualsValueClause
······································●●●●●·  ˃ trivia: /*!*/
···········●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●· AddExpression
······································●●●●●·  ˃ trivia: /*!*/
···········●●●●●●●●●●●●●●●●●●●●●●●●········· DivideExpression
·····························●●●●●··········  ˃ trivia: /*³*/
···········●●●●●●●●●●······················· NumericLiteralExpression
···············●●●●●························  ˃ trivia: /*²*/
·······················●●●●●●●●●●●●········· ParenthesizedExpression
·····························●●●●●··········  ˃ trivia: /*³*/
························●●●●················ NumericLiteralExpression
·····································●●●●●●· NumericLiteralExpression
······································●●●●●·  ˃ trivia: /*!*/

0 个答案:

没有答案