为什么Bison总是给我"Syntax error near line x"?

Why Bison always gives me "Syntax error near line x"?

我目前正在从事一个 flex / bison 项目,该项目包括识别给定文件中的语法错误。 我已经编写了我的解析器和包含规则的 lex 文件,但我认为我遇到了问题,因为无论我向我的程序提供哪个文件,我都会收到以下消息 “第 1 行附近的语法错误”。 =28=],即使是像 int r1; 这样的基本行。 所以这是我的 .lex 文件,其中包含我的所有规则:

    %{
#include <stdlib.h>
#include <stdio.h>
#include "tpc-2019-2020.h"
int lineno = 1; 
%}

%option nounput
%option noinput
%x COMMENT

%%
<COMMENT>"*/" BEGIN INITIAL;
"/*" {printf("ok\n"); BEGIN COMMENT;}
"//".* ; 
<COMMENT>. ;
<COMMENT>\n ; lineno++;
int { return TYPE; }
char { return TYPE; }
";" { return 0; }
[ \t] {};
[0-9]* { return NUM; }
\n { lineno++; }
void { return VOID; }
print { return PRINT; }
while { return WHILE; }
readc { return READC; }
reade { return READE; }
[a-zA-Z] { return CHARACTER; }
[a-zA-Z][a-zA-Z0-9_]* { return IDENT; }
\+|- { return ADDSUB; }
\=\= { return EQ; }
\!\= { return EQ; }
\< { return ORDER; }
\<\= { return ORDER; }
\> { return ORDER; }
\>\= { return ORDER; }

\|\| { return OR; }
\&\& { return AND; }
. return yytext[0];

%%

还有我的 .y 文件:

%{
/* tpc-2019-2020.y */
/* Syntaxe du TPC pour le projet d'analyse syntaxique de 2019-2020*/
#include <stdio.h>
int yyparse();
int yylex();
void yyerror(char *s);
extern int lineno;
%}

%token CHARACTER
%token NUM
%token IDENT
%token TYPE
%token EQ
%token ORDER
%token ADDSUB
%token OR
%token AND
%token ELSE
%token IF
%token PRINT
%token READC
%token READE
%token RETURN
%token VOID
%token WHILE
%left ELSE 

%%
Prog:  DeclVars DeclFoncts 
    ;
DeclVars:
       DeclVars TYPE Declarateurs ';' 
    |  ;
Declarateurs:
       Declarateurs ',' IDENT 
    |  Declarateurs ',' '*' IDENT 
    |  IDENT 
    |  '*' IDENT 
    ;
DeclFoncts:
       DeclFoncts DeclFonct 
    |  DeclFonct 
    ;
DeclFonct:
       EnTeteFonct Corps 
    ;
EnTeteFonct:
       TYPE IDENT '(' Parametres ')' 
    |  TYPE '*' IDENT '(' Parametres ')' 
    |  VOID IDENT '(' Parametres ')' 
    ;
Parametres:
       VOID 
    |  ListTypVar 
    ;
ListTypVar:
       ListTypVar ',' TYPE IDENT 
    |  ListTypVar ',' TYPE '*' IDENT 
    |  TYPE IDENT 
    |  TYPE '*' IDENT 
    ;
Corps: '{' DeclVars SuiteInstr '}' 
    ;
SuiteInstr:
       SuiteInstr Instr 
    |  ;
Instr:
       LValue '=' Exp ';'
    |  READE '(' IDENT ')' ';'
    |  READC '(' IDENT ')' ';'
    |  PRINT '(' Exp ')' ';'
    |  IF '(' Exp ')' Instr 
    |  IF '(' Exp ')' Instr ELSE Instr
    |  WHILE '(' Exp ')' Instr
    |  IDENT '(' Arguments  ')' ';'
    |  RETURN Exp ';' 
    |  RETURN ';' 
    |  '{' SuiteInstr '}' 
    |  ';' 
    ;
Exp :  Exp OR TB 
    |  TB 
    ;
TB  :  TB AND FB 
    |  FB 
    ;
FB  :  FB EQ M
    |  M
    ;
M   :  M ORDER E 
    |  E 
    ;
E   :  E ADDSUB T 
    |  T 
    ;    
T   :  T '*' F 
    |  T '/' F 
    |  T '%' F 
    |  F 
    ;
F   :  ADDSUB F 
    |  '!' F 
    |  '&' IDENT 
    |  '(' Exp ')' 
    |  NUM 
    |  CHARACTER
    |  LValue
    |  IDENT '(' Arguments  ')' 
    |  '*' IDENT '(' Arguments  ')' 
    ;
LValue:
       IDENT 
    |  '*' IDENT 
    ;
Arguments:
       ListExp 
    | ;
ListExp:
       ListExp ',' Exp 
    |  Exp 
    ;
%%
int main(int argc, char** argv) {
    yyparse();
    return 0;
}
void yyerror(char *s){
    fprintf(stderr, "%s near line %d\n", s, lineno);
}

即使我的输入文件只是: int r1, r2;

它给我“语法错误行 1”

我试图只将一些注释行放入我的文件中,但我收到了“OK”消息,这意味着我的规则可以识别注释行,但即使每次我总是得到相同的“第 1 行附近的语法错误”。

感谢您的帮助!

你的语法说声明看起来像这样:

DeclVars:
   DeclVars TYPE Declarateurs ';' 

换句话说,每个声明都以分号结束。

但是你的扫描器从来没有returns一个分号:

";" { return 0; }

当扫描器到达一个分号时,它 returns 一个输入结束指示符。因此,由于缺少分号,解析失败。

启用会使这一点更加明显。