野牛yacc yyerror不起作用

时间:2017-12-28 19:36:30

标签: bison yacc

我更喜欢Yacc编程,我有一个简单的任务来编写一个程序,它检查输入文本文件是否 包含一系列正确配对的括号。任何错误的序列 应该标记为“语法错误!”。我使用野牛和弯曲。

示例正确数据:     (()()((())())()) 但     (() 是不正确的。

我的问题是我认为它应该有效,但似乎yyerror无效。也许我做错了什么,请纠正我。 这是我的代码 Yacc代码:

 %{
int yylex();
void yyerror(char* x);
%}
%%
S: S A
 |A
 ;
A: '('S')'
  |'(' ')'
  ;

和lex代码:

%{
#include "y.tab.h"
%}
%%
[\(\)] return(yytext[0]);
. {printf("%c - error!\n",yytext[0]);}

%%
void yyerror(char* x)
{
    printf("syntax error");
    exit(1);
}

所以问题是它不会触发语法错误,我写的括号有多大并不重要。 编辑: 这是我编译它的方式: screen

2 个答案:

答案 0 :(得分:1)

您需要提供一个main()函数(至少)调用yyparse()。否则,将使用main中的libflmain不会调用yyparse();相反,它会反复调用yylex,直到发出EOF信号。 (libfl是Flex的一部分,而不是野牛,所以它不能依赖于yyparse甚至是现有的。)

确实无需与-lfl关联。 main()定义对您没有用,库中唯一的其他内容是yywrap()的虚拟定义。您没有定义yywrap(),因此将调用库函数;但是,您可以简单地添加

,而不是依赖于库
%option noyywrap

到您的Flex代码(就在%%之前),然后生成的扫描程序将不会调用yywrap()

调用野牛时也无需使用-y标志。使用-y的唯一原因是能够使用bison处理传统的yacc文件。我想你正在使用该标志,以便生成的解析器被称为y.tab.c;没有标志,它将被称为z5.tab.c(头文件将是z5.tab.h);你可以使用这些名字。 (或者您可以使用-o标志告诉Bison您希望它使用的确切文件名。)

最后,关于你的lex文件的两个注释:

  1. 括号的模式可以写成:

    [()]  { return yytext[0]; }
    

    字符类中不需要使用反斜杠转义括号,因为]-\以外的字符在字符类中没有特殊含义。

  2. 模式.与换行符不匹配,这就是输入中的换行符不会产生错误消息的原因。实际上,没有一个模式与换行符匹配,因此当您键入换行符时,将调用默认规则。默认规则等同于ECHO,其中bison定义为:

    fputs(yytext, yyout);
    

    (或fprintf(yyout, "%s", yytext);

    这就是当您输入换行符时输出额外换行符的原因。

答案 1 :(得分:-1)

所以lex的正确代码是:

%{
#include "z5.tab.h"
%}

%%
[\(\)] return(yytext[0]);
. {printf("%c - error!\n",yytext[0]);}
\n ;
%%
int main(void)
{
   yyparse();
   return 0;
}

int yywrap(void)
{
   return 0;
}
void yyerror(char* x)
{
    printf("syntax error");
    exit(1);
}

以及编译它的正确方法是:

flex s5.l 
bison -d z5.y 
gcc lex.yy.c z5.tab.c -L"C:\GnuWin32\lib"