me gustaría convertir una cadena que contiene una expresión válida de Erlang a su representación abstracta árbol de sintaxis, sin ningún éxito hasta el momento.cadena de árbol de sintaxis abstracta
A continuación se muestra un ejemplo de lo que me gustaría hacer. Después de compilar, Alling z:z().
genera módulo zed
, que llamando zed:zed().
devuelve el resultado de aplicar lists:reverse
en la lista dada.
-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
podría ser "[1,2,3]."
o "begin A=4, B=2+3, [A,B] end."
, ni nada parecido.
(Tenga en cuenta que esto es sólo un ejemplo de lo que me gustaría hacer, por lo que la evaluación de String
no es una opción para mí.)
EDITAR:
Especificación ListAST de la siguiente genera un enorme monstruo dict-digraph-error-monstruo, y dice "error interno en lint_module".
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
Edit2:
Esta solución funciona para términos simples:
{ok, Ts, _} = erl_scan:string(String),
{ok, Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term),
Ahora que miro el código, obviamente, mezclando erl_syntax y formatos erl_parse ... todavía no puede encontrar la manera de hacer esto, sin embargo (típico exceso de error bejgli). – Zed
Sí, si compara su ListAST con una hecha por erl_syntax, no se ven igual :( 42> ListAST. [{Cons, 1, {integer, 1,1}, {cons, 1, {integer, 1,2}, {nil, 1}}}] 43> erl_syntax: list ([1, 2, 3], []). {tree, list, {attr, 0, [], none}, {list , [1,2,3], []}} 44> –
Así que, o necesito una forma de hacer una AST compatible con 'erl_syntax' fuera de la cadena, o una forma de poner un marcador de posición a las cosas 'erl_syntax', y reemplácelo después de llamar a 'revert()'. O me falta algo obvio ... – Zed