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

Yacc/bison解析语法报错:IF分支遇到意外endif,期望接收分号

问题原因

报错的核心是未消除的移进/归约冲突:因作业要求不能使用优先级声明,当前语法规则存在二义性,Bison默认的移进策略和预期的IF语句匹配逻辑不符。解析完ELSE分支带分号的statement_后,Bison会错误判定外层语句已经结束,等待接收分号,不会继续移位匹配后续的ENDIF标记。

解决步骤

1. 排查冲突

运行以下命令生成Bison状态分析文件,确认冲突具体位置:

bison -Wconflicts-rr -Wconflicts-sr -v parser.y

生成的parser.output文件会明确标注所有移进/归约、归约/归约冲突,必须全部解决这些冲突才能保证语法解析符合预期。

2. 调整语法规则消除二义性

通过显式拆分「不带分号的基础语句」和「带分号的语句单元」消除IF语句的歧义,调整后的参考规则如下:

// 不带分号的基础语句:包括表达式、IF复合语句
statement:
    expression |
    IF expression THEN statement_with_semicolon ELSE statement_with_semicolon ENDIF
    ;

// 带分号的语句单元:用于块内的单个语句项
statement_with_semicolon:
    statement ';' |
    error ';'
    ;

// 表达式部分保持不变,左递归规则已经天然实现运算优先级,不需要额外优先级声明
expression:
    expression ANDOP relation |
    relation ;

relation:
    relation RELOP term |
    term;

term:
    term ADDOP factor |
    factor ;

factor:
    factor MULOP primary |
    primary ;

primary:
    '(' expression ')' |
    INT_LITERAL | 
    IDENTIFIER ;

如果你的语法中包含begin/end复合块规则,同步调整为匹配statement_with_semicolon序列即可:

compound_stmt:
    BEGIN statement_list END
    ;

statement_list:
    statement_with_semicolon |
    statement_list statement_with_semicolon
    ;

额外排查点

确认Flex词法规则中,所有关键字(IF、THEN、ELSE、ENDIF等)的匹配规则写在IDENTIFIER规则之前,避免关键字被错误识别为标识符。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:06:03