yacc解析器因两次通过同一行而失败

时间:2019-06-26 04:04:22

标签: yacc

我需要帮助调试yacc / lex解析器

这是.y文件

%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
#include <math.h>

#include "grm_parsegrammar.h" 
%} 

%union { 
  char *string; 
} 

%token <string> LHS

%% /* yacc grammar rules  */ 

rna_grammar: LHS;

%% /* user generated code */

void yyerror(char const *s)
{
  fprintf(stderr, "yyerror: %s\n", s);
}
int yywrap()
{
  return 1;
}

void
Grammar_Parse()
{
  yyparse();

}

这是lex文件

%{  
#include "grm_parsegrammar.tab.h"

%}


/* REWRITE */
arrow "-"+">" 
nonterm [A-Z]
lhs {nonterm}{arrow}

%% /* RULES */
[ \t] ;
{lhs}  { return LHS; }
.      { printf("Illegal character |%c|\n", *yytext); }

文件grm-parsegrammar.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


/* yacc-req'd declarations */
extern int  yyparse(void);
extern int  yylex(void);
extern void yyerror(char const *s);
extern int  yywrap();

/* my declarations */
extern void Grammar_Parse();

文件grm-parse.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "grm_parsegrammar.h"
#include "grm_parsegrammar.tab.h"

int 
main (int argc, char **argv) 
{
  Grammar_Parse();

  return 0;
}

编译命令是

bison -v -d -t grm_parsegrammar.y
gcc  -o grm_parsegrammar.tab.o -c grm_parsegrammar.tab.c
flex -I -d grm_parsegrammar.lex
gcc  -o lex.yy.o -c lex.yy.c
gcc  -o grm-parse.o -c grm-parse.c
gcc  -o grm-parse grm_parsegrammar.tab.o lex.yy.o  grm-parse.o -lm

然后我用它来解析此文件

S->

文件的十六进制转储是

hexdump语法/foo.grm 0000000 53 2d 3e 0a
0000004

然后,我获得以下命令:

grm-parse foo.grm


--(end of buffer or a NUL)
--accepting rule at line 14 ("S->")
--accepting default rule ("
")

--accepting rule at line 13 (" ")
--accepting rule at line 14 ("S->")
yyerror: syntax error

我不明白为什么会出现语法错误,或者为什么它两次接受S->。

如果我修改y文件并替换一条规则 rna_grammar:LHS

rna_grammar:LHS | rna_grammar LHS

并使用它来解析同一文件,然后语法错误消失,但是S->被解析两次。 这是上面修改的现在递归规则的输出

-(缓冲区结尾或NUL) -在第14行接受规则(“ S->”) -接受默认规则(“ “)

-接受第13行的规则(“”) -在第14行接受规则(“ S->”) -接受默认规则(“ “)

-(缓冲区结尾或NUL) --EOF(开始条件0)

没有任何意义。

“第13行接受规则”中的空格来自哪里?

0 个答案:

没有答案