只有在找到EOF时才能使野牛减少以开始符号

时间:2013-05-08 03:35:49

标签: bison yacc lex

我正在使用Bison和Flex。 我的Yacc输入文件中有以下规则:

program     : PROGRAM m2 declarations m0 block {cout << "Success\n"} ;

问题是如果我有一个部分正确的程序,但是在EOF之前有一些“垃圾”,它将根据先前的规则减少,报告“成功”,然后才报告错误。

我想在上面的规则结尾处包含EOF,但是,当读取<<EOF>>时,Flex必须返回EOF,Bison将如何知道何时结束该程序? 现在,我在Flex中有这个:

<<EOF>>    {return 0;}

1 个答案:

答案 0 :(得分:1)

这是一个可以做到这一点的例子:

首先是lex文件:

%{
#include "grammar.tab.h"
%}
%x REALLYEND
%option noinput nounput
%%
"END"                   { return END; }
.                       { return TOK; }
<INITIAL><<EOF>>        { BEGIN(REALLYEND); return EOP; }
<REALLYEND><<EOF>>      { return 0; }
%%

int yywrap(void)
{
        return 1;
}

<INITIAL>条件下,文件结尾会生成令牌EOP。请注意明确使用<INITIAL>,否则<<EOF>>将用于所有开始条件。然后它切换到<REALLYEND>以生成野牛的内部文件结束“令牌”。

野牛文件可能如下所示:

%token END EOP TOK
%{
#include <stdio.h>
void yyerror(char * msg)
{
        fprintf(stderr, "%s\n", msg);
}
extern int yylex(void);
%}
%%
prog : END EOP { printf ("ok\n"); };
%%

int main(void)
{
        return yyparse();
}

标题中的问题有点误导,因为如果找到bison EOF将始终只减少内部开始符号,那就是内部结束-file令牌用于。不同之处在于,您希望在语法中打印success的操作仅在找到EOF之后执行,而不是之前执行。也就是说,减少你的开始符号。