使用 m4 进行预处理

Pre-Processing using m4

我正在使用 m4. I was reading the thread at Whosebug here and from there reached a blog 为 Free-Pascal(课程作业)编写一个预处理器,它基本上展示了 m4 用于 C 预处理的基本用法。博主使用这样的测试 C 文件 test.c.m4

#include 

define(`DEF', `3')

int main(int argc, char *argv[]) {
        printf("%d\n", DEF);
        return 0;
}

并使用 m4 生成处理过的 C 文件,这很好。

$ m4 test.c.m4 > test.c
$ cat test.c
#include <stdio.h>



int main(int argc, char *argv[]) {
    printf("%dn", 3);
    return 0;
}

我的疑惑是:
1.程序员将在行

处编写代码
    define(`DEF', `3')

将是

    #define DEF 3

那谁把这行转换成上面那行呢?我们可以使用像 sedawk 这样的工具来做同样的事情,但是 m4 有什么用呢? m4 所做的事情也可以使用 sed 来实现。
如果有人能告诉我如何将程序员的代码转换成可供 m4.

使用的文件,那将非常有帮助 2. 我在使用 m4 时遇到了另一个问题。 C 等语言的注释在预处理之前被删除,所以可以使用 m4 来完成吗?为此,我在 m4 中寻找可以使用正则表达式替换注释的命令,我找到了 regexp(),但它需要将字符串替换为在这种情况下不可用的参数。那么如何实现呢?

对不起,如果这是一个天真的问题。我阅读了 m4 的文档,但找不到解决方案。

    在这种情况下,
  1. m4 是将 DEF 转换为 3 的工具。 sedawk 确实可以为这个简单的案例提供相同的目的,但 m4 是一个更强大的工具,因为它 a) 允许参数化宏,b) 包含条件, c) 允许通过输入文件重新定义宏,等等。例如,可以写(在文件 for.pas.m4 中,受 ratfor 启发):
define(`LOOP',`for  := 1 to  do
begin')dnl
define(`ENDLOOP',`end')dnl

LOOP(i,10)
  WriteLn(i);
ENDLOOP;

... 当由 m4 for.pas.m4 处理时,它会为 Pascal 编译器生成以下输出:

for i := 1 to 10 do
begin
        WriteLn(i);
end;
  1. 使用 m4 删除一般的 Pascal 注释是不可能的,但是创建一个宏来包含一个 在处理过程中被 `m4' 删除的注释是很简单的:
define(`NOTE',`dnl')dnl
NOTE(`This is a comment')
      x := 3;

... 产生:

    x := 3;

可以将 m4 扩展的常用宏放在一个通用文件中,该文件可以包含在任何使用它们的 Pascal 文件的开头,从而无需定义所有必需的每个 Pascal 文件中的宏。请参阅 m4 manual 中的 include (file)