1

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

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

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

我想在上述规则的末尾包含 EOF,但是,Flex 必须在读取时返回 EOF <<EOF>>,而 Bison 怎么知道何时结束程序?现在,我在 Flex 中有这个:

<<EOF>>    {return 0;}
4

1 回答 1

2

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

首先是 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,这就是内部文件结束标记的用途。不同之处在于您希望success语法中的操作打印仅在EOF找到之后而不是之前执行。也就是说,减少你的开始符号。

于 2013-05-08T08:07:24.237 回答