【问题标题】:Is there any language to specify automatic code modifications?是否有任何语言可以指定自动代码修改?
【发布时间】:2015-03-18 03:59:17
【问题描述】:

我正在做一些工作,我需要能够描述对某些要自动完成的程序代码的修改。

是否有任何语言可以描述这一点?

该语言应具有接收代码中要进行修改的位置的模块或函数,并应允许指定可能进行的修改。
它应该允许描述修改,例如删除给定函数、在一段代码周围添加 if 条件、添加不执行任何操作的新函数声明等。
修改应该在解析树上完成,因此只有通过修改才能恢复原始代码。
我什至不需要语言来关联解析器或实现,我所需要的只是语言本身的描述,无论是作为 BNF 语法还是非正式的。

我知道 PHP 提前编译器 phc 能够将源代码转换为 XML 表示形式并返回,从而更容易修改和恢复代码。 我需要的是一种描述对 XML 的实际修改的方法,以便我可以运行一个程序,例如可以删除特定函数调用的所有实例,或者在每个实例周围添加 if(false)。 此外,如果语言与语言无关,那就更好了,尽管这不是必需的。

你认为这样的事情存在吗?

【问题讨论】:

  • 您在这里使用了两种语言,我无法理解哪个是哪个,它会导致奇怪的短语,例如“如果该语言与语言无关”。请尝试在您要运行的软件之间进行更多分离来描述这一点,以更改您正在运行的软件。
  • 这两种语言是描述修改的语言和要修改的源代码的语言。我在任何地方使用语言这个词都是指前者,除了与语言无关的位,这意味着语言(前者)不应该关心源代码的语言(后者)。
  • 如果您坚持使用 XML 表示的代码,那么 XSLT 将是您理想的“与语言无关”的答案。您会发现,您必须 a) 说出与语言相关的内容,并且 b) 在 XSLT 中说出与语言相关的更改并不是很方便。您最大的希望是“源到源”程序转换引擎,它可以帮助您在很大程度上避免学习 AST 的纳米级细节,并允许您根据您打算修改的语言来说明更改。

标签: automation program-transformation


【解决方案1】:

查看 Semantic Designs 的 DMS software reengineering toolkit。它可以用于您正在寻找的东西。

【讨论】:

  • 我不怀疑我可以使用它,但是作为一个试图写硕士论文的学生,我没有钱购买这样的软件,我找不到地方他们免费提供该语言的地方。
  • 你应该研究更好的东西!依靠你的硕士论文来完成你想要达到的一切的商业软件无论如何不会给你带来学位;-)
  • 如果我要在我已经研究的基础上研究它,我应该得到的不是一个而是两个学位! =P 我只是需要该语言作为我正在设计的更大架构中的一个小组件使用,如果我找不到它,我将不得不在解释该组件如何工作时更加抽象。不过还是谢谢!
【解决方案2】:

关键思想是program transformations。 Ondrej 对 DMS 的想法是正确的,但我是 DMS 的作者,所以我可能有偏见。

用于完成转换的 DMS 语言称为“(DMS)规则规范语言”或 RSL,用于指定(程序转换)规则。这样的规则有:

  • 一个名字(我们往往有很多,这是一种方便的方式来引用它们)
  • 参数(定义模式变量),根据感兴趣的目标语言语法键入,
  • 左手“匹配这个”模式
  • 右手“用这个替换”模式

模式通常用目标语言的surface-syntax 编写,即被转换的语言的本机语法,带有模式变量的扩展。区分 目标语言的 RSL 语言语法,模式写在(元)引号“...”内。模式中的 \ 字符是(元)转义回 RSL。模式变量写成“\x”。一个(元)函数 foobar 写为 \foobar( ... ),注意 (meta)functions 参数上的 (meta)escape。在引号之外,还需要元转义,并且这些构造不带 \,例如 foobar(...)。

DMS 规则可能比这复杂得多,但这些是基础。表面句法模式不代表文本;相反,它们实际上代表了模式中代码的等效 AST。 DMS 规则用于匹配和更改 AST。程序转换系统当然必须有解析器来生成 AST,以及反解析器(“prettyprinters”)来将 AST 转换回文本。 (DMS 有一个庞大的语言前端库,涵盖了地球上所有广泛使用的语言和许多不常见的语言;我们刚刚添加了 MUMPS)。

对于您的具体示例,以下规则可以解决问题:

“...删除给定的功能”:

rule remove_function(f:IDENTIFIER,p:parameters,b:body): declarations -> declarations
  "  \f \p \b " -> " ; "  -- replace function delcaration by empty declation
  if f==target_function_name();

...在代码块周围添加 if 条件:

rule wrap_in_if(s:statement): statement -> statement
 " \s " ->  " \if ( \generated_condition\(\) ) \s ";

...添加一个什么都不做的新函数声明:

rule insert_noop_function(d:declarations): delcarations -> declarations
" \d " -> " \target_function\name\(\) ( )  { } ";

正如你所观察到的,你必须指出这些地方;这是一个“元程序”的工作,它定位你希望在 AST 中应用规则的位置,然后应用它们。对于您的规则,您需要(使用 DMS)和明确的程序方法来找到正确的位置。对于某些 DMS 规则,您可以简单地应用然后“无处不在”; DMS 基本上会遍历指定的 AST 并为您应用规则。

几条规则永远不会让人印象深刻,就像几行代码并不令人印象深刻一样。几百或几千条规则可以做非常壮观的事情(比如完整的语言翻译),就像几百或几千行代码可以产生非常有趣的结果一样。不同之处在于,传统代码使用数字、字符串和结构,而程序转换工具通过程序结构 (AST) 进行计算。

有一个complete worked example 展示了如何为 DMS 定义一种语言和规则,以及如何应用这些规则来实现“程序修改”(该示例实际上修改了“代数表达式”,但想法完全相同)。

DMS 毫不掩饰的商业化,它不是一个 dimestore 工具,所以它可能不是你的论文所需要的。

如果不是 DMS,您可以获得具有相同想法的免费工具。考虑 TXL (www.txl.ca) 或 StrategoXt (www.strategoxt.org)。 DMS、TXL、Stratego 都使用表面语法模式进行程序转换,但 TXL 和 Stratego 无法像 DMS 恕我直言一样处理代码的大量更改。 (出于某些原因,请阅读 DMS 网站上的流量分析)。不过,TXL 和 Stratego 非常适合学习基础知识和构建强大的演示。

【讨论】:

  • 太好了,这正是我想要的!我会尝试在我的论文中应用它,我不需要让它工作,我只需要它如何工作的例子,所以这就足够了!谢谢! (我会支持你,但我还没有足够的声誉=P)
猜你喜欢
  • 2013-06-22
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多