【问题标题】:Partially parse C++ for a domain-specific language为特定领域的语言部分解析 C++
【发布时间】:2011-02-16 07:32:00
【问题描述】:

我想创建一种特定领域的语言作为增强型 C++ 语言。我主要需要两种类型的结构:

  • 专用类型或声明的顶级构造
  • 代码内构造,即添加原语以使函数调用或习语更容易

该语言将用于科学计算目的,最终将被翻译成纯 C++。选择 C++ 是因为它似乎在以下方面提供了一个很好的折衷:易用性、效率和各种库的可用性。

由于 C++ 语法的复杂性,之前使用 flex 和 bison 的尝试失败了。现有的解析器仍然可能在某些构造上失败。所以我们想重新开始,但要在更好的基础上。

你知道类似的项目吗?如果你尝试这样做,你会使用什么工具?主要的陷阱是什么?你有语法方面的建议吗?

【问题讨论】:

  • 您可以检查 Clangs 当前的 C++ 支持是否对您来说足够好 - 他们的 API 看起来很有前途并且应该是可扩展的。

标签: c++ parsing code-generation dsl


【解决方案1】:

有很多(聪明的)尝试在 C++ 语言中使用特定领域的语言。

对于领域特定的嵌入式语言,它通常被称为DSEL。例如,您可以查找 Boost.Spirit 语法或 Boost.rdb(在 boost vault 中)。

这些是完全兼容的 C++ 库,使用 C++ 语法。

如果你想隐藏一些复杂性,你可以添加一些宏。

如果你给我们一些可以使用的东西,我很乐意提供一些例子:)

【讨论】:

    【解决方案2】:

    您可以尝试扩展一个开源 Elsa C++ 解析器(它现在是 Mozilla 的 Pork 项目的一部分):

    https://wiki.mozilla.org/Pork

    【讨论】:

      【解决方案3】:

      扩展 C++ 的方法不是尝试扩展语言,这将非常困难并且可能会随着新的基本编译器版本实现新功能而中断,而是编写类库来支持您的问题域。自 C++ 语言诞生以来,这就是 C++ 编程的全部内容。

      【讨论】:

      • 我知道,这就是我开始的。但是对于非 C++ 程序员来说,结果看起来仍然相当可怕。这就是为什么我现在想在 C++ 之上添加一个薄层以使内容更具可读性(例如避免使用复杂的模板,添加一些在代码中经常出现的惯用构造,或者用关键字替换一些函数调用以提供更好的语法)。
      • 这并不完全正确。一些基于 C++ 的最佳项目包含增强的 C++ DSL。仅举几例:Qt 中的 MOC 预处理器,LLVM 中的 tablegen DSL。
      【解决方案4】:

      如果您真的想扩展 C++,您将需要一个完整的 C++ 解析器以及名称和类型解析。正如您所发现的,这非常困难。您最好的解决方案是获取现有的并对其进行修改。

      我们的DMS Software Reengineering Toolkit 是用于实现语言处理器的基础架构。它是 旨在支持构建解析语言、执行转换和输出相同语言(使用增强代码)或不同语言/方言的工具。

      DMS 有一个完整的C++ Front End,它解析 C++、构建抽象语法树和符号表(例如,所有名称和类型解析的东西)。

      DMS/C++前端以源代码形式提供DMS,可以自定义实现你想要的那种效果。您将 DSL 定义为 C++ 前端的扩展,然后编写将您的特殊构造转换为“普通”C++ 构造的转换,然后输出可编译的结果。

      DMS/C++ 已用于各种各样的转换任务,包括您所描述的涉及扩展 C++ 的任务,以及对大型 C++ 应用程序进行大规模重组的任务。 (参见该网站上的出版物)。

      【讨论】:

      • “如果你真的想扩展 C++,你需要一个完整的 C++ 解析器以及名称和类型解析”——不,不一定。解析出 augmented 结构就足够了。当然,这不需要阻塞其余代码,但这并不需要拥有完整的解析器。
      • 实际上有可能找到足够琐碎的扩展,所以实际上你可以通过 Perl 和 regex hacking 来做到这一点。在实践中,很难找到有趣的 C++ 扩展(例如 OP 的概念“专用类型和声明”),这样您就可以摆脱解析,特别是如果编写这样的声明会影响代码的其他部分。即使这样,您也会发现解析是一项艰巨的任务。如果您尝试解析 而没有 名称和类型解析,则必须保留所有模棱两可的解析。
      • 这看起来很不错,但不幸的是,这仅适用于Windows,这是我不使用的系统。
      • 祝你好运。这些野兽非常罕见。您可能会查看 EDG,但是,解析器是手动实现的,这将使其扩展比仅添加额外的语法规则要困难得多,并且您必须自己构建所有转换支持基础架构。您可能会发现它与 C++ 解析引擎具有相同的规模
      【解决方案5】:

      为了解决你的第一个问题,也许你可以使用 C++0x 的新特性“初始化列表”和“用户定义的文字”来避免需要新的解析器。他们也可能有助于第二个子弹。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-05
        • 2010-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多