Make bison reduce to start symbol only if EOF is f

2019-03-06 11:26发布

I am using Bison with Flex. I have the following rule in my Yacc input file:

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

The problem is that if I have a program that is partially correct, but then there is some "garbage" before EOF, it will reduce according to the previous rule, report "success" and only then report an error.

I want to include EOF at the end of the rule above, but then, Flex would have to return EOF when it read <<EOF>>, and how would Bison know when to end the program? Now, I have this in Flex:

<<EOF>>    {return 0;}

标签: bison yacc lex
1条回答
smile是对你的礼貌
2楼-- · 2019-03-06 12:01

Here is an example that would do that:

First the lex file:

%{
#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;
}

In the <INITIAL> condition the end-of-file generates a token EOP. Note the explicit use of <INITIAL>, because otherwise the <<EOF>> will be used for all begin conditions. Then it switches to <REALLYEND> to generate the internal end-of-file "token" for bison.

The bison file could look like this:

%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();
}

The question in your title is a bit misleading as bison will always only reduce the internal start symbol if EOF is found, that is what the internal end-of-file token is for. The difference is that you wanted the action, printing success, in the grammar only to be executed after the EOF has been found and not before. That is, reduction of your start symbol.

查看更多
登录 后发表回答