Bison 解析器总是打印语法错误而不指定错误所在

问题描述 投票:0回答:1

大家好,我正在尝试为这个简单的 java 简单文件编写一个解析器,基本上我希望这个解析器能够识别和验证指令块。找到正确的指令块后,验证器将打印一条成功消息。

输入文件:

{ 
  a = b; 
}

{
  counter = counter- 1;
  i = i + 1;
}

{
  variable1 = i / j;
  variable2 = i * j;
  i++;
  j--;

}

但无论我尝试什么,我总是遇到语法错误

Bison parser.y 代码

%{
#include <stdio.h>
%}
%union {
char * str;
}
%token IDENTIFIER
%token INT_LITERAL
%token STRING_LITERAL
%token PLUS PLUS_PLUS MINUS MINUS_MINUS EQUAL SEMICOLON
%%
program: block
       | /* empty */
       ;
block: '{' statement_list '}'
      ;

statement_list: statement
              | statement_list statement
              ;

statement: assignment_statement
         | increment_statement
         | decrement_statement
         ;

assignment_statement: IDENTIFIER EQUAL INT_LITERAL SEMICOLON
                   ;

increment_statement: IDENTIFIER PLUS_PLUS SEMICOLON
                  ;

decrement_statement: IDENTIFIER MINUS_MINUS SEMICOLON
                  ;

%%

int yyerror (char *s) {
fprintf (stderr, "%s\n", s);
}

int main() {
    yyparse();
    return 0;
}

Flex parserlex.l 代码:

%{
#include "parser.tab.h"
%}

%%

"{"                             { return '{'; }
"}"                             { return '}'; }
"="                             { return EQUAL; }
";"                             { return SEMICOLON; }
"++"                            { return PLUS_PLUS; }
"--"                            { return MINUS_MINUS; }
[ \t\n\r]+                      ;  // Ignore white spaces

[a-zA-Z_][a-zA-Z0-9_]*           { yylval.str = strdup(yytext); return IDENTIFIER; }
[0-9]+                          { yylval.str = strdup(yytext); return INT_LITERAL; }

.                               { fprintf(stderr, "Unrecognized token: %s\n", yytext); return 0; }

%%

int yywrap() {
    return 1;
}

我不知道出了什么问题,因为我收到的唯一错误消息是“语法错误”,我什至不知道从哪里开始寻找潜在的解决方案。 我还尝试使用 bison -v 并读取 bison.output 文件,但它并没有给我带来太多帮助。任何帮助将不胜感激

gcc gnu bison flex-lexer
1个回答
0
投票

你的语法的一些明显的局限性:

  • 您的 assignment_statement 规则仅接受

    IDENTIFIER EQUAL INT_LITERAL
    ,因此除 rhs 上的常量之外的任何内容(例如
    a = b;
    - 输入中的第二行)都会给出语法错误

  • 您的顶级程序仅接受单个,因此在看到第二个块时会出现语法错误(如果它达到了那么远)。

为了帮助跟踪您的程序,您可以启用跟踪代码(通过使用 bison 的

-t
参数),并通过在调用
yydebug = 1
之前设置
yyparse()
将其打开。我更喜欢放类似的东西

if (getennv('YYDEBUG')) yydebug = 1;

在 main 的开头并始终使用

-t
(或 .y 文件顶部附近的
%define parse.trace
- 效果相同)。这样,如果您在运行程序之前在环境中设置
YYDEBUG
,它将打印一条跟踪信息。

© www.soinside.com 2019 - 2024. All rights reserved.