我已经编写了一个库来匹配一组模式的字符串,现在我可以轻松地将词汇扫描程序嵌入到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=eE>&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=eE>&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.
预处理器将提供更强大和通用的解决方案.另一方面,宏可以快速启动,提供良好的概念验证,并且当样本关键字/令牌空间很小时很容易.扩展/包含新功能可能会在一点之后使用宏变得乏味.我会说启动宏然后将它们转换为预处理器命令.
此外,尽可能尝试使用通用预处理器而不是编写自己的预处理器.
[...]我会有另一个依赖项来处理(例如,Windows的m4).
是.但你写的任何解决方案也是如此:) - 你必须维护它.您命名的大多数程序都有可用的Windows端口(例如,请参阅m4 for windows).使用这种解决方案的好处是可以节省大量时间.当然,缺点是你可能必须加快源代码的速度,如果奇怪的错误出现(虽然维护这些的人非常有帮助,肯定会确保你得到一切帮助).
再说一遍,是的,我更喜欢打包自己的打包解决方案.