无法在 Bison 代码中找到“语法错误”的原因

问题描述

我正在尝试连接简单的 flex 和 bison 代码,这些代码现在只能识别一个字符。然而我正面临这个错误。我已经阅读了很多答案以找出问题所在,但我迷路了。任何帮助将不胜感激,因为我刚刚开始探索这个并且找不到很多资源。

这是我的 .l 文件

%{
#include <stdlib.h>
#include <stdio.h>
#include "MiniJSC.tab.h"
void yyerror (char *s);
int yylex();
%}

%%


[0-9]+                                                              { yylval.num = atoi(yytext); return T_INT_VAL; }

%%
int yywrap (void) {return 1;}

我的 .y 文件

%{
void yyerror (char *s);
int yylex();
#include <stdio.h>     /* C declarations used in actions */
#include <stdlib.h>
%}

%union {int num; char id;}         /* Yacc deFinitions */
%start line
%token print
%token T_INT_VAL
%type <num> line
%type <num> term 
%type <num> T_INT_VAL

%%

/* descriptions of expected inputs     corresponding actions (in C) */

line    : print term ';'            {printf("Printing %d\n",$2);}
        ;
        
term    : T_INT_VAL                 {$$ = $1;}
        ;

%%                     /* C code */
void yyerror (char *s) {
fprintf (stderr,"%s\n",s);
}

int main (void) {

    return yyparse ( );
}

编译和输出

$ bison MiniJSC.y -d
$ lex MiniJSC.l
$ gcc lex.yy.c MiniJSC.tab.c
$ ./a.out
10
Syntax error
$ 

解决方法

line    : print term ';'

据此,有效行包含一个 print 标记,后跟一个 term。由于 term 必须是 T_INT_VAL 标记,这意味着有效行是 print 标记后跟 T_INT_VAL 标记。

您的输入仅包含一个 T_INT_VAL 标记,因此它不是有效行,这就是您收到语法错误的原因。

另请注意,您的词法分析器永远不会产生 print 标记,因此即使您输入 print 10 作为输入,这也是一个错误,因为词法分析器不会识别 {{1 }} 作为令牌。所以你也应该为此添加一个模式。

您还应该重命名 print 以匹配您的令牌命名约定(即 ALL_CAPS)。