可以在运行时解析和评估.NET

时间:2011-11-30 14:53:04

标签: c# .net vb.net interpreter

我认为如果我能在运行时编写vb.net或c#代码并且解释器会自动解析它就像python那样会很有趣,所以我做了一个小程序,它会做类似的事情。基本上它看起来像这样:

InputArgs = Console.ReadLine()
ParseInput(InputArgs.Split(" "))

Private Sub ParseInput(Args as List(Of String), Optional TempArgs as List(Of String))
Dim arg as string = Args(0)
If arg = ".." then
 ...
elseif arg = ".." then
 ...
end if
End Sub

我知道这不是一个好的系统,但它显示了基础知识。所以我的问题是:是否有可能使vb.net或c#像python一样 - 在运行时解释?

6 个答案:

答案 0 :(得分:5)

这已经存在于相当多的形状和形式中:

Mono.CSharp

Mono拥有Mono.CSharp程序集,您可以参考该程序集执行CSharp.exe (A C# 'interpreter' or interactive shell, if you will)可以执行的操作:

void ReadEvalPrintLoopWith (ReadLiner readline)
{
    string expr = null;
    while (!InteractiveBase.QuitRequested){
            string input = readline (expr == null);
            if (input == null)
                return;

            if (input == "")
                continue;

            expr = expr == null ? input : expr + "\n" + input;

            expr = Evaluate (expr);
    } 
}

毋庸置疑这也适用于MS.Net (当然,这是关于便携式.Net的重点)。

完整来源here on github - 就像其他的Mono一样。

DLR

已实施多种DLR语言,包括但不限于

它允许您在.NET框架中动态评估python / ruby​​代码。

罗斯林

Microsoft已将Roslyn发布为CTP(预览版)。它基本上可以做与Mono REPL(第一项)相同的东西,以及(更多)。但它仍然是预览。

答案 1 :(得分:2)

它可以,但这将是很多工作。

一种方法是自己编写解析器+解释器。要创建解析器,您需要输入语言的语法定义,例如C#。请注意,C#语法非常复杂。

另一种方法是动态编译C#代码。以下是如何执行此操作的示例:http://www.voidspace.org.uk/ironpython/dynamically_compiling.shtmlhttp://blogs.msdn.com/b/saveenr/archive/2009/08/11/a-walkthrough-of-dynamically-compiling-c-code.aspx

祝你好运!

答案 2 :(得分:1)

没有太多时间给你一个正确的答案,但这里是我的一个旧项目的评估代码:

        CSharpCodeProvider c = new CSharpCodeProvider();
        ICodeCompiler icc = c.CreateCompiler();
        CompilerParameters cp = new CompilerParameters();

        cp.ReferencedAssemblies.Add("system.dll");
        cp.ReferencedAssemblies.Add("system.xml.dll");
        cp.ReferencedAssemblies.Add("system.data.dll");
        cp.ReferencedAssemblies.Add("system.windows.forms.dll");
        cp.ReferencedAssemblies.Add("system.drawing.dll");

        cp.CompilerOptions = "/t:library";
        cp.GenerateInMemory = true;

        StringBuilder sb = new StringBuilder("");
        sb.Append("using System;\n");
        sb.Append("using System.Xml;\n");
        sb.Append("using System.Data;\n");
        sb.Append("using System.Data.SqlClient;\n");
        sb.Append("using System.Windows.Forms;\n");
        sb.Append("using System.Drawing;\n");

        sb.Append("namespace CSCodeEvaler{ \n");
        sb.Append("public class CSCodeEvaler{ " + csCode + "} }");

        CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
        if (cr.Errors.Count > 0)
        {
            MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
               "Error evaluating cs code", MessageBoxButtons.OK,
               MessageBoxIcon.Error);
            return null;
        }

        System.Reflection.Assembly a = cr.CompiledAssembly;
        object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");

        Type t = o.GetType();
        MethodInfo mi = t.GetMethod("Transform");

        return mi;

此代码的原始变体取自:http://www.codeproject.com/KB/cs/evalcscode.aspx

它编译了一些C#代码(代码应该在csCode变量中),然后尝试在其中找到Transform()方法并返回它的MethodInfo,这样我们就可以执行它了。

但请记住,每次调用此代码时,都会加载一个新的程序集,所以不要经常使用它。

此外,正如普雷斯科特所说 - 试试罗斯林

希望这会有所帮助。很抱歉,没有提供更具体问题的代码示例。

PS。如果你想要一些交互式窗口,可以使用第三方控件(使用google查找,因为我不记得确切的产品名称)

答案 3 :(得分:1)

你是在重新发明LinqPad吗?

LinqPad是一个免费的符合人体工程学的C#/VB/F# scratchpad,它可以立即执行具有丰富输出格式的任何表达式,语句块或程序。这很棒。

如果您真的想开发自己的问题,请查看一些类似的现有问题one two three four ......

答案 4 :(得分:0)

  

所以我的问题是:是否有可能使vb.net或c#像python一样 - 在运行时解释?

不确定。开始为它编写解释器,然后你就可以解释它。 从一个很好的语法分析器开始。然后从那里继续。

答案 5 :(得分:0)

不是我知道..但是作为一个黑客,你可以创建一个textarea,它有一个TextChanged事件处理程序,它调用编译器程序(不知道它在哪里)。