我有两个非常小的文件(试图删除所有其他混淆变量)分别用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:
程序似乎运行良好,但第二次,它就会呕吐。
我不知道为什么会这样。
答案 0 :(得分:3)
这是因为你的语法文件说只允许一个“a”。更多是一个错误,因此你得到一个错误。你的语法规则说:
butts: VAR
仅此而已。
因此,您的语法匹配的唯一有效程序是:
a
任何其他输入,例如:
aa
或:
a
a
会导致语法错误。您的规则非常明确地说一个 VAR 仅;不是VARS的序列;不是一些变种。只有一个VAR。
如果您希望它与输入中的多个匹配,则 来表示。因此语法必须描述允许的顺序:
butts: VAR | butts VAR
然后它将允许序列。
更清楚了吗?