【问题标题】:How do I "compile" an expression in c++ at runtime? [duplicate]如何在运行时在 C++ 中“编译”表达式? [复制]
【发布时间】:2012-08-31 04:42:34
【问题描述】:

可能重复:
compile and run c++ code runtime

我想将来自用户的表达式作为字符串作为输入,并将其编译为可调用的 c++ 函数。是否有任何工具可以让您轻松做到这一点?

基本上,How do I compile an Expression Tree into a callable method, C#? 似乎与我想做的类似,只是我需要在 c++ 而不是 c# 中执行此操作。

我当然可以使用 lex 和 yacc 制作一种通用的求值器,但我不想每次都解析字符串。基本上这个表达式将在一个关键的内部循环中运行,所以我正在寻找一种在运行时“编译”它的方法。

【问题讨论】:

  • 这似乎与 Compile and run C++ code runtime 重复
  • 嗯,是的,它是重复的。但是这个问题也没有很好的答案……
  • 我会研究 libclang 和 llvm。您应该知道,C# 使这项任务变得异常简单,而在 C++ 中它是劳动密集型的。
  • @owagh 那是因为真的没有一个好的答案。您可以使用重量级解决方案,例如使用外部或嵌入式的实际编译器(例如,LLVM 可用于嵌入式 JIT 编译器),或者您可以实现自己的字节码编译器和评估器(或使用其他人的;Lua 是实现为可嵌入的字节码编译器/评估器。当然它只处理 Lua 语言)。
  • 也许this 就是您要找的。 -尼克

标签: c++ compilation runtime expression


【解决方案1】:

这并不容易...如果你想要我的两分钱,我会按照以下步骤操作:

  1. 为必须在运行时创建的代码创建一个接口。首先,你为你能做的事情创建一个界面。例如,您的类必须从代表您的接口的纯虚拟基类继承。请注意,您的程序不会使用任意代码,而是以特定方式创建的代码,因为它必须知道如何使用它。
  2. 从程序内部调用编译器。编译器应该从您的源代码创建一个库。您可以使用存储在某处的预定义项目,然后将其源文件替换为您自己的。所以很容易获得合适的库。
  3. 将您的库放在您可以找到的指定来源中。
  4. 在运行时加载库。如果您搜索,您会发现可以在运行时加载动态库,而不仅仅是在链接时(例如,您可以通过这种方式为程序创建插件)。所以你的程序可以加载你的库并使用它。比如你可以找到一些信息here

但是,正如其他人所说,这不是一项微不足道的任务。

编辑:另一种解决方案是检查像 boost::spirit::qi 这样的解析器,使用得当可以提供非常有用的结果。

【讨论】:

  • 这似乎是一个连贯但困难的解决方案。让我看看这是怎么回事。
【解决方案2】:

您必须将表达式解析为抽象语法树并在原地遍历或评估它。 Something like this 应该可以满足您对简单数学表达式的需求。

【讨论】:

    【解决方案3】:

    您可以编写您的迷你解释器。使用与 c++ 相同的命令(不是全部)。当然你的编译器会优化它,但不确定多少。我在 qbasic (mov, add, sub...) 中进行了组装,但由于是解释器的解释器,所以速度很慢:D

    您是否考虑过进化计算和适应度函数?值得一看。

    【讨论】:

      【解决方案4】:

      您可以创建一个数据结构来表示您解析的表达式树,并且与每次解析字符串相比,在运行时评估它的开销会很小。

      实际上在 C++ 中获得一个可调用的方法是相当困难的,因为您必须生成目标代码并将其动态加载到您的程序中。这将复制整个编译器工具链所做的很多事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-21
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多