字符串到抽象语法树 [英] string to abstract syntax tree
问题描述
我想将一个包含有效的Erlang表达式的字符串转换为其抽象语法树表示,迄今没有任何成功。
下面是一个例子想做编译后,调用 z:z()。
生成模块 zed
,通过调用 zed :zed()。
返回在给定列表中应用列表的结果:reverse
。
- 模(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),%这是我将把我的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 (反向),
[Listast]
)])]),
Forms = [erl_syntax:revert(AST)|| AST< - [ModuleAST,ExportAST,FunctionAST]],
案例编译:
{ok,ModuleName,Binary} - >代码:load_binary(ModuleName,z,Binary);
{ok,ModuleName,Binary,_Warnings} - >代码:load_binary(ModuleName,z,Binary)
end。
String
可以是[1,2,3]。
或开始A = 4,B = 2 + 3,[A,B]结束。
或任何类似的东西。
(请注意,这只是我想做的一个例子,所以评估 String
不是我的选择。)
编辑:
如下所示指定ListAST生成一个巨大的字母 - 图 - 错误怪物,并说lint_module中的内部错误。
String =[1,2,3]。,
{ok,Ts,_} = erl_scan:string(String),
{ ListAST} = erl_parse:parse_exprs(Ts),
EDIT2 :
此解决方案适用于简单的术语:
code> {ok,Ts,_} = erl_scan:string(String),
{ok,Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term)
在您的EDIT示例中:
String =[1,2,3]。,
{ok,Ts,_} = erl_scan:string String),
{ok,ListAST} = erl_parse:parse_exprs(Ts),
ListAST实际上是一个AST:s的列表(因为parse_exprs,如名称所示,解析多个表达式(每个表达式以一个句点终止)。由于您的字符串包含单个表达式,因此您有一个元素的列表。所有你需要做的是匹配:
{ok,[Listast]} = erl_parse:parse_exprs(Ts),$所以它与erl_syntax(它接受所有的erl_parse树)无关; b $ b
这只是你在ListAST周围有一个额外的列表包装,导致编译器呕吐。
I would like to convert a string containing a valid Erlang expression to its abstract syntax tree representation, without any success so far.
Below is an example of what I would like to do. After compiling, alling z:z().
generates module zed
, which by calling zed:zed().
returns the result of applying lists:reverse
on the given list.
-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
could be "[1,2,3]."
, or "begin A=4, B=2+3, [A,B] end."
, or anything alike.
(Note that this is just an example of what I would like to do, so evaluating String
is not an option for me.)
EDIT:
Specifying ListAST as below generates a huge dict-digraph-error-monster, and says "internal error in lint_module".
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
EDIT2:
This solution works for simple terms:
{ok, Ts, _} = erl_scan:string(String),
{ok, Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term),
In your EDIT example:
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
the ListAST is actually a list of AST:s (because parse_exprs, as the name indicates, parses multiple expressions (each terminated by a period). Since your string contained a single expression, you got a list of one element. All you need to do is match that out:
{ok, [ListAST]} = erl_parse:parse_exprs(Ts),
so it has nothing to do with erl_syntax (which accepts all erl_parse trees); it's just that you had an extra list wrapper around the ListAST, which caused the compiler to puke.
这篇关于字符串到抽象语法树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!