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

分数计算器Lexer分词异常:无空格分隔时无法识别FRACTION令牌

解决ANTLR词法分析器分数无空格分隔的分词异常问题

问题现象

当分数表达式无空格分隔时,词法分析器会错误地将部分内容合并为不符合规则的令牌,导致语法解析失败。

示例输入

2|1+4|1*5|2-18|5

错误信息

line 1:11 no viable alternative at input '2|1+4|1*5|2-18|5'

正确格式与预期输出

带空格输入:

2|1 + 4|1 * 5|2 - 18|5

预期输出:

42|5

已尝试的无效方案

  • 方案一:调整WS规则
FRACTION: '-'? [0-9]+ '|' [0-9]+;
WS: [ \t\r\n]+ -> skip;
  • 方案二:将运算符定义为单独令牌(完整语法见用户提供代码)

问题根源

核心是减号(MINUS)与分数负号的词法歧义:当-出现在数字/分数之后时,词法分析器错误地将其识别为后续分数的负号(合并进FRACTION令牌),而非作为减号运算符,导致令牌序列不符合语法规则;无空格时的拆分异常只是该歧义的外在表现。

解决方案

通过将负号处理从词法层移到语法层,消除歧义,同时确保运算符被正确识别:

修改后的完整语法

grammar FractionCalc;
@members {
    public static int count = 0;
}
prog
    : expr NEWLINE         { Console.WriteLine($expr.value); count++; }
    | NEWLINE
    | expr EOF             { Console.WriteLine($expr.value); count++; }
    ;
expr returns [Fraction value]
    : e1=expr PLUS e2=term  { $value = $e1.value + $e2.value; }
    | e1=expr MINUS e2=term { $value = $e1.value - $e2.value; }
    | t=term                { $value = $t.value; }
    ;
term returns [Fraction value]
    : t1=term MUL f=factor  { $value = $t1.value * $f.value; }
    | t1=term DIV f=factor  { $value = $t1.value / $f.value; }
    | f=factor              { $value = $f.value; }
    ;
factor returns [Fraction value]
    : MINUS f=factor       { $value = $f.value.Negate(); } // 处理一元负号
    | f=FRACTION            { $value = Fraction.Parse($f.text); }
    | LPAREN e=expr RPAREN  { $value = $e.value; }
    ;
// 移除FRACTION开头的负号,仅匹配正分数
FRACTION: [0-9]+ '|' [0-9]+;
PLUS: '+';
MINUS: '-';
MUL: '*';
DIV: '/';
LPAREN: '(';
RPAREN: ')';
NEWLINE: '\r'? '\n';
WS: [ \t]+ -> skip;

修改说明

  1. 调整FRACTION规则:移除开头的-,仅匹配正分数,从根源避免负号与减号的词法冲突。
  2. 添加一元负号语法分支:在factor规则中增加MINUS f=factor,通过语法逻辑处理负分数(调用Fraction的Negate方法实现取反)。
  3. 保留独立运算符令牌:确保+、-、*、/始终被识别为单独令牌,无论输入是否带空格,词法分析器都会正确拆分。

验证效果

输入无空格表达式2|1+4|1*5|2-18|5时,词法分析器会正确拆分为:
FRACTION(2|1), PLUS(+), FRACTION(4|1), MUL(*), FRACTION(5|2), MINUS(-), FRACTION(18|5)
语法解析可正常计算,输出预期结果42|5。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 02:27:08