为什么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 一个输入结束指示符。因此,由于缺少分号,解析失败。
启用会使这一点更加明显。
我目前正在从事一个 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 一个输入结束指示符。因此,由于缺少分号,解析失败。
启用