Ich möchte einen String, der einen gültigen Erlang-Ausdruck enthält, in seine abstrakte Syntaxbaumdarstellung konvertieren, bisher jedoch ohne Erfolg.String zum abstrakten Syntaxbaum
Unten ist ein Beispiel, was ich gerne machen würde. Nach dem Kompilieren generiert alling z:z().
das Modul zed
, das durch Aufruf von zed:zed().
das Ergebnis der Anwendung lists:reverse
auf die angegebene Liste zurückgibt.
-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
konnte gleich "[1,2,3]."
oder "begin A=4, B=2+3, [A,B] end."
, oder irgendetwas sein.
(Beachten Sie, dass dies nur ein Beispiel dafür, was Ich mag, so zu tun, würde String
Bewertung ist keine Option für mich.)
EDIT:
Angeben ListAST wie unten erzeugt ein riesiges Dict-Digraph-Fehler-Monster und sagt "interner Fehler in lint_module".
String = "[1,2,3].",
{ok, Ts, _} = erl_scan:string(String),
{ok, ListAST} = erl_parse:parse_exprs(Ts),
EDIT2:
Diese Lösung funktioniert für einfache Worte:
{ok, Ts, _} = erl_scan:string(String),
{ok, Term} = erl_parse:parse_term(Ts),
ListAST = erl_syntax:abstract(Term),
Jetzt, wo ich den Code anschauen, mischen ich natürlich bis erl_syntax und erl_parse Formate ... immer noch nicht herausfinden können, wie dies aber tun (typisch zu viel bejgli Fehler). – Zed
Ja, wenn Sie Ihre ListAST mit der von erl_syntax vergleichen, sehen sie nicht gleich aus :( 42> ListAST. [{Cons, 1, {integer, 1,1}, {cons, 1, {integer, 1,2}, {nil, 1}}}] 43> erl_syntax: list ([1, 2, 3], []). {Baum, Liste, {attr, 0, [], none}, {list , [1,2,3], []}} 44> –
Also muss ich entweder einen 'erl_syntax' kompatiblen AST aus der Zeichenkette machen oder einen Platzhalter für' erl_syntax' verwenden, und ersetze es nach dem Aufruf von 'revert()'. Oder ich vermisse etwas Offensichtliches ... – Zed