缩进代码生成

时间:2008-10-20 01:01:44

标签: php code-generation metaprogramming

通常,程序员编写生成其他代码的代码。

(技术术语是metaprogramming,但它比仅仅交叉编译器更常见;想想生成HTML或每个XSLT文件的每个PHP网页。)

我发现一个具有挑战性的领域是提出确保两者手写源文件的技术,并且计算机生成的目标文件显然缩进以帮助调试。这两个目标似乎经常竞争。

我发现这在PHP / HTML组合中尤其具有挑战性。我认为那是因为:

  • 源文件中的HTML代码有时比生成PHP
  • 更多
  • HTML文件往往比SQL语句更长,需要更好的缩进
  • HTML具有对空间敏感的功能(例如标签之间)
  • 结果是公开可见的HTML而不是SQL语句,因此要做更合理的工作会有更大的压力。

您使用什么技术来解决这个问题?

<小时/> 编辑:我接受至少有三个参数不打扰生成漂亮的HTML代码:

  • 生成代码的复杂性增加。
  • 浏览器渲染没有区别;开发人员可以使用Firebug或类似功能来很好地查看它。
  • 轻微的性能损失 - 增加了空格字符的下载时间。

我当然有时会在不考虑缩进(特别是SQL)的情况下生成代码。

然而,有一些论点推动了另一种方式:

  • 在实践中,我发现我经常阅读生成的代码 - 有额外的步骤来访问它是不方便的。
  • HTML有一些空间敏感度问题,偶尔会有一些问题。

例如,考虑代码:

<div class="foo">
    <?php
        $fooHeader();
        $fooBody();
        $fooFooter();
    ?>
</div>

比以下代码更清晰:

<div class="foo"><?php
        $fooHeader();
        $fooBody();
        $fooFooter();
?></div>

但是,由于HTML中包含空格,它也有不同的渲染。

8 个答案:

答案 0 :(得分:4)

在更一般的情况下,我编写了生成C ++数据库接口代码的XSLT代码。虽然起初我试图从XSLT输出正确的缩进代码,但很快就变得站不住脚了。我的解决方案是完全忽略XSLT输出中的格式化,然后通过GNU indent运行生成的很长的代码行。这产生了一个适合调试的格式合理的C ++源文件。

我可以想象在处理HTML和PHP等组合源时问题变得更加棘手。

答案 1 :(得分:3)

当生成代码超过生成的代码时,我使用的一种技术是传递一个缩进参数。

例如,在Python中,生成更多的Python。

def generateWhileLoop(condition, block, indentPrefix = ""):
    print indentPrefix + "while " + condition + ":"
    generateBlock(block, indentPrefix + "    ")

或者,取决于我的心情:

def generateWhileLoop(condition, block, indentLevel = 0):
    print " " * (indentLevel * spacesPerIndent) + "while " + condition + ":"
    generateBlock(block, indentLevel + 1)

请注意假设condition是一条适合同一行的短文本,而block位于单独的缩进行中。如果此代码无法确定子项是否需要缩进,则此方法开始减少。

此外,这种技术对于将相对少量的PHP喷洒到HTML中并不是那么有用。

[编辑澄清:我写了这个问题,也是这个答案。我想用我使用过的一种技术来解决问题并且有时很有用,但这种技术使我无法进行典型的PHP编码,因此我正在寻找其他类似的想法。]

答案 2 :(得分:3)

生成一个AST然后遍历它并发出格式正确的源代码。

答案 3 :(得分:2)

我发现在生成过程中忽略缩进是最好的。我编写了一个通用的“代码格式化”引擎,后处理了所有输出的代码。这样,我可以从生成器中单独定义缩进规则和代码语法规则。这种分离有明显的好处。

答案 4 :(得分:1)

我同意奇怪的回答。

有时最好通过反转来解决问题。如果您发现自己生成了大量文本,请考虑使用少量智能生成代码将文本编写为模板是否更容易。或者,如果您可以将问题分解为一系列您组装的小模板,然后将每个模板整体缩进。

答案 5 :(得分:1)

使用PHP制作网站,我发现混合了HTML和功能特定的PHP问题,它限制了概述并使调试更难。在这种情况下避免混合的解决方案是使用模板驱动的内容,例如see Smarty。除了更好的意图,内容的模板对于其他事情是有用的,例如,更快的修补。如果客户需要更改布局,则可以快速找到并修复该特定布局问题,而无需使用生成数据的功能性PHP代码(以及相反的方式)。

答案 6 :(得分:0)

特别是关于HTML生成 - 为什么重要?

你花了很多时间绕过缩进参数,并试图找出你的嵌套程度等等。除了浪费时间之外(因为最终渲染没有差异)如何在div中添加其他HTML标记和包装页面时如何维护所有这些内容?

无论如何,安装Firebug(以及IE developer toolbar以后用于测试IE)并且它们都以嵌套格式显示HTML,并且您只需单击页面元素即可直接查看标记 - 比查看原始源HTML输出更有效。

答案 7 :(得分:0)

我的PHP / HTML情况我试图让每个代码片段在源代码中始终缩进。这使得代码在真正重要的地方保持可读,并且通常具有产生可读的HTML输出的副作用。正如其他人所说,萤火虫照顾其余部分。