我想将包含有效 Erlang 表达式的字符串转换为其抽象语法树表示,但到目前为止没有任何成功。
下面是我想做的一个例子。编译后,allingz: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 会生成一个巨大的 dict-digraph-error-monster,并显示“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),