的AST
对于某些erlang项,例如 atom
, tuple
, list
i可以使用 erl_parse:abstract/1
获得AST。但这对fun
s不起作用。
~ $ 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)
我知道某些本地fun
S在他们的信息中具有AST。但这并不适用于所有本地fun
s。
~ $ 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。如果您有更好的解决方案,请告诉我。主要问题是获取本地fun
s。
也许您也可以尝试组合erl_scan:string/1
和erl_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}]}]}}]}
希望,这会有所帮助。
erl_parse:Abstract/1不能接受函数对象为参数。我认为您在其余的地方。