ciąg do abstrakcyjnego drzewa składni
Chciałbym przekonwertować łańcuch zawierający poprawne wyrażenie Erlang na jego reprezentację drzewa składni abstrakcyjnej, bez żadnego dotychczasowego sukcesu.
Poniżej znajduje się przykład tego, co chciałbym zrobić. Po kompilacji, allingz:z().
generuje modułzed
, które dzwoniączed:zed().
zwraca wynik zastosowanialists:reverse
na podanej liście.
-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
możliwe"[1,2,3]."
lub"begin A=4, B=2+3, [A,B] end."
lub coś podobnego.
(Zauważ, że to tylko przykład tego, co chciałbym zrobić, więc oceniamString
nie jest dla mnie opcją.)
EDYTOWAĆ:
Określenie ListAST jak poniżej generuje ogromny potwór-błąd-dyktafon-błąd i mówi „błąd wewnętrzny w lint_module”.
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
EDIT2:
To rozwiązanie działa na prostych warunkach:
{ok, Ts, _} = erl_scan:string(String),
{ok, Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term),