Parsing 读取LEX YACC中给出语法错误的新行

Parsing 读取LEX YACC中给出语法错误的新行,parsing,yacc,lex,Parsing,Yacc,Lex,我试图解析一段代码,为此我编写了LEX和YACC文件,将在下面给出。第一行读取正确,但在它给出语法错误之后,它不会读取下一行,如果我修改输入和取消输出函数,我将从文件读取并将输出写入文件…我刚刚开始使用LEX YACC,需要一些想法 输入文件 b_7 = _6 + b_3; a_8 = b_7 - c_5; lex文件 %{ /* parser for ssa; */ #include<stdio.h>

我试图解析一段代码,为此我编写了LEX和YACC文件,将在下面给出。第一行读取正确,但在它给出语法错误之后,它不会读取下一行,如果我修改输入和取消输出函数,我将从文件读取并将输出写入文件…我刚刚开始使用LEX YACC,需要一些想法

输入文件

b_7 = _6 + b_3;
a_8 = b_7 - c_5;
lex文件

    %{
        /*
            parser for ssa;
        */

    #include<stdio.h>
    #include<stdlib.h>
    #include"y.tab.h"


    %}
    %%
    [\t]+   ;
    \n  ;



    [if]+       printf("first input\n");
    [else]+     return(op);
    [=]+        return(equal);
    [+]+        return(op);
    [*]+        return(op);
    [-]+        return(op);

    [\<][b][b][ ]+[1-9][\>] {return(bblock);}

    ([[_][a-z]])|([a-z][_][0-9]+)|([0-9]+)  {return(var);}

    .   ;




    %%
%{
/*
ssa解析器;
*/
#包括
#包括
#包括“y.tab.h”
%}
%%
[\t]+;
\n;
[if]+printf(“第一次输入”);
[其他]+返回(op);
[=]+回报(相等);
[+]+返回(op);
[*]+返回(op);
[-]+返回(op);
[\]{return(bblock);}
([[u][a-z]])|([a-z][0-9]+)|([0-9]+){return(var);}
.   ;
%%
yacc文件

%{
/* lexer for ssa gramer to use for recognizing operations*/
#include<stdio.h>
char add_graph(char,char,...);

%}

%token  opif opelse equal op bblock var

%%

sentence: var equal var op var  { add_graph($1,$2,$3,$4,$5);} 

    ;


%%
extern FILE *yyin;
main(argc,argv)
int argc;
char **argv;
{
    if(argc > 1) {
        FILE *file;
        file=fopen(argv[1],"r");
        if(file==NULL) {
            fprintf(stderr,"couldnot open%s\n",argv[0]);
            exit(1);
        }
        yyin=file;
    }
      do
    {
    yyparse();
    }while (!feof(yyin));
fclose(yyin);
}
char add_graph(something)
{
.....
.....
}

yyerror(s)
char *s;
{
    fprintf(stderr,"%s there is error\n",s);
}
yywrap()
{
printf("the output");
}
%{
/*ssa gramer用于识别操作的lexer*/
#包括
char add_图(char,char,…);
%}
%令牌opif opelse等于op bblock var
%%
句子:var-equal-var-op-var{add_图($1,$2,$3,$4,$5);}
;
%%
外部文件*yyin;
主(argc、argv)
int-argc;
字符**argv;
{
如果(argc>1){
文件*文件;
file=fopen(argv[1],“r”);
if(file==NULL){
fprintf(stderr,“无法打开%s\n”,argv[0]);
出口(1);
}
yyin=文件;
}
做
{
yyparse();
}而(!feof(yyin));
fclose(yyin);
}
字符添加图(某物)
{
.....
.....
}
YY错误
char*s;
{
fprintf(stderr,“%s有错误\n”,s);
}
yywrap()
{
printf(“输出”);
}

您的语法只允许使用一个
句子。因此,如果在第一句话之后有任何输入,就会出现错误。您希望允许使用一个或多个句子。在.y文件中尝试以下操作:

%%
sentences : sentences sentence
          | sentence
          ;
sentence  : var equal var op var  { add_graph($1,$2,$3,$4,$5);}
          ;
%%
这里有很多问题:

  • 您的语法需要标记
    op
    ,但您的lexer永远不会生成它,而是生成
    opadd
    opmul
  • 你的例子有
    位于行的末尾,但您的lexer和解析器都不能处理它们。复制到stdout的默认lexer操作几乎从来都不是您想要的
  • 您的yacc文件试图使用
    \\
    作为某种注释标记,但yacc不理解这一点。yacc的某些版本将C++风格的
    /
    理解为注释,但不是全部
  • 您的语法只允许输入一个句子
  • 你的句子末尾(下一行)有一个虚假的
    op
    ,这不是一个单独的句子规则——你需要
    来分开规则
  • yyparse
    返回时,如果尚未达到eof,则尝试循环,但如果出现错误,则输入仍可能有一些积垢,这将导致立即错误,导致错误风暴——可能不是您想要的

    • 大卫说的没错,但还需要再做一次修改


      看看这是否有帮助。如果我错了,请承认我。

      是的,大卫,我已经编写了你的代码,并且按照克里斯所说的,我在lex文件中又添加了一行,它可以工作“;”;
      ";"     ;