【问题标题】:How to get AST (Abstract Syntax Tree) of an Erlang local fun?如何获得 Erlang 本地乐趣的 AST(抽象语法树)?
【发布时间】:2018-09-10 14:22:00
【问题描述】:

对于某些 Erlang 术语,例如 atomtuplelist,我可以使用 erl_parse:abstract/1 获取 AST。但它不适用于funs。

~ $ erl
Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V8.0  (abort with ^G)

1> erl_parse:abstract(foo).
{atom,0,foo}

2> erl_parse:abstract([bar]).
{cons,0,{atom,0,bar},{nil,0}}

3> erl_parse:abstract({baz}).
{tuple,0,[{atom,0,baz}]}

4> erlang:fun_info(fun() -> ok end, type).
{type,local} % So this is a local fun

5> erl_parse:abstract(fun() -> ok end).       
** exception error: no function clause matching 
                    erl_parse:abstract(#Fun<erl_eval.20.52032458>,0,
                                       #Fun<erl_parse.3.3133389>) (erl_parse.yrl, line 1330)

我知道一些本地funs 在他们的信息中有他们的 AST。但这并不适用于所有本地funs。

~ $ erl
Erlang/OTP 19 [erts-8.0] [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V8.0  (abort with ^G)

1> erlang:fun_info(fun() -> ok end, env).
{env,[{[],
       {eval,#Fun<shell.21.31625193>},
       {value,#Fun<shell.5.31625193>},
       [{clause,1,[],[],[{atom,1,ok}]}]}]} %% Here

2> foo:test(). %% Yields a fun
#Fun<foo.0.10202683>

3> erlang:fun_info(foo:test(), type).
{type,local} %% So this is a local fun too

4> erlang:fun_info(foo:test(), env). 
{env,[]} %% : (

获取外部fun 的 AST 并不难。我的解决方案是加载其模块梁块并获取该功能的 AST。如果您有更好的解决方案,请告诉我。主要问题是获取本地 funs 的 AST。

【问题讨论】:

    标签: erlang abstract-syntax-tree erlang-otp object-code


    【解决方案1】:

    erl_parse:abstract/1 不能接受函数对象作为参数。我认为你是对的。

    【讨论】:

    • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
    【解决方案2】:

    也许你也可以尝试结合erl_scan:string/1erl_parse:parse_exprs/1,例如:

    1> Fun = "fun() -> ok end.".
    "fun() -> ok end."
    2> {ok, Tokens, _EndLocation} = erl_scan:string(Fun).
    {ok,[{'fun',1},
         {'(',1},
         {')',1},
         {'->',1},
         {atom,1,ok},
         {'end',1},
         {dot,1}],
        1}
    3> {ok, ExprList} = erl_parse:parse_exprs(Tokens).
    {ok,[{'fun',1,{clauses,[{clause,1,[],[],[{atom,1,ok}]}]}}]}
    

    希望,这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      相关资源
      最近更新 更多