C++ 在bison中设置直通规则

C++ 在bison中设置直通规则,c++,c,bison,flex-lexer,C++,C,Bison,Flex Lexer,我有一个使用Flex/Bison生成的解析器——它解析文件的每一行,并返回该行的一些输出。我的输入数据有点损坏,我想做的是在行的开头添加一个特殊字符(如#),我希望bison忽略它,而只是将行回显到输出 如果我的输入看起来像 apples 3 ate oranges 4 consumed # rhino ten 解析这些行后的输出可能是 I ate three apples I consumed four oranges # rhino ten 有什么简单的方法可以做到这一点吗 您可以在fl

我有一个使用Flex/Bison生成的解析器——它解析文件的每一行,并返回该行的一些输出。我的输入数据有点损坏,我想做的是在行的开头添加一个特殊字符(如#),我希望bison忽略它,而只是将行回显到输出

如果我的输入看起来像

apples 3 ate
oranges 4 consumed
# rhino ten
解析这些行后的输出可能是

I ate three apples
I consumed four oranges
# rhino ten

有什么简单的方法可以做到这一点吗

您可以在flex scanner中按词汇进行此操作

比如:

^#.*\n   { fputs(yytext, stdout); /* increment line number */ }
或者在解析器中:

^#.*\n   { yystype.lexeme = strdup(yytext);
           return HASH_ECHO; /* token type defined in parser */ }
在解析器中,只需从顶级语法生成以下内容的产品:

/* in top section */
%union {
   /* ... */
   char *lexeme;
   /* ... */
}

%token<lexeme> HASH_ECHO
/*...*/

/* make sure this rule is hooked into your grammar, of course */
hash_echo : HASH_ECHO { fputs($1, stdout); free($1); }
          ;
顶部部分的
/**/
%联合{
/* ... */
char*词素;
/* ... */
}
%令牌杂凑回音
/*...*/
/*当然,要确保这条规则与你的语法相衔接*/
hash_echo:hash_echo{fputs($1,stdout);free($1);}
;

不确定是否包括那条新线;我不知道你是怎么处理的。因此,这可能不合适。

这会正确地删除正在解析的条目,但不会打印它。可能您正在查看较旧的编辑。fputs调用应该打印词素。顺便说一句,我使用fputs而不是puts,因为puts添加了一个换行符,我们已经有了一个换行符。当然,当您在一行的开头看到一个#时,您的操作本身可以使用输入字符,直到行尾,并在运行时打印它们。您不必让词法分析器将其作为词法位进行扫描。@Kaz我通常会尝试不在扫描仪和解析器中输出某些内容,因为如果解析器需要提前查看标记,那么输出可能会失败,然后输出会不同步。也许您的意思是,如果解析器也生成输出,则不要在词法分析器中输出某些内容,因为lexer将抢先一步,在解析器决定如何处理令牌之前生成输出,因此lexer的输出将是过早的。这就是为什么我包含了第二个答案,它将词素添加到一个标记中,并让解析器在规则操作中打印它。