如何在GNU flex中将yyout重定向到char * buffer?

时间:2013-06-08 03:54:21

标签: c gnu flex-lexer

默认情况下,yyout设置为stdout,可以重定向到FILE*流。是一种将yyout重定向到char*的方法吗?

1 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点。如果您在尝试使用yyout的地方发布一些扫描仪代码,我可以给您一个更具体的答案:

通常情况下,您可以执行此操作。因此,不要使用ECHOfprintf(yyout...,而是使用其他内容,例如

<token>  { snprintf(buf, sizeof(buf), "%s", yytext); }
早些时候你已宣布:

char buf[BUFSIZE];

附录I - 另一种方法

有一些聪明的方法来处理这种情况,但从长远来看,它们容易出现维护问题,因为它们“聪明”......并且更聪明的解决方案是它的寿命缩短。 (除非附有警告,否则聪明才有详细记录)

 int yyprintf(const char *fmt, ...)  {
     va_list ap;
     va_start(ap, fmt);
     if ( some_flag & FLAG_OUTFILE ) {
         vfprintf(yyout, fmt, ap);
     }
     else {
         sprintf(buf, fmt, ap);
     }
     va_end(ap);
 }

其中buf是全局缓冲区。

但是如果你想让事情有点局部化:

方法2:精细控制事物的去向和时间

你希望细致地控制事物的发展方向。有时你想要输出 提交文件,其他时间提交给字符串,你并不总是知道哪个,以及何时何地可以使用这样的文字:

 int myvprintf(void *here, size_t len, const char *fmt, va_list ap) 
      __attribute__((format (gnu_printf, 3, 4), nonnull(1, 3))) {

     int rv;

     if ( len > 0 ) { 
        rv = vsnprintf((char *), len, fmt, ap);
     }
     else {
        rv = vfprintf((FILE *)here, fmt, ap);
     }

     return rv;
 }

 int myprintf(void *here, size_t len, const char *fmt, ... ) 
      __attribute__((format (gnu_printf, 3, 4), nonnull(1, 3))) {
     int rv;
     va_list ap;
     va_start(fmt, ap);
     rv = myvprintf(here, len, fmt, ap);
     va_end(ap);
     return rv;
 }

并沿途使用myprintf,您将始终控制here的内容。

Just for Fun

不要在家里试试。但是所有yy *标识符和ECHO都不是普通变量,它们是#define的。所以你可以做一些聪明的宏重写:

例如,如果您在任何地方使用ECHO,那么您可以在顶部重新定义它以执行您喜欢的任何操作(只需#undef和#define):

%{
#undef ECHO
#define ECHO snprintf(buf, sizeof(buf), "%s", yytext)
%}

%%

<token> ECHO;
%% 

只需将它全部隐藏在复杂的标题中,然后做一些其他聪明的事情,以便稍后为你讨厌的程序员调试地狱。这可以有自己的奖励和咯咯笑。