%%% Takes a prolog source file on standard input, % writes its AST to standard output, % as a Scheme literal s-expression % (with minimal formatting, rest left to Scheme). % % SWI's read_term renames identifiers to be unique by term. % The AST is written as a list of pairs of renamings and term: % '( % ( ( (= ) ... ) % ) % ... % ) % % Works with SWI Prolog 5.6.35. % % E.g. parsing itself, on the CDF machines: % pl -s pl2sexp < pl2sexp % % More robust escaping of special characters needs work. % Some experimentation. % functor(X, F, A), X =.. Flat, write(F), nl, write(A), nl, write(Flat), nl. % term_expansion(X,X) :- sexp(X), fail. % Display helper. % emit_token(Token) :- writef(Token), writef(" "). %% Leaves. % sexp(Var) :- var(Var), !, write(Var), writef(" "). % % Escape some common tokens special to Scheme reader. % sexp('.') :- !, emit_token("\\."). sexp(';') :- !, emit_token("\\;"). % sexp(Atom) :- atom(Atom), emit_token(Atom). sexp(Number) :- number(Number), emit_token(Number). % sexp(String) :- string(String), write_term(String,[quoted(true)]). %% Internal nodes. % sexp(Compound_term) :- compound(Compound_term), Compound_term =.. List_of_terms, writef("("), maplist(sexp, List_of_terms), writef(")"). %% Main loop to read stream of terms. % r :- at_end_of_stream, !, writef(")"), nl, halt. r :- read_term(X,[double_quotes(string),variable_names(Vs)]), writef("(("), maplist(sexp, Vs), writef(")"), nl, sexp(X), writef(")"), nl, r. %% Suppress prompt, read. % ?- prompt(_,' '), writef("'("), nl, r, !.