我的Lex和Yacc程序运行得很好,然后第二次尝试崩溃了?

时间:2016-05-20 18:58:54

标签: bison flex-lexer yacc lex

我有两个非常小的文件(试图删除所有其他混淆变量)分别用Lex和Yacc编写。

莱克斯:

%{
    #include <stdlib.h>
    #include "y.tab.h"
    void yyerror(char *);
%}

%%

[a] {
    yylval = *yytext;
    return VAR;
    }

[ \t\n] ;

. yyerror("invalid character");

%%

int yywrap(void) {
 return 1;
}

的Yacc:

%token VAR

%{
    void yyerror(char *);
    int yylex(void);
    #include <stdio.h>
%}

%%

butts:
    VAR { printf("%d\n", $1); }

%%

void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}


int main(void) {
    #if YYDEBUG
    yydebug = 1;
    #endif
    yyparse();
    return 0;
}

当我编译整个事物(使用-DYYDEBUG)选项时,我得到输出:

Starting parse
Entering state 0
Reading a token: a
Next token is token VAR ()
Shifting token VAR ()
Entering state 1
Reducing stack by rule 1 (line 12):
   $1 = token VAR ()
97
-> $$ = nterm butts ()
Stack now 0
Entering state 2
Reading a token: a
Next token is token VAR ()
syntax error
Error: popping nterm butts ()
Stack now 0
Cleanup: discarding lookahead token VAR ()
Stack now 0

两次输入“a”时。我第一次按“a”时询问Reading a token:程序似乎运行良好,但第二次,它就会呕吐。

我不知道为什么会这样。

1 个答案:

答案 0 :(得分:3)

这是因为你的语法文件说只允许一个“a”。更多是一个错误,因此你得到一个错误。你的语法规则说:

butts: VAR 

仅此而已。

因此,您的语法匹配的唯一有效程序是:

a

任何其他输入,例如:

aa

或:

a
a

会导致语法错误。您的规则非常明确地说一个 VAR ;不是VARS的序列;不是一些变种。只有一个VAR。

如果您希望它与输入中的多个匹配,则 来表示。因此语法必须描述允许的顺序:

butts: VAR | butts VAR

然后它将允许序列。

更清楚了吗?