如何更改“-define” Erlang 属性(宏定义)的值?

4

普通的Erlang属性可以通过解析转换进行修改。这不适用于“-define”属性,因为它们由预处理器处理。如果您想要更改所有宏的值而不更改文件本身,该怎么办?

理想情况下,我希望调用一些修改后的编译器,它会产生以下效果:

当输入运行时...

...
-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个回答

3
正常编译器无法提供包含预处理宏的语法树。如您所知,在源代码被传送到解析器之前,宏是由预处理器扩展的。 有一种方法可以获得伪解析树(erl_parse返回的正常解析树无法表示宏):使用模块epp_dodger。 epp_dodger - 跳过Erlang预处理器。该模块对大多数Erlang源代码进行标记化和解析,而不会扩展预处理指令和宏应用,只要这些语法上符合规范。因为erl_parse模块的正常解析树无法表示这些内容(通常在解析器看到它们之前,它们已经被Erlang预处理器epp(3)扩展了),因此创建了一个扩展语法树,使用erl_syntax模块。 但是,这不能集成到解析转换中。

但是,如果您需要,您可以自由查阅语法树并将结果提供给编译器。仅需对代码进行推理,解析树和Erlang Syntax Tools就足够了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接