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

My Lex and Yacc program runs once fine, then crashes on the second try?

我有两个非常小的文件(试图删除所有其他混淆变量)分别用 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", ); }

%%

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):
    = 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: 程序似乎 运行 正常,但第二次,它吐了。

我不知道为什么会这样。

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

butts: VAR 

不多也不少。

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

a

任何其他输入,例如:

aa

或:

a
a

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

如果您希望它在输入中匹配多个,您必须这么说。因此语法必须描述允许的序列:

butts: VAR | butts VAR

然后它将允许序列。

是不是更清楚了?