我已经实现了一台漂亮的打印机,它在复杂的语法树上运行良好。由于语法很复杂,有时会给出statement
或expression
,因此有助于打印构造函数以了解它们的结构。为此,我添加了一个参数constructor_print
。如果此变量为false,则通常会打印statement
或expression
;否则,所有相关的构造函数都以良好的顺序打印。这是代码的一小部分(实际上有很多函数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) =
...
...
例如,3 + (-2)
被解析为表达式e
。当!constructor_print
为假时。 pp_e stdout e
返回3 + (-2)
;否则pp_e stdout e
返回
ADD_E_E (
Int 3,
PARENTHESIZED_E UMINUS_E INT 2)
然而,问题是,我想在必要时打印缩进以使其更具可读性。例如,我希望以前的输出可能是:
ADD_E_E (
INT 3,
PARENTHESIZED_E UMINUS_E INT 2)
规则很简单:当有一对(或三个或更多)构造函数(例如ADD_E_E
)时,它会为其参数打印一个新行,每行有另外两个缩进空格;如果有一元制的医生(例如UMINUS_E
),则不会打印新行。
几乎所有的行都有Printf.fprintf chan (tercs ... ...) ...
结构,因为它们很多,我真的需要以巧妙的方式自动化缩进。
我想到的一种方法是使用一个ref变量i
来表示当前缩进的空格数。我们在i := !i+2
之前和之后合并了i := !i-2
和Printf.fprintf chan (tercs ... ...)
。我们还需要修改tercs
返回的格式:一旦有\n
,我们会在i
之后添加\n
个空格。
但我也听说过box
模块提供的hint
,Format
等。有没有人了解它们,我的请求有更直接的解决方案吗?
答案 0 :(得分:1)
您可以将一个整数参数传递给您的函数,这将填充您应该在每行开头写入的空格数。如果你要做一些递归调用,应该增加这个值。