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

ANTLR4语法中比较运算符匹配异常问题求助

问题分析与解决方案

问题原因

  1. 非法运算符组合被接受:ANTLR词法分析器采用最长匹配原则,但当输入包含多余字符(如===中的第三个=)时,剩余字符无法匹配任何词法规则,ANTLR默认会尝试错误恢复,跳过非法字符继续解析,导致非法组合看似被“接受”。
  2. 解析时丢失最后一个等号:以number !== value为例,词法分析会将!==拆分为!=(NEQ)和单独的=,而单独的=无对应词法规则,被解析器错误恢复机制忽略,最终丢失该字符。

修复步骤

1. 调整词法规则顺序(增强可读性)

将多字符运算符放在单字符运算符之前,虽然ANTLR优先按最长匹配处理,但此顺序更符合直觉,避免混淆:

GE: '>=' ;
GT: '>' ;
LE: '<=' ;
LT: '<' ;
EQ: '==';
NEQ: '!=' ;

2. 添加非法字符拦截规则

在词法规则末尾添加规则,匹配任何未被前面规则覆盖的字符并直接报错,阻止错误恢复:

INVALID_CHAR: . -> fail;

此规则会让词法分析器遇到非法字符(如单独的=、!)时立即终止并报错,避免解析器跳过错误继续执行。

3. 完整修复后的语法

grammar Filter;

filter: expr EOF ;

expr: expr 'and' expr
    | expr 'or' expr
    | 'not' expr
    | '(' expr ')'
    | compExpr
    ;
compExpr: ( operand (EQ | NEQ) operand )
        | ( numOperand (GT | GE | LT | LE) numOperand )
        ;
operand: qualifiedName | nodeId | STR | bool | numOperand ;
numOperand: INT | HEX | TIMESTAMP | qualifiedName ;
bool: TRUE | FALSE ;
qualifiedName: NAME ( '.' NAME )* ;
nodeId: SERIAL ;

// 多字符运算符优先定义
GE: '>=' ;
GT: '>' ;
LE: '<=' ;
LT: '<' ;
EQ: '==';
NEQ: '!=' ;

TRUE: 'true' ;
FALSE: 'false' ;
NAME: [a-zA-Z_$][a-zA-Z0-9_$]* ;
INT: '-'? DIGIT+ ;
STR: '"' (~["])* '"' ;
HEX: '0x' [0-9a-fA-F]+ ;
SERIAL: [0-9a-zA-Z]+ ;
TIMESTAMP: DIGIT DIGIT':'DIGIT DIGIT':'DIGIT DIGIT('.'DIGIT DIGIT DIGIT)? ;
DIGIT: [0-9] ;
WS  : [ \t\r\n]+ -> skip ;

// 拦截所有非法字符
INVALID_CHAR: . -> fail;

验证效果

  • 输入===:词法分析匹配==后,剩余的=触发INVALID_CHAR规则,直接报错,拒绝非法组合。
  • 输入number !== value:!==拆分为!=和=,=触发报错,不会丢失字符,而是提示非法输入。
  • 合法运算符(如==、>=)仍可正常解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:57:03