【发布时间】:2019-09-29 17:40:03
【问题描述】:
我正在尝试使用 flex 和 bison 编写一个语法识别器来确定输入字符串是否在 L(G) 中,其中语言是以下各项的并集:
L(G) = {a^i b^j c^k d^l e^m} 其中 i,j,k,l,m > 0 且 i=m 且 k=l
和
L(G) = {e^i d^j c^k b^l a^m} 其中 i,j,k,l,m > 0 and i=2m k=3l and j=2
现在我可以正常工作,但仅在使用语言中的标记时。如果我包含任何其他令牌,它似乎会被忽略,并且测试会根据其他允许的令牌通过或失败。这是有问题的,因为它允许诸如“abcdef”之类的字符串通过解析,即使“f”不在该语言中。
我现在测试的错误输入是“abcdef”。 “abcde”部分是正确的并给出了正确的输出,但在末尾添加“f”会导致来自 yyerror("syntax error") 的语法错误消息和从 main 到的“congratulations; parse succeeded”打印语句打印。
使用“fabcde”与我上面描述的一样。它给了我错误,但它也给了我成功的打印声明。我正在使用“if(yyparse() == 0))”在 main 中打印成功语句,我认为这可能是罪魁祸首,尽管当我将 print 语句移动到 . y 文件,只在 main 中使用了 yyparse() 和 return(1)。
这是我的 .in 文件(减去包括):
%%
a return A;
b return B;
c return C;
d return D;
e return E;
. yyerror("syntax error\n\nSorry, Charlie, input string not in L(G)\n"); /* working but still prints success message too */
%%
这是我的 .y 文件(减去包括):
%token A
%token B
%token C
%token D
%token E
%% /* Grammar Rules */
string: as bs cs ds es
{
if(($1 == $5) && ($3 == $4)) {
return(0);
}
else
{
return(-1);
}
}
;
string: es ds cs bs as
{
if(($1 == (2 * $5) && ($3 == (3 * $4)) && ($2 = 2)) {
return(0);
}
else
{
return(-1);
}
}
;
as: A as {$$ = $2 +1;}
;
as: A {$$ = 1;}
;
bs: B bs {$$ = $2 +1;}
;
bs: B {$$ = 1;}
;
cs: C cs {$$ = $2 +1;}
;
cs: C {$$ = 1;}
;
ds: D ds {$$ = $2 +1;}
;
ds: D {$$ = 1;}
;
es: E es {$$ = $2 +1;}
;
es: E {$$ = 1;}
;
%%
我的 .c 文件很简单,如果 yyparse() == 0 则返回“恭喜;解析成功”,否则返回“输入字符串不在 L(G) 中”。
当输入字符串仅包含 a、b、c、d 和 e 时,一切正常。如果输入字符串中除了它们之外还有任何标记,我只需要弄清楚如何使解析器在没有成功语句的情况下给出语法错误。
这是一张有助于显示我的问题的图片: The first two parses work as intended. The third one shows my issue.
【问题讨论】:
-
输入错误是什么?例如,我希望以
f开头的输入会产生错误返回。 -
@rici 我现在正在测试的错误输入是“abcdef”。 “abcde”部分是正确的并给出了正确的输出,但在末尾添加“f”会导致来自 yyerror("syntax error") 的语法错误消息和从 main 到的“congratulations; parse succeeded”打印语句打印。
-
是的,这很容易解释。请在您的问题中添加这些详细信息。
-
@rici 刚刚看到您对评论的编辑。使用“fabcde”与我在上一条评论中描述的相同。它给了我错误,但它也给了我成功的打印声明。我正在使用“if(yyparse() == 0))”在 main 中打印成功语句,我认为这可能是罪魁祸首,尽管当我将 print 语句移动到 . y 文件,只在 main.y 文件中使用了 yyparse() 和 return(1)。也谢谢你的建议,我会把它添加到我的帖子中。
-
我的猜测是这是未定义的行为:
return yyerror("syntax error\n\nSorry, Charlie, input string not in L(G)\n");除非您的yyerror函数实际上返回了一些东西(大多数都没有)。
标签: parsing bison flex-lexer