5

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

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

我发现具有挑战性的一个领域是想出一些技术来确保手写源文件和计算机生成的目标文件都清楚地缩进以帮助调试这两个目标似乎经常相互竞争。

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

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

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


编辑:我接受至少有三个论点不费心生成漂亮的 HTML 代码:

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

我当然有时会生成代码而不考虑缩进(尤其是 SQL)。

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

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

例如,考虑以下代码:

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

它比下面的代码更清楚:

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

但是,由于 HTML 中包含空格,它也具有不同的呈现方式。

4

8 回答 8

4

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

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

于 2008-10-20T01:08:16.127 回答
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 编码中失败了,所以我正在寻找其他类似的想法。]

于 2008-10-20T01:04:20.533 回答
3

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

于 2008-10-20T01:08:46.437 回答
2

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

于 2008-10-20T01:59:03.700 回答
1

我同意奇思妙想的回答。

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

于 2008-10-20T01:11:33.390 回答
1

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

于 2008-10-20T01:21:22.167 回答
0

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

您花费大量时间传递缩进参数,并试图弄清楚您的嵌套深度等等。除了一般浪费时间(因为最终渲染输出没有区别),当您添加其他 HTML 标记并将页面包装在 div 等中时,您如何维护所有这些内容?

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

于 2008-10-20T01:21:51.853 回答
0

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

于 2008-10-20T12:34:53.883 回答