Reputation: 5510
I have implemented a pretty printer which works quite well on a complex syntax tree. As the syntax is complicated, sometimes given a statement
or an expression
, it helps to print the constructors to understand their structure. To this end, I added a parameter constructor_print
. When this variable is false, a statement
or an expression
is normally printed; otherwise, all the related constructors are printed in a good order. Here is a very small part of code (there are actually lots of functions pp_...
):
let tercs s0 s1 =
if !constructor_print then
format_of_string s0
else
format_of_string s1
let pp_e (chan: out_channel) (e: expression) =
match e with
| ADD_E_E (e0, e1) ->
Printf.fprintf chan (tercs "ADD_E_E (\n%a,\n%a)" "%a + %a") pp_e e0 pp_e e1
| UMINUS_E e ->
Printf.fprintf chan (tercs "UMINUS_E %a" "- %a") pp_e e
| PARENTHESIZED_E e ->
Printf.fprintf chan (tercs "PARENTHESIZED_E %a" "(%a)") pp_e e
...
let pp_s (chan: out_channel) (s: statement) =
...
...
For instance, 3 + (-2)
is parsed to an expression e
. When !constructor_print
is false. pp_e stdout e
returns 3 + (-2)
; otherwise pp_e stdout e
returns
ADD_E_E (
Int 3,
PARENTHESIZED_E UMINUS_E INT 2)
However, the problem is, I would like to print indentation when necessary to make it more readable. For instance, I would hope the previous output could be:
ADD_E_E (
INT 3,
PARENTHESIZED_E UMINUS_E INT 2)
The rule is quite simple: when there is a pair (or triple or more) constructor (e.g. ADD_E_E
), it prints a new lines for its arguments, each line has another 2 spaces of indentation; when there is a unary constroctor (e.g. UMINUS_E
), it doesn't print new line.
Almost all the lines have this structure Printf.fprintf chan (tercs ... ...) ...
, as they are a lot, I really need to automatize the indentation in a clever way.
One way I think of is to have a ref variable i
which represents the number of the spaces of the current indentation. We incorporate i := !i+2
and i := !i-2
before and after Printf.fprintf chan (tercs ... ...)
. Also we need to modify the format returned by tercs
: once there is \n
, we add i
spaces after \n
.
But I have also heard of box
, hint
, etc. provided by Format
module. Does anyone know them well, and is there a more direct solution for my request?
Upvotes: 2
Views: 246
Reputation: 2839
You can pass an integer parameter to your functions which will incapsulate how many spaces you should write at the beginning of each line. If you will do some recursive call this value should be increased.
Upvotes: 1