我正在使用m4为Free-Pascal(课程作业)编写一个预处理器。我在这里阅读了堆栈溢出的线程,并从那里到达了一个博客,该博客基本上显示了m4
对C
进行预处理的基本用法。博主使用测试C
文件test.c.m4
如下所示:
#include
define(`DEF', `3')
int main(int argc, char *argv[]) {
printf("%dn", 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 := 1 to $2 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 手册中的include (file)
。