使用Python的漂亮打印Lisp

时间:2015-10-24 20:42:18

标签: python lisp pretty-print s-expression

有没有办法在Python中漂亮地打印Lisp风格的代码字符串(换句话说,一堆平衡的括号和文本)而无需重新发明轮子?

2 个答案:

答案 0 :(得分:1)

简短回答

如果可以的话,我认为合理的方法是生成Python列表或自定义对象而不是字符串,并使用pprint模块,如@saulspatz所示。

答案很长

整个问题看起来像是XY-problem的一个实例。为什么?因为你正在使用 Python (为什么不是Lisp?)来操纵字符串(为什么不是数据结构?)来表示生成的 Lisp风格的代码,其中 Lisp风格的被定义为""中的一堆括号和文本。 对于问题"如何漂亮?",我会回复"I wouldn't start from here!"。 除了使用现有的轮子之外,不用重新发明轮子的最佳方法是坚持使用简单的输出格式。

但首先,为什么你需要漂亮的印刷品吗?谁会查看生成的代码?

根据您使用的确切Lisp方言以及代码的预期用法,您可以非常不同地格式化代码。例如,考虑文本的换行符,缩进和最大宽度。 Common Lisp pretty-printer是特别发展的,我怀疑你想要具有相同级别的可配置性。     如果您使用Lisp,只需调用pprint即可解决您的问题,但您使用的是Python,因此暂时坚持使用最合理的输出,因为漂亮的打印是一种蠕虫。

如果您的代码适用于人类读者,请:

  • 不要在自己的行上加上右括号
  • 不要垂直对齐左括号
  • 不要在左括号之间添加空格

这太丑了:

 ( * ( + 3 x )
     (f 
        x
        y
     )
 )

这样更好:

(* (+ 3 x)
   (f x y))

或者简单地说:

(* (+ 3 x) (f x y))

See here了解详情。

但在打印之前,您必须解析输入字符串并确保其格式正确。由于你如何生成表单,也许你确定它是格式良好的,但我认为打印机应该忽略它而不是做太多的假设。如果你通过漂亮的打印机传递一个由Python对象代表的AST而不仅仅是字符串,这将更容易,如评论中所建议的那样。您可以构建数据结构或自定义类并使用pprint(python)模块。如上所述,如果您可以更改生成Lisp样式代码的方式,那么这似乎是您的理由。

对于字符串,您应该处理任何可能的输入并拒绝无效的输入。 这意味着检查括号和引号是否平衡(小心转义字符)等。 实际上,你并不需要来真正构建一个用于打印的中间树(尽管它可能有助于程序的其他部分),因为Lisp风格的代码由易于嵌套的表单组成,并使用前缀表示法:您可以从左到右扫描输入字符串,并在查看括号时打印(打开括号:recurse;关闭括号,从递归返回)。当您第一次遇到未转义的双引号"时,请阅读下一个",... 这与简单的印刷方法相结合,足以满足您的需求。

答案 1 :(得分:0)

我认为最简单的方法是使用三引号。如果你说:

print """
    (((This is some lisp code))) """

它应该工作。 你可以在三重引号中以任何你喜欢的方式格式化你的代码,它会以你想要的方式出现。

祝你好运,编码愉快!