当前位置:  开发笔记 > 编程语言 > 正文

C风格:宏还是预处理器?

如何解决《C风格:宏还是预处理器?》经验,为你挑选了1个好方法。

我已经编写了一个库来匹配一组模式的字符串,现在我可以轻松地将词汇扫描程序嵌入到C程序中.

我知道有许多成熟的工具可用于创建词法扫描程序(lex和re2c,仅列出前两个想到的)这个问题不是关于词法分析器,而是关于"扩展"C语法的最佳方法.词法分析器示例只是一个普遍问题的具体案例.

我可以看到两种可能的解决方案

    编写一个预处理器,将带有嵌入词法分析器的源文件转换为普通的C文件,并可能转换为要在编译中使用的一组其他文件.

    编写一组C宏来以更易读的形式表示词法分析器.

我已经做过两个但问题是:"你会根据以下标准考虑哪一个更好的做法?"

可读性.词法分析器逻辑应清晰易懂

可维护性.找到并修复bug不应该是一场噩梦!

构建过程中的干扰.预处理器在构建过程中需要额外的步骤,预处理器必须在路径等中等.

换句话说,如果你不得不维护或编写一个使用这两种方法之一的软件,那么一个人会不会让你失望?

例如,以下是针对以下问题的词法分析器:

求和所有数字(可以是十进制形式,包括像1.3E-4.2那样的指数)

跳过字符串(双引号和单引号)

跳过列表(类似于LISP列表:(3 4(0 1)()3))

在遇到单词end(case无关紧要)或缓冲区末尾时停止

在两种风格.

/**** SCANNER STYLE 1 (preprocessor) ****/
#include "pmx.h"

t = buffer

while (*t) {
  switch pmx(t) { /* the preprocessor will handle this */
    case "&q" :         /* skip strings */
      break; 

    case "&f&F" : /* sum numbers */ 
      sum += atof(pmx(Start,0));
      break;

    case "&b()":        /* skip lists */
      break;

    case "&iend" :      /* stop processing */ 
      t = "";
      break;

    case "<.>":         /* skip a char and proceed */
      break;
  }
}

/**** SCANNER STYLE 2 (macros) ****/
#include "pmx.h"
/* There can be up to 128 tokens per scanner with id x80 to xFF */
#define TOK_STRING x81
#define TOK_NUMBER x82
#define TOK_LIST   x83
#define TOK_END    x84
#define TOK_CHAR   x85

pmxScanner(   /* pmxScanner() is a pretty complex macro */
   buffer
 ,
   pmxTokSet("&q"         , TOK_STRING)
   pmxTokSet("&f&F" , TOK_NUMBER)
   pmxTokSet("&b()"       , TOK_LIST)
   pmxTokSet("&iend"      , TOK_END)
   pmxTokSet("<.>"        , TOK_CHAR)
 ,
   pmxTokCase(TOK_STRING) :   /* skip strings */
     continue; 

   pmxTokCase(TOK_NUMBER) :   /* sum numbers */ 
     sum += atof(pmxTokStart(0));
     continue;

   pmxTokCase(TOK_LIST):      /* skip lists */
     continue;

   pmxTokCase(TOK_END) :      /* stop processing */ 
     break; 

   pmxTokCase(TOK_CHAR) :     /* skip a char and proceed */
     continue;
);

如果有人对当前的实施感兴趣,则代码位于:http://sites.google.com/site/clibutl.



1> dirkgently..:

预处理器将提供更强大和通用的解决方案.另一方面,宏可以快速启动,提供良好的概念验证,并且当样本关键字/令牌空间很小时很容易.扩展/包含新功能可能会在一点之后使用宏变得乏味.我会说启动宏然后将它们转换为预处理器命令.

此外,尽可能尝试使用通用预处理器而不是编写自己的预处理器.

[...]我会有另一个依赖项来处理(例如,Windows的m4).

是.但你写的任何解决方案也是如此:) - 必须维护它.您命名的大多数程序都有可用的Windows端口(例如,请参阅m4 for windows).使用这种解决方案的好处是可以节省大量时间.当然,缺点是你可能必须加快源代码的速度,如果奇怪的错误出现(虽然维护这些的人非常有帮助,肯定会确保你得到一切帮助).

再说一遍,是的,我更喜欢打包自己的打包解决方案.

推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有