【问题标题】:C# Interpreter (without compilation) [closed]C#解释器(不编译)[关闭]
【发布时间】:2010-12-12 05:45:13
【问题描述】:

是否有现成的 C# 解释器,它不依赖于运行时编译?

我的要求是:

  • 脚本引擎
  • 必须处理 C# 语法
  • 必须在中等信任环境中工作
  • 不得使用运行时编译(CodeDomProvider ...)
  • 开源(或至少免费供个人和专业用途)

如果不清楚,我需要 Jint (http://jint.codeplex.com/) 之类的东西,但它允许我编写 C# 脚本而不是 JavaScript 脚本。

感谢您的帮助。

【问题讨论】:

  • 您能否详细说明为什么需要 C# 语法而不需要运行时编译?由于 C# 语言的指定方式以及 CLR 原始类型的实现方式,我不相信您所要求的甚至是可能的。但我的猜测是,你并不真正需要 C# 语言来做你想做的事情。
  • 1) 运行时编译涉及程序集生成,需要完全信任模式,我正在使用中等信任的 asp.net 环境。 2) 在某些特定情况下,我需要评估 10000 多个不同的小脚本,编译所有这些脚本会非常缓慢,并且使用程序集缓存将毫无用处,并且会很快杀死我的 AppPool。
  • ... 3) 除了 C#,我不想写任何东西:p
  • 在 DLR 中运行的 C# 会很有趣。
  • 反射是否适用于中等信任环境?

标签: c# scripting


【解决方案1】:

你看过paxScript.NET吗?

【讨论】:

  • 感谢您的回复,我的办公室代理目前正在阻止此网址(作为垃圾邮件),不知道为什么,我今晚回家查看。
  • 我刚刚测试了它,它看起来很棒,但我忘了提到我需要一个开源工具。无论如何都要为这个答案+1。
  • 6年后是什么意思?快速谷歌发现:paxcompiler.com/paxscriptnet/about.htm我已经更新了链接,谢谢。
【解决方案2】:

查看Mono 项目。他们最近演示了CsharpRepl,这听起来像是您所追求的。 PDC 2008 视频here.


更新:
仔细一看,似乎不可能使用Mono.CSharp 服务来评估脚本。目前它与 Mono 运行时相关联,他们不希望它在中等信任环境中运行。请参阅this discussion 了解更多信息。

另一种可能性是在您的项目中包含Mono C# compiler(来源here)并使用它来生成您从文件系统加载的程序集。如果您担心加载所有这些程序集所需的资源,您可能必须将它们加载到单独的 AppDomain 中。

【讨论】:

  • 嗨,是否可以 1) 允许脚本与我编译的程序集进行交互(针对 .NET 3.5 而不是 Mono)2) 在 asp.net 应用程序中使用它(而不是在外壳模式)?
  • @manitra,1) Mono 程序集与 .NET 程序集交互得很好。我有许多应用程序使用 Mono 中的一些程序集和 .NET 中的一些程序集。 2) 无论您从哪种应用中调用它们都没有关系。
  • 这个解决方案的问题在于它是一个编译器。我无法承受预热延迟,因为我有很多不同的小脚本。
【解决方案3】:

我需要评估 10000+ 个小 完全不同的脚本, 编译所有这些只是 非常慢

解释这些会更加缓慢。我们有一个类似的问题,我们解决如下:

我们使用 Gold Parser 项目来解析源代码并将其转换为基于 XML 的“通用语言”。我们通过一个生成 VB.Net 源代码的转换来运行它(仅仅是因为它不区分大小写)。然后我们使用 .Net 运行时将它们编译成一个独立的 DLL,并使用严格限制的访问来调用它。

听起来好像您正在创建一个动态网站,人们可以在其中创建自定义模块或功能的 sn-ps,但是使用 C# 来执行此操作会带来几个主要问题; C# 必须编译,解决这个问题的唯一方法是在运行时对其进行交互,这是不可行的,即使你编译每个 sn-p 最终也会得到 10,000 个 DLL,这是不切实际且不可用的。

如果您的 sn-ps 很少更改,那么我会考虑以编程方式将它们包装到一组源代码中,每个源都有一个唯一的名称,然后一次性编译它们(或者每 10 分钟作为一个定时过程?) .这就是我们所做的,因为它还允许对人们的会话进行“版本控制”,以便他们继续使用他们在会话开始时拥有的 DLL 版本,但是当每个会话停止使用旧版本时,它就会被删除。

如果您的 sn-ps 在一天中定期更改,那么我建议您改用解释脚本语言,甚至是 PHP,并根据您需要的功能混合您的语言。 CScript 和 LinqPad 等产品都使用 CodeDomProvider,因为如果要对编译后的逻辑进行编程,就必须在某个地方拥有 IMSL。

唯一的其他选择是编写自己的解释器并使用反射来访问您需要访问的所有其他库,但这非常复杂和可怕。

由于您的要求实际上无法实现,我建议您退后一步,想办法消除一个或多个限制。无论您是找到一个 FullTrust 环境来编译您的 sn-ps,消除对完整代码支持的需求(即转向解释代码 sn-p 支持),还是甚至将整个框架更改为非 .Net 的东西。

