erl_pp module provides this functionality. The only complicated thing is that it expects to deal with intermediate Erlang forms, such as those produced by the erl_parse module. Of course, the erl_parse module wants to deal with lexically-scanned tokens, such as those produced by the erl_scan module. Consequently, taking a chunk of badly-formatted Erlang code and generating beautiful output is generally a three-step process.
1> Badly_formatted = "fib(0) -> 1;fib(1) -> 1;fib(N) -> fib(N-2) + fib(N-1).".
"fib(0) -> 1;fib(1) -> 1;fib(N) -> fib(N-2) + fib(N-1)."
2> {ScanStatus, Scanned_Badly_Formatted, ScanCount} =
2> erl_scan:string(Badly_formatted).
{ok,[{atom,1,fib},
{'(',1},
{integer,1,0},
{')',1},
{'->',1},
{integer,1,1},
{';',1},
{atom,1,fib},
{'(',1},
{integer,1,1},
{')',1},
{'->',1},
{integer,1,1},
{';',1},
{atom,1,fib},
{'(',1},
{var,1,'N'},
{')',1},
{'->',1},
{atom,1,fib},
{'(',1},
{var,1,'N'},
{'-',1},
{integer,1,2},
{')',1},
{'+'|...},
{...}|...],
1}
3> {ParseStatus,Parsed_Badly_Formatted} =
3> erl_parse:parse_form(Scanned_Badly_Formatted).
{ok,{function,1,
fib,
1,
[{clause,1,[{integer,1,0}],[],[{integer,1,1}]},
{clause,1,[{integer,1,1}],[],[{integer,1,1}]},
{clause,1,
[{var,1,'N'}],
[],
[{op,1,
'+',
{call,1,{atom,1,fib},[{op|...}]},
{call,1,{atom,1|...},[{...}]}}]}]}}
4> Pretty_Form = erl_pp:form(Parsed_Badly_Formatted).
[[[["fib","(",["0"],")"],[],[" ->","\n ","1"]],
[";\n",[["fib","(",["1"],")"],[],[" ->","\n ","1"]]],
[";\n",
[["fib","(",[["N"]],")"],
[],
[" ->",
"\n ",
[["fib","(",[[["N"]," - ","2"]],")"],
" + ",
["fib","(",[[["N"]," - ","1"]],")"]]]]]],
".\n"]
5> io:fwrite("~s", [Pretty_Form]).
fib(0) ->
1;
fib(1) ->
1;
fib(N) ->
fib(N - 2) + fib(N - 1). |
pretty_print(BadStr) ->
{ScanStatus, Scanned_Badly_Formatted, ScanCount} =
erl_scan:string(Badly_formatted),
{ParseStatus,Parsed_Badly_Formatted} =
erl_parse:parse_form(Scanned_Badly_Formatted),
erl_pp:form(Parsed_Badly_Formatted).
1> io:fwrite("~s", [pretty_print(
"fib(0) -> 1;fib(1) -> 1;fib(N) -> fib(N-2) + fib(N-1).")]).
fib(0) ->
1;
fib(1) ->
1;
fib(N) ->
fib(N - 2) + fib(N - 1).
ok |
pretty_print function that would allow us to control formatting, such as the desired columns width, perhaps a maximum level to parse, etc.
In fact, it appears someone has already done so. Richard Carlsson (a member of the HIPE Project) has written a number of tools for parsing and manipulating Erlang text. His edoc package appears to support everything you could possibly want with respect to pretty printing.
-- BrentAFulgham - 22 Aug 2004
| CookbookForm | |
|---|---|
| TopicType: | Recipe |
| ParentTopic: | StringRecipes |
| TopicOrder: | 190 |