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

为何Bison无法匹配指定语法规则?Lex/Bison解析异常问题

6502汇编解析语法错误问题

现有定义与代码

Lex令牌定义

,[Yy] {
    return COMMAY;
}

(?xi:
    ADC|AND|ASL|BCC|BCS|BEQ|BIT|BMI|BNE|BPL|BRK|
    BVC|BVS|CLC|CLD|CLI|CLV|CMP|CPX|CPY|DEC|DEX|
    DEY|EOR|INC|INX|INY|JMP|JSR|LDA|LDX|LDY|LSR|
    NOP|ORA|PHA|PHP|PLA|PLP|ROL|ROR|RTI|RTS|SBC|
    SEC|SED|SEI|STA|STX|STY|TAX|TAY|TSX|TXA|TXS|
    TYA
) {
    yylval.str = strdup(yytext);
    for(char *ptr = yylval.str; *ptr = tolower(*ptr); *ptr++);

    return MNEMONIC;
}

\$[0-9a-fA-F]{2} {
    yylval.str = strdup(yytext);
    return ZEROPAGE;
}

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

Bison语法规则

expression:
    MNEMONIC '(' zp_identifier ')' COMMAY   { statement($1, $3,     "(zp),y"); }
|   MNEMONIC '(' zp_abs_identifier ')'      { statement($1, $3,     "(zp)"); }
;

zp_identifier:
    ZEROPAGE
|   IDENTIFIER
;

zp_abs_identifier:
    ZEROPAGE
|   ABSOLUTE
|   IDENTIFIER
;

测试代码

; absolute indirect
lda ($9000)
lda (steps) 

; zp indirect
lda ($90)
lda (gold)

问题描述

测试代码中的lda (steps)触发语法错误。按逻辑它应该匹配MNEMONIC '(' zp_abs_identifier ')'规则,但Bison会优先尝试匹配带COMMAY的规则,当后续没有COMMAY时匹配失败,且不会自动回溯尝试第二个规则。移除带COMMAY的规则后,解析可正常进行。

问题原因与解决方案

原因

Bison的LR解析器在处理歧义规则时,会优先选择定义顺序更早的规则。这里第一个expression规则是带COMMAY的变体,解析器遇到lda (steps)时,会先尝试匹配该规则,期望后续出现COMMAY令牌,但实际不存在,因此抛出语法错误。

解决方案

调整expression规则的顺序,把不带COMMAY的规则放在前面,让解析器优先匹配该规则:

expression:
    MNEMONIC '(' zp_abs_identifier ')'      { statement($1, $3,     "(zp)"); }
|   MNEMONIC '(' zp_identifier ')' COMMAY   { statement($1, $3,     "(zp),y"); }
;

这样当解析到lda (steps)时,会直接匹配第一个规则;而遇到带,y的指令(如lda ($10),y)时,解析器会在匹配完zp_identifier和)后,发现后续有COMMAY,从而回溯匹配第二个规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 04:55:06