You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bison解析器始终输出无详情语法错误,求排查类Java指令块解析问题

问题根源及修复方案

你的解析器报错核心原因是语法规则、词法定义完全不匹配输入文件的结构,具体问题和修复步骤如下:

1. 关键问题拆解

(1)赋值语句规则过于局限

你定义的assignment_statement只接受 标识符 = 整数字面量; 的格式,但输入里大量出现:

  • 标识符赋值标识符(a = b;)
  • 带运算表达式的赋值(counter = counter - 1;、i = i + 1;)
    这些都不符合现有规则,直接触发语法错误。

(2)词法分析器缺失基础运算符定义

Flex代码里没定义+、-、*、/这些运算符,导致输入里的符号会被识别为未知字符,触发Unrecognized token错误,中断语法分析。

(3)语法规则未支持表达式逻辑

现有规则完全没处理counter-1、i/j这类运算表达式,只能处理最简单的自增自减和字面量赋值。

(4)程序入口不支持多个指令块

当前program规则只能匹配单个block或空输入,但你的输入有3个连续指令块,这也会导致语法错误。


2. 修复后的代码

(1)Flex 词法文件(parserlex.l)

补充缺失的运算符定义,完善细节:

%{
#include "parser.tab.h"
#include <stdlib.h> // 为strdup引入头文件
%}

%%

"{"                             { return '{'; }
"}"                             { return '}'; }
"="                             { return EQUAL; }
";"                             { return SEMICOLON; }
"++"                            { return PLUS_PLUS; }
"--"                            { return MINUS_MINUS; }
"+"                             { return PLUS; }
"-"                             { return MINUS; }
"*"                             { return MULTIPLY; }
"/"                             { return DIVIDE; }
[ \t\n\r]+                      ;  // 忽略空白字符

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

.                               { fprintf(stderr, "未识别的符号: %c\n", *yytext); return 0; }

%%

int yywrap() {
    return 1;
}

(2)Bison 语法文件(parser.y)

扩展语法规则,支持表达式、多block输入,添加成功提示:

%{
#include <stdio.h>
#include <stdlib.h>
%}
%union {
char * str;
}
%token IDENTIFIER
%token INT_LITERAL
%token PLUS PLUS_PLUS MINUS MINUS_MINUS EQUAL SEMICOLON
%token MULTIPLY DIVIDE
// 定义运算符优先级(从低到高)
%left PLUS MINUS
%left MULTIPLY DIVIDE

%%
program: /* empty */
       | program block       { printf("指令块验证成功!\n"); }
       ;

block: '{' statement_list '}'
      ;

statement_list: statement
              | statement_list statement
              ;

statement: assignment_statement
         | increment_statement
         | decrement_statement
         ;

assignment_statement: IDENTIFIER EQUAL expression SEMICOLON
                   ;

increment_statement: IDENTIFIER PLUS_PLUS SEMICOLON
                  ;

decrement_statement: IDENTIFIER MINUS_MINUS SEMICOLON
                  ;

// 定义表达式规则,支持标识符、字面量、加减乘除运算
expression: IDENTIFIER
          | INT_LITERAL
          | expression PLUS expression
          | expression MINUS expression
          | expression MULTIPLY expression
          | expression DIVIDE expression
          ;

%%

int yyerror (char *s) {
fprintf (stderr, "语法错误: %s\n", s);
}

int main() {
    if (yyparse() == 0) {
        printf("所有指令块解析完成,无语法错误!\n");
    }
    return 0;
}

3. 编译与测试步骤

  1. 生成语法分析器:
    bison -d parser.y
    
  2. 生成词法分析器:
    flex parserlex.l
    
  3. 编译可执行文件:
    gcc parser.tab.c lex.yy.c -o parser
    
  4. 运行测试:
    ./parser < 你的输入文件名
    

修改后,输入文件会被正确解析,每个合法指令块都会输出"指令块验证成功!",最终输出整体完成提示。

内容的提问来源于stack exchange,提问作者Gholem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:05:02