Компиляция C # с нестандартными языковыми функциями - PullRequest
0 голосов
/ 26 августа 2018

Мне нужно скомпилировать пользовательские выражения в сборки .NET, которые можно вызывать.Язык выражений (унаследованный от версии 1 приложения) очень ограничен и является почти допустимым C #, но у него действительно есть некоторые необычные свойства.

Я хочу переключиться на полный C # в версии 2, но у меня возникли проблемы с преобразованием идиосинкразий в компилируемое SyntaxTree с использованием Roslyn.В данный момент я пытаюсь выяснить, как получить полномочия и факториалы для компиляции, то есть

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

Я хочу знать, есть ли какой-нибудь способ уговорить Рослина разобрать остальныестроки, как есть, или, если нет, какой будет хорошая стратегия для подготовки строки.Очевидно, что я мог бы заменить символы ² и ³ каким-либо разбираемым заполнителем, но не тогда, когда эти символы встречаются внутри строковых или символьных литералов.

----------------------------------- Редактировать -----------------------------------

Преобразование недопустимых символов в комментарии блока позволяет выполнять синтаксический анализ, хотя странно они выглядят как пустякипосле многих узлов:

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: /*!*/
...