使用m4进行预处理

时间:2015-03-11 05:01:37

标签: preprocessor m4

我正在使用m4为Free-Pascal(课程作业)编写预处理器。我正在stackoverflow here阅读该帖子,并从那里得到一个blog,它基本上显示m4的基本用法,用于C的预处理。该博主使用了这样的测试C文件test.c.m4

#include 

define(`DEF', `3')

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

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

$ 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 个答案:

答案 0 :(得分:2)

    在这种情况下,
  1. m4是将DEF转换为3的工具。确实,sedawk可以为这个简单的情况提供相同的目的,但m4是一个更强大的工具,因为它a)允许宏参数化,b)包括条件,c)允许通过输入文件重新定义宏,等等。例如,可以编写(在文件for.pas.m4中,受ratfor启发):
  2. 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;
    
    1. 使用m4删除一般Pascal评论是不可能的,但是创建一个宏来包含删除的评论“m4&#39;在处理过程中很简单:
    2. define(`NOTE',`dnl')dnl
      NOTE(`This is a comment')
            x := 3;
      

      ...生产:

          x := 3;
      

      要由m4扩展的常用宏可以放在一个公共文件中,该文件可以包含在使用它们的任何Pascal文件的开头,因此不必定义所有需要的宏。每个Pascal文件。请参阅m4 manual中的include (file)