【问题标题】:Source-to-source compiler framework wanted需要源到源编译器框架
【发布时间】:2011-02-23 02:07:22
【问题描述】:

我曾经使用 OpenC++ (http://opencxx.sourceforge.net/opencxx/html/overview.html) 来执行代码生成,例如:

来源:

class MyKeyword A {
  public:
    void myMethod(inarg double x, inarg const std::vector<int>& y, outarg double& z);
};

生成:

class A {
  public:
    void myMethod(const string& x, double& y);
    // generated method below:
    void _myMehtod(const string& serializedInput, string& serializedOutput) {
      double x;
      std::vector<int> y;
      // deserialized x and y from serializedInput
      double z;
      myMethod(x, y, z);
    }
};

这种代码生成直接匹配OpenC++教程(http://www.csg.is.titech.ac.jp/~chiba/opencxx/tutorial.pdf)中的用例,通过编写处理“MyKeyword”、“inarg”和“outarg”的元级程序并执行代码生成。但是,OpenC++ 现在有点过时且不活跃,我的代码生成器只能在 g++ 3.2 上工作,并且在解析更高版本的 g++ 头文件时会触发错误。

我看过 VivaCore,但它没有提供编译元级程序的基础结构。我也在看 LLVM,但我找不到指导我解决源到源编译用法的文档。我也知道 ROSE 编译器框架,但我不确定它是否适合我的使用,以及它的专有 C++ 前端二进制文件是否可以在商业产品中使用,以及是否有 Windows 版本可用。

非常感谢任何 cmets 和指向特定教程/论文/文档的指针。

【问题讨论】:

  • 您不能在商业环境中使用 Rose 框架,除非您获得自己的 EDG 前端许可证。不知道 Rose 是否有 Windows 版本。

标签: c++ code-generation code-translation


【解决方案1】:

我不知道任何现成的解决方案,但您可以用相对较少的精力构建自己的解决方案。一种可能的选择是 Elsa C++ 解析器,它有点过时,但易于使用且可扩展。另一种选择是篡改由 Clang++ 生成的 XML AST。我在不同的场景中使用了这两种方法。

【讨论】:

  • 非常感谢大家提供问题的答案。 Elas 和 Clang++ 是非常有用的信息。
  • Clang 是我强烈推荐的。 LLVM 在编译器路径上太远了,无法满足您的需求,但 Clang 是在正确的位置。
  • Elsa 网站似乎自 2005 年左右以来没有任何更新;它声称尝试解析 C++ 2003。
  • @IraBaxter,是的,Elsa 以及 Clang XML 序列化已被弃用。现在应该改用 libclang,它涵盖了以前由其他工具提供的所有可能的用例。
【解决方案2】:

您了解模板元编程的做法吗?如果您以前没有使用过它,它是 C++ 预处理器的应用程序,用于创建奇怪的元程序,感觉更像 LISP 而不是 C++。这个想法和上面的一样——有一个预编译步骤,根据某些输入生成重复的代码。但是,它都是在编译时执行的(而 OpenC++ 看起来在运行时做了几件事)。

考虑到看起来你无论如何都愿意学习一门新的,你愿意用它作为替代“语言”吗?

Boost 提供了一个库,它使用这种技术来提供简单的序列化,就像您在上面展示的那样。 From the tutorial in its manual:

/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
private:
    friend class boost::serialization::access;
    // When the class Archive corresponds to an output archive, the
    // & operator is defined similar to <<.  Likewise, when the class Archive
    // is a type of input archive the & operator is defined similar to >>.
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & degrees;
        ar & minutes;
        ar & seconds;
    }
    int degrees;
    int minutes;
    float seconds;
public:
    gps_position(){};
    gps_position(int d, int m, float s) :
        degrees(d), minutes(m), seconds(s)
    {}
};

int main() {
    // create and open a character archive for output
    std::ofstream ofs("filename");

    // create class instance
    const gps_position g(35, 59, 24.567f);

    // save data to archive
    {
        boost::archive::text_oarchive oa(ofs);
        // write class instance to archive
        oa << g;
        // archive and stream closed when destructors are called
    }

    // ... some time later restore the class instance to its orginal state
    gps_position newg;
    {
        // create and open an archive for input
        std::ifstream ifs("filename");
        boost::archive::text_iarchive ia(ifs);
        // read class state from archive
        ia >> newg;
        // archive and stream closed when destructors are called
    }
    return 0;
}

【讨论】:

  • 感谢关于使用预处理器的想法。但是,一些遗留问题和兼容性问题限制了我过多地改变当前的使用方式。
【解决方案3】:

您可以考虑我们的DMS Software Reengineering Toolkit。 DMS 是将任意语言的源文本解析为编译器数据结构的通用基础 (ASTs、符号表、控制流图、数据流图,取决于你走多远)。

DMS 是一个通用的Source-to-source program transformation system。您可以应用源到源模式导向转换,或编写程序转换(很像 OpenC++), 然后重新生成转换后的程序对应的可编译源文本。

DMS 由显式语言定义参数化,并处理 C、C#、COBOL、Java、Python、javascript、Fortran。

它有一个完整的C++ Front End,可以处理许多真正的 C++ 方言(ANSI、GNU、MS),具有全名和类型解析。带有 C++ 前端的 DMS 可以在多个编译单元内和跨多个编译单元执行由“元程序”控制的转换。它被愤怒地用于对 C++ 软件系统进行彻底重组,包括大规模重新构建任务航空电子软件(参见网站上的论文),最终用于无人机。

DMS 在 Windows 上运行,并在使用 sh 脚本的 Wine 下透明地在 Linux 上运行。

编辑 2/3/2011:DMS 在 Linux 和 Solaris 上的 Wine 下似乎也可以正常运行。在 OSX 下对 Wine 上的 DMS 进行测试。

编辑 3/1/2011:DMS 似乎也可以在 Wine for OSX 下运行。

编辑 2/21/2013:C++ 前端现在处理 ANSI C++11,以及 C++11 的 MS 和 GNU 版本。

编辑 2/24/2015:现在处理 ANSI、MS 和 GNU 风格的 C++14。

编辑 1/16/2019:现在处理 ANSI、MS 和 GNU 风格的 C++17。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2019-06-09
    • 2019-05-27
    • 1970-01-01
    • 2015-01-30
    相关资源
    最近更新 更多