【讨论】:

    【解决方案4】:

    LINQPad 可以作为代码 sn-p IDE 工作。该应用程序非常小巧轻便。它是免费的(就像啤酒一样),但不是开源的。自动完成需要额外的费用,但并不高(19 美元)。

    编辑:在仔细阅读这篇文章中的 cmets 之后,我认为 LINQPad 不是您想要的。您需要能够以编程方式动态评估数千个小脚本的东西,对吧?我在工作中使用 Iron Ruby 很容易做到了这一点。如果您愿意使用 DLR 语言,这可能更可行。我还对一些代码进行了类似的工作,这些代码可以评估作为字符串传入的 C# lambda 表达式,但这非常有限。

    【讨论】:

    • 感谢您的回答。事实上,Linqpad 不是我想要的,但它仍然是一个很棒的工具 :)
    【解决方案5】:

    我编写了一个开源项目Dynamic Expresso,它可以将使用 C# 语法编写的文本表达式转换为委托(或表达式树)。表达式被解析并转换为Expression Trees,而不使用编译或反射。

    你可以这样写:

    var interpreter = new Interpreter();
    var result = interpreter.Eval("8 / 2 + 2");
    

    var interpreter = new Interpreter()
                    .SetVariable("service", new ServiceExample());
    
    string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";
    
    Lambda parsedExpression = interpreter.Parse(expression, 
                            new Parameter("x", typeof(int)));
    
    parsedExpression.Invoke(5);
    

    我的作品基于 Scott Gu 的文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

    【讨论】:

    • +1 这项工作值得点赞,但它并不是很干净。
    【解决方案6】:

    http://www.csscript.net/ Oleg 在code project

    写了一篇很好的介绍

    【讨论】:

    • 你好 Marc,CsScript 使用运行时编译,因此它无法在中等信任环境中工作。
    • 啊,对不起,我可能在你的问题中匆忙解决了这个限制。现在我明白了。
    • 没关系。无论如何,感谢您的快速回复:)
    【解决方案7】:

    它不能处理精确的 C# 语法,但是 PowerShell 与 .NET 框架如此紧密地结合在一起,并且是一个如此成熟的产品,我认为你至少将它作为一种可能的解决方案来忽略它是不明智的。 Microsoft 推出的大多数服务器产品现在都支持 PowerShell 的脚本接口,包括 Microsoft Exchange 和 Microsoft SQL Server。

    【讨论】:

    • 谢谢 Lee,但 C# 语法确实是我问题的重要部分。那里有很多现有的解释器(Jint 是我最接近的要求)但是,我厌倦了学习多种语言,只需要我的 c# 东西。无论如何感谢您的回答:)
    【解决方案8】:

    我相信 Mono 有 mint,这是他们在为给定平台实现 JIT 之前使用的解释器。虽然官方网站上的文档(例如Runtime)说这只是整合 jitting VM 之前的一个中间状态,但我很确定我上次在 L​​inux 上编译它时它就在那里。很遗憾,我现在不能完全检查它,但也许它正朝着你想要的方向。

    【讨论】:

    • 嗯,它看起来像一个死气沉沉的项目?它可以在 Windows 上运行吗?
    • 它并没有死——它只是在虚拟机被移植后失去了相关性。我已经阅读了更多内容,但它最终不会做你想要的:mint 解释 CLI 字节码,而不是像 paxScript 那样解释 C# 文件。抱歉,我无法提供更多帮助。
    • -1 mint 是 IL 解释器。它在很久以前就被淘汰了。现在只有一个 IL JIT。
    【解决方案9】:

    bungee#是你想要的东西,在短时间内,bungee sharp将成为一个开源项目

    http://www.crssoft.com/Services/Bungee

    。您可以使用相同的 c# 语法创建脚本。运行脚本时不会创建程序集,解释是即时完成的,因此性能很高。所有关键字都可以像 c# 一样使用。我希望你会非常喜欢它..

    【讨论】:

      【解决方案10】:

      我遇到了同样的问题。在一个项目中,我希望提供一种通用方法来指定控制何时必须生成某个字母的条件。在另一个项目中,条件是控制如何将案件分配到队列中。在他们两个中,以下解决方案都非常有效:

      1. sn-ps 的语言 - 我选择 JScript 是为了不必担心变量类型。
      2. 编译 - 是的,它需要完全信任,但您可以将代码放在单独的程序集中并给予完全信任。不要忘记使用 AllowPartiallyTrustedCaller 属性对其进行标记。
      3. 代码 sn-ps 的数量 - 我将每个 sn-p 视为一种方法,而不是一个类。这样可以将多种方法组合成一个程序集
      4. 磁盘使用 - 我在内存中进行了所有编译,但没有将程序集保存到磁盘。如果您需要重新加载它,它也会有所帮助。

      所有这些都可以在生产中正常工作

      编辑

      只是为了澄清'sn-p' - 我所说的条件只是布尔表达式。我以编程方式添加附加文本以将其转换为可编译类的方法和方法。

      我也可以用 C# 做同样的事情,尽管我仍然认为 JScript 更适合代码 sn-ps

      顺便说一句,我的代码是开源的,请随意browse。请记住,那里有很多与此讨论无关的代码。如果您需要帮助来查找与该主题相关的部分,请告诉我

      【讨论】:

        【解决方案11】:

        这个真的很好用 c# repl and interactive interpreter

        【讨论】:

        • 让我限定一下 - 它适用于大多数基本需求。它缺乏良好的错误报告。可能是我抓住源头并重振这项工作的时候了。
        【解决方案12】:

        Snippet Compiler 是您在寻找的东西吗?

        【讨论】:

        • 我负担不起脚本的编译时间,此外,它无法在中等信任的环境中工作。
        猜你喜欢
        • 1970-01-01
        • 2010-09-09
        • 2011-08-24
        • 1970-01-01
        • 2011-03-23
        • 2023-04-10
        • 2010-09-07
        • 2017-06-28
        • 1970-01-01
        相关资源
        最近更新 更多