【问题标题】:How to compile erlang code loaded into a string?如何编译加载到字符串中的erlang代码?
【发布时间】:2017-06-16 20:18:42
【问题描述】:

我有一个生成的字符串,其中包含 erlang 模块的代码。

有没有办法直接从字符串编译生成的模块?

或者有没有办法将字符串转换为compile:forms/1所需的格式?

还是我必须先将它保存到一个临时文件中,然后用compile:file/1 编译它?

另外,我可以添加对编译模块的支持,但是写erlang的好人没有添加它一定是有原因的。

【问题讨论】:

    标签: erlang compilation


    【解决方案1】:

    您需要将您的字符串扫描为标记,然后将标记解析为表单。 不幸的是,一次只能解析一个表单,因此您需要剪切字符串或表单边界处的标记。这是一个简短的例子:

    % create tokens from strings containing forms
    > {ok, MTs, _} = erl_scan:string("-module(z).").
    > {ok, ETs, _} = erl_scan:string("-export([f/0]).").
    > {ok, FTs, _} = erl_scan:string("f() -> hello_world.").
    % tokens to erl_parse trees
    > {ok,MF} = erl_parse:parse_form(MTs).
    > {ok,EF} = erl_parse:parse_form(ETs).
    > {ok,FF} = erl_parse:parse_form(FTs).
    
    % compile forms to binary
    > {ok, z, Bin} = compile:forms([MF,EF,FF]).
    {ok,z,<<70,79,82,49,0,0,1,164,66,69,65,77,65,116,111,109,0,0,0,...>>}
    
    % load module from binary
    > code:load_binary(z, "nofile", Bin).
    {module,z}
    
    % test
    > z:f().
    hello_world
    

    或者,您可以扫描您的字符串,然后将生成的令牌列表在{dot, _} 标记处分开。

    【讨论】:

    • 修正了错字。我想您可以将整个源代码放入一个字符串中,对其进行扫描,然后在每个 {dot, _} 处剪切令牌列表。
    • 另外,请注意包含不适用于此方法(请参阅:stackoverflow.com/questions/2013119/…
    • 正是我最终所做的,扫描了 {dot, _} :D
    • 不幸的是erl_parse需要拆分,erl_scan:string没有问题。我正在修复 yecc,它用于生成 erl_parse,因此它可以以合理的方式处理少量和过多的令牌。
    • 如果您需要对包含、ifdefs 和帮派的支持,请使用 Aleppo:github.com/evanmiller/aleppo
    【解决方案2】:

    将字符串的内容存储在带有模块名称的文件中(如果代码中没有)并使用 compile module 编译它。
    代码在 VM 中可用。我正在使用这种技术将配置文件转换为模块。这样在执行过程中不会发生太多的二进制副本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 2020-03-08
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      相关资源
      最近更新 更多