Мне нужно скомпилировать пользовательские выражения в сборки .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: /*!*/