使用 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
那谁把这行转换成上面那行呢?我们可以使用像 sed
或 awk
这样的工具来做同样的事情,但是 m4
有什么用呢? m4
所做的事情也可以使用 sed
来实现。
如果有人能告诉我如何将程序员的代码转换成可供 m4
.
使用的文件,那将非常有帮助
2. 我在使用 m4
时遇到了另一个问题。 C
等语言的注释在预处理之前被删除,所以可以使用 m4
来完成吗?为此,我在 m4
中寻找可以使用正则表达式替换注释的命令,我找到了 regexp()
,但它需要将字符串替换为在这种情况下不可用的参数。那么如何实现呢?
对不起,如果这是一个天真的问题。我阅读了 m4
的文档,但找不到解决方案。
在这种情况下,m4
是将 DEF
转换为 3
的工具。 sed
或 awk
确实可以为这个简单的案例提供相同的目的,但 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;
- 使用
m4
删除一般的 Pascal 注释是不可能的,但是创建一个宏来包含一个 将 在处理过程中被 `m4' 删除的注释是很简单的:
define(`NOTE',`dnl')dnl
NOTE(`This is a comment')
x := 3;
... 产生:
x := 3;
可以将 m4
扩展的常用宏放在一个通用文件中,该文件可以包含在任何使用它们的 Pascal 文件的开头,从而无需定义所有必需的每个 Pascal 文件中的宏。请参阅 m4 manual 中的 include (file)
。
我正在使用 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
那谁把这行转换成上面那行呢?我们可以使用像 sed
或 awk
这样的工具来做同样的事情,但是 m4
有什么用呢? m4
所做的事情也可以使用 sed
来实现。
如果有人能告诉我如何将程序员的代码转换成可供 m4
.
使用的文件,那将非常有帮助
2. 我在使用 m4
时遇到了另一个问题。 C
等语言的注释在预处理之前被删除,所以可以使用 m4
来完成吗?为此,我在 m4
中寻找可以使用正则表达式替换注释的命令,我找到了 regexp()
,但它需要将字符串替换为在这种情况下不可用的参数。那么如何实现呢?
对不起,如果这是一个天真的问题。我阅读了 m4
的文档,但找不到解决方案。
-
在这种情况下,
m4
是将DEF
转换为3
的工具。sed
或awk
确实可以为这个简单的案例提供相同的目的,但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;
- 使用
m4
删除一般的 Pascal 注释是不可能的,但是创建一个宏来包含一个 将 在处理过程中被 `m4' 删除的注释是很简单的:
define(`NOTE',`dnl')dnl NOTE(`This is a comment') x := 3;
... 产生:
x := 3;
可以将 m4
扩展的常用宏放在一个通用文件中,该文件可以包含在任何使用它们的 Pascal 文件的开头,从而无需定义所有必需的每个 Pascal 文件中的宏。请参阅 m4 manual 中的 include (file)
。