At me in a window the expression "a + b * 2" can be entered. How can I parse such a string into a function in the code?
Asked
Active
Viewed 899 times
-3
-
1Did you try anything before asking? Did you ask Google? And how do plan to use it? Do you have inputs for a, b? – Pic Mickael May 28 '18 at 19:30
-
1`String.Split` , `for` loop, Reflection, and some good old fashioned research/googling. Are you up to the challenge? – TheGeneral May 28 '18 at 19:42
-
Also you should really take a look at https://stackoverflow.com/help/how-to-ask – TheGeneral May 28 '18 at 19:44
-
1what you're probably looking for is an "expression parsing library"; many exist, or you can implement it using string functions - for example, I'd probably use a modified shunting-yard algorithm to parse that – Marc Gravell May 28 '18 at 19:46
1 Answers
0
Try something like this:
class Program
{
static void Main(string[] args)
{
var a = 1;
var b = 2;
Console.WriteLine(FN_ParseSnippet($"{a} + {b} * 2"));
Console.ReadKey();
}
public static object FN_ParseSnippet(string snippet)
{
object ret = null;
var usingList = new List<string>();
usingList.Add("System");
usingList.Add("System.Collections.Generic");
usingList.Add("System.Text");
usingList.Add("Microsoft.CSharp");
//Create method
CodeMemberMethod pMethod = new CodeMemberMethod();
pMethod.Name = "Execute";
pMethod.Attributes = MemberAttributes.Public;
pMethod.ReturnType = new CodeTypeReference(typeof(object));
pMethod.Statements.Add(new CodeSnippetExpression(" return " + snippet));
//Create Class
CodeTypeDeclaration pClass = new System.CodeDom.CodeTypeDeclaration("Compilator");
pClass.Attributes = MemberAttributes.Public;
pClass.Members.Add(pMethod);
//Create Namespace
CodeNamespace pNamespace = new CodeNamespace("MyNamespace");
pNamespace.Types.Add(pClass);
foreach (string sUsing in usingList)
pNamespace.Imports.Add(new CodeNamespaceImport(sUsing));
//Create compile unit
CodeCompileUnit pUnit = new CodeCompileUnit();
pUnit.Namespaces.Add(pNamespace);
CompilerParameters param = new CompilerParameters();
param.GenerateInMemory = true;
List<AssemblyName> pReferencedAssemblys = new List<AssemblyName>();
pReferencedAssemblys = Assembly.GetExecutingAssembly().GetReferencedAssemblies().ToList();
pReferencedAssemblys.Add(Assembly.GetExecutingAssembly().GetName());
pReferencedAssemblys.Add(Assembly.GetCallingAssembly().GetName());
foreach (AssemblyName asmName in pReferencedAssemblys)
{
Assembly asm = Assembly.Load(asmName);
param.ReferencedAssemblies.Add(asm.Location);
}
//Compile
CompilerResults pResults = (new CSharpCodeProvider()).CreateCompiler().CompileAssemblyFromDom(param, pUnit);
if (pResults.Errors != null && pResults.Errors.Count > 0)
{
//foreach (CompilerError pError in pResults.Errors)
// MessageBox.Show(pError.ToString());
}
var instance = pResults.CompiledAssembly.CreateInstance("MyNamespace.Compilator");
ret = instance.GetType().InvokeMember("Execute", BindingFlags.InvokeMethod, null, instance, null);
return ret;
}
}

Ermindo Lopes
- 109
- 6