我想把一个包含有效 Erlang 表达式的字符串转换为其抽象语法树表示形式,但到目前为止都没有成功。
下面是我想要做的示例。编译后,调用
下面是我想要做的示例。编译后,调用
z:z().
生成模块 zed
,通过调用 zed:zed().
返回对给定列表应用 lists:reverse
的结果。-module(z).
-export([z/0]).
z() ->
ModuleAST = erl_syntax:attribute(erl_syntax:atom(module),
[erl_syntax:atom("zed")]),
ExportAST = erl_syntax:attribute(erl_syntax:atom(export),
[erl_syntax:list(
[erl_syntax:arity_qualifier(
erl_syntax:atom("zed"),
erl_syntax:integer(0))])]),
%ListAST = ?(String), % This is where I would put my AST
ListAST = erl_syntax:list([erl_syntax:integer(1), erl_syntax:integer(2)]),
FunctionAST = erl_syntax:function(erl_syntax:atom("zed"),
[erl_syntax:clause(
[], none,
[erl_syntax:application(
erl_syntax:atom(lists),
erl_syntax:atom(reverse),
[ListAST]
)])]),
Forms = [erl_syntax:revert(AST) || AST <- [ModuleAST, ExportAST, FunctionAST]],
case compile:forms(Forms) of
{ok,ModuleName,Binary} -> code:load_binary(ModuleName, "z", Binary);
{ok,ModuleName,Binary,_Warnings} -> code:load_binary(ModuleName, "z", Binary)
end.
String
可以是"[1,2,3]."
, 或者"begin A=4, B=2+3, [A,B] end."
, 或者类似的其他内容。
(请注意,这只是一个我想要做的示例,所以对String
进行评估对我来说不是一个选项。)
编辑:
指定ListAST如下会生成一个巨大的字典-图错误怪物,并显示“lint_module中的内部错误”。
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
编辑2:
这个解决方案适用于简单的术语:
{ok, Ts, _} = erl_scan:string(String),
{ok, Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term),