c ++是否有非模板元语言? [英] Is there a non-template metalanguage for c++?

查看:79
本文介绍了c ++是否有非模板元语言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读boost :: MPL作者的c ++模板元程序设计书。我是一个精神/凤凰图书馆的大粉丝。



但我很想知道。使用模板进行c ++元编程是一个麻烦。它不是为了使用。模板和宏都不支持循环。在模板中你基本上必须通过递归。



根据我的理解,c ++编译过程大致如下:


  1. 扩展/评估宏

  2. 实例化模板(代码生成)

  3. 解析,中间代码生成,机器无关优化,生成汇编/对象文件/链接...)

模板元编程是进入步骤1& 2,20年前错误地发现了。



使用实际语言不是更简单吗?我的意思是一些语言,可以访问的c + +语法树和操纵它,以及漂亮的文本处理能力。



我想到一个模板语言,如twig / django,以及适当的钩子到g ++ AST,以及type_traits和pod类型的本地定义。 strong>



是否存在?我在网上找不到类似的东西。它可以实现与c ++模板元编程相同的结果(和更多),但是编译速度更快,更干净,更可读的代码。

解决方案

p>您想要的是计划转换系统(PTS)



这些工具通过完全跳过编程语言来泛化元编程(因此,不同于模板[和你的投诉] PTS不限于你在编程语言中说的) 。通常,PTS通过编程语言语法和美观打印规则来参数化(使其能够将感兴趣的语言P解析成AST,并且从AST解释为返回到源)代码),一组变换(它们表示要进行的更改的实质,例如优化数组访问)和一些元程序图M,它们对变换应用于何处以实现所需的确切目的(例如, ,优化这些数组访问,但不是这些)。



一个好的PTS允许你使用嵌入在P语法中的模式语言编写变换。因此,一个变换基本上表示如果你匹配一个模式p,replace它由q,其中p和q是感兴趣的代码的表面语法版本。对于基于AST的变换规则,没有一个变换可以做任意大量的工作(因为模式AST是固定直径的),所以需要一个以上的变换来实现复杂的结果。



元程序对转换进行排序;它可以以各种方式编码。策略在对基本变换模式语言的策略DSL扩展中对元程序进行编码,这是对在点处变换成功或失败的反应以及树导航步骤(上,下,重复)。 TXL的元程序在模式匹配中起作用。 DMS使用PARLANSE,它是一种并行编程语言,它允许对真正大量的源代码并行应用(仔细)变换。 Clang没有完全的源模式匹配,但是有一些AST匹配器,使语法匹配更容易;否则你将变换作为程序代码在树上向上/向下写,嵌入在C ++本身编码的元程序中。 Rose Compiler的元程序在很大程度上是类似Clang的程序。有Eclipse CDT重构工具;我不知道他们的状态,但他们没有模式导向的转换,我认为元程序是用Java编写的。还有其他PTS;他们中的大多数不像这些强大或成熟。 GCC存在,但没有被组织为PTS。 (所有这一切都用一粒盐;我是DMS背后的人,所以你可能不想相信我)。



你特意要操纵C ++。这意味着工具必须正确地处理C ++。 Stratego和TXL目前不支持C ++,并且是不太可能的,因为它需要努力来产生一个完整的C ++前端。 Clang显然有一个有用的C ++前端。玫瑰由于使用EDG前端也是如此。 DMS有一个完整的C ++ 11前端,我们在大型GCC和Windows c ++代码库上构建和验证。我不知道CDT前端的成熟度;



(编辑2015年9月:DMS现在处理完整的C ++ 14在MS和GCC方言)。



通过元编程从内部与外部交换的内容是真正真正的模板元编程的可读性,对于通常较少的奥术语法的模式和元编程语言。 IMHO你得到表达力,因为PTS被设计为操纵源代码,他们通常可以调用由底层机器(符号表,类型信息,控制/数据流)提供的分析器,模板根本不能接近。



对我来说,真正的优势是PTS可以跨任意代码边界应用变换;大多数C ++模板只能生成代码来替换模板调用。 (特别地,在语言中实现的所有元编程/反射方案的缺陷是它们的能力总是有限的; PTS没有这样的限制)。



您可以找到指向DMS描述的链接。更重要的是,有一系列文章(例如,案例研究:通过自动程序转换重新设计C ++组件模型),描述了应用于C ++程序的大规模转换(将其从具有复杂API的一个RTOS转移到完全不同的系统,以及从根本上重构API),可以给你一个风味的这看起来像。 (据我所知,在各种PTS工具中,只有DMS已经应用于C ++转换任务这个雄心勃勃的。)这些论文将显示PTS操作根本不像模板元编程,不依赖于像SFINAE这样的技巧,可以做事情没有模板元程序IMHO可以实现。


I'm reading the c++ template meta-programming book from the boost::MPL authors. I'am a big fan of the spirit/phoenix libraries.

However I was wondering. Using templates for c++ meta-programming is a hassle. It was not intended for that use. Neither templates nor macros support looping. In templates you basically have to go through recursion.

As I understand it, the c++ compilation process is roughly:

  1. expands/evaluates Macro
  2. instantiates templates ( code generation )
  3. then actual other compilation steps ( lexical analysis, parsing, intermediate code generation, machine independent optimization, generating assembly/object files/linking...)

template meta-programming is a hack into the steps 1 & 2, discovered somewhat by mistake 20 years ago.

wouldn't it be simpler to use an actual language ? I mean some language which could access the c++ syntax tree and manipulate it, together with nice text processing capability.

I am thinking of a template language like twig/django, together with appropriate hooks into the g++ AST, and native definitions for type_traits and pod types.

Does this exist ? I haven't found anything like this on the web. It could achieve the same result ( and more ) than c++ template meta programming, but with faster compilation, cleaner and more readable code.

解决方案

What you want is a program transformation system (PTS).

These tools generalize metaprogramming by stepping outside the programming language entirely (so, unlike templates [and your complaint] PTSs are not limited to what you can say in the programming language).

In general, PTS are parameterized by programming language syntax and prettyprinting rules (enabling it to parse the language of interest P into ASTs, and to unparse from ASTs back to source code), a set of transformations (which represent the essence of the changes you want to make, e.g, "optimize array accesses") and some "metaprogram" M which sequences how the transformations are applied to acheive the exact purpose you want (e.g., "optimize these array accesses but not those)".

A good PTS allows you to write the transformations in a pattern language embedded in the syntax of P. A transformation thus states essentially, "If you match a pattern p, replace it by q" where p and q are surface syntax versions of the code of interest. For AST-based transformation rules, no one transformation can do arbitrarily large amounts of work (because pattern ASTs are fixed-diameter), so one needs more than one transformation to achieve complex results.

The metaprogram sequences the transformations; it may be coded in a variety of ways. Stratego codes meta programs in a "strategies" DSL extension to the base transform pattern language, which are reactions to transforms succeeding or failing at point, and tree navigation steps (up, down, repeat). TXL's meta programs are functional over pattern matches. DMS uses PARLANSE, a parallel programming language, which allows transforms to be applied (carefully) in parallel on really big sets of source code. Clang doesn't have full source pattern-matching, but has some "AST" matchers to make syntax matching a little easier; otherwise you write the transforms as procedural code walking up/down the tree, embedded in a meta program coded in C++ itself. Rose Compiler's meta programs are largely procedural like Clang. There the Eclipse CDT Refactoring tools; I don't know their status well, but they do not have pattern directed transformations, and I think the meta programs are written in Java. There are other PTSs; most of them are not as robust or mature as these. GCC exists but isn't organized to be a PTS. (Take all this with a grain of salt; I'm the guy behind DMS and so you might not want to believe me).

You specifically want to manipulate C++. This means that the tool must process C++ decently. Stratego and TXL do not presently support C++, and are unlikely because of the effort it takes to produce a full C++ front end. Clang obviously has a useful C++ front end. So does Rose by virtue of its use of the EDG front end. DMS has a full C++11 front end that we built and validated against on large GCC and Windows c++ code bases. I'm not sure about the maturity of the CDT front end; in particular, I don't understand what they are using as a parser.

(EDIT Sept 2015: DMS now handles full C++14 in both MS and GCC dialects).

What you trade by metaprogramming from "inside" vs. "outside" the language is readability of truly, truly arcane "template metaprogramming" for the usually less arcane syntax of patterns and the metaprogramming language. IMHO you get expressive power, because the PTSs are designed to manipulate source code, and they can typically call on analyzers provided by the underlying machinery (symbol tables, type information, control/dataflows) that the templates simply cannot get near.

For me, the real strength is that PTSs they can apply transformations across arbitrary code boundaries; most C++ templates can only generate code to replace the template call. (In particular, a flaw with all metatprogramming/reflection schemes implemented inside a language is they are invariably limited in capability; PTSs have no such limitations).

At my bio, you can find a link to a description of DMS. More importantly, there's a set of papers there (e.g., "Case Study: Re-engineering C++ Component Models Via Automatic Program Transformation"), describing massive transformation applied to C++ programs (to shift them from one RTOS with complex APIs to a completely different system, as well as refactor the APIs radically) that can give you a flavor for what this looks like. (To my knowledge, of the various PTS tools, only DMS has been applied to C++ transformation tasks this ambitious.) These papers will show that PTS operations don't resemble template metaprogramming at all, don't rely on tricks like SFINAE, and can do things no template metaprogram IMHO could ever achieve.

这篇关于c ++是否有非模板元语言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