2011-09-16 20 views
3

正常的Erlang属性可以通过解析转换来修改。这不适用于“-define”属性,因为它们是由预处理器处理的。如果你想改变所有宏的值而不改变文件本身,你会怎么做?如何更改“-define”Erlang属性(宏定义)的值?

理想我想打电话给这会带来以下影响编译器的一些修改的版本:

当输入运行...

... 
-define(constant, 45). 
-define(debug(X), io:format(X)). 
... 
    ?debug(?constant) % Line: 7 
... 

..和参数...

something:external 

结果将是一些抽象的形式代替其...

{call,7, 
     {remote,7,{atom,7,io},{atom,7,format}}, 
     [{integer,7,45}]} 

...将有:

{call,7, 
     {remote,7,{atom,7,something},{atom,7,external}}, 
     [{call,7, 
      {remote,7,{atom,7,something},{atom,7,external}}, 
      []}]} 

当然生成的代码可能不会是可执行的,但可以启用宏的使用一些“质量”分析。

回答

1

与包括预处理宏语法树不能被正常编译来提供。 正如您所注意到的,在源被送入解析器之前,宏由预处理器扩展。

有一种方式来获得一个伪解析树(由erl_parse返回不能代表宏正常解析树):使用模块epp_dodger

epp_dodger - 绕过Erlang的预处理器。

此模块tokenises并解析最二郎源代码,而无需扩大预处理器指令和宏的应用程序,只要这些在语法“乖”。因为erl_parse模块不能代表这些东西的正常解析树(通常情况下,它们被二郎神预处理epp(3)解析器看到他们之前展开),扩展语法树被创建,使用erl_syntax模块。

然而,这不能被集成在解析变换。

但你可以仔细阅读语法树,只要你喜欢,并将结果馈送到编译器,如果你需要这个。为了推理代码树和Erlang Syntax Tools都是你需要的。