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

ANTLR4解析带引号多格式字符串遇模式切换问题求助

ANTLR4词法解析问题:匹配带比较运算符的引号内字符串

我有多种以双引号开头和结尾的输入字符串,引号内的内容需被分配至特定类型,示例包括:

  • "Simple text"
  • "Field20"
  • ">=20"
  • ">20<=10"
  • "20"

现有Lexer.g4代码如下:

...
WQ: '"' -> pushMode(IN_STRING) ;
DIGIT: [0-9]+ ;
...
mode IN_STRING;
DQUOTE_IN_STRING: '"' -> type(WQ), popMode ;
BEGIN_EXPR: [<=>]+ -> pushMode(EXP) ;
STRING: ~["]+;

mode EXP;
DQUOTE_IN_EXP: '"' -> type(WQ), mode(DEFAULT_MODE) ;
COMPARE_EXPR: [<=>]+ ;
EXPESSION: DIGIT+ ;
...

解析词法流时无法进入EXP模式,原因在于STRING规则匹配了包含比较字符的内容,不清楚如何定义规则让STRING不匹配以比较字符开头的序列,恳请提供建议或其他解析这些示例的方法。


核心问题分析

ANTLR词法规则遵循最长匹配和先定义先匹配原则,当前STRING: ~["]+会匹配所有非引号字符,包括以<=>开头的内容,导致BEGIN_EXPR永远没有匹配机会。

修正方案

调整IN_STRING模式下的规则顺序,优先匹配以比较运算符开头的序列,同时限制STRING规则不匹配以<=>开头的内容:

...
WQ: '"' -> pushMode(IN_STRING) ;
DIGIT: [0-9]+ ;
...
mode IN_STRING;
DQUOTE_IN_STRING: '"' -> type(WQ), popMode ;
// 优先匹配以比较运算符开头的序列,进入EXP模式
BEGIN_EXPR: [<=>]+ -> pushMode(EXP) ;
// 匹配不以<=>开头的非引号字符串
STRING: ~["<=>] ~["]*;

mode EXP;
DQUOTE_IN_EXP: '"' -> type(WQ), mode(DEFAULT_MODE) ;
COMPARE_EXPR: [<=>]+ ;
EXPRESSION: DIGIT+ ; // 修正原拼写错误EXPESSION
...

补充说明

  1. 规则顺序调整:把BEGIN_EXPR放在STRING前面,确保ANTLR先尝试匹配比较运算符开头的内容。
  2. STRING规则优化:~["<=>] ~["]*表示第一个字符不能是引号或比较运算符,后续可以是任意非引号字符,避免抢占BEGIN_EXPR的匹配机会。
  3. 修正原代码拼写错误:将EXPESSION改为EXPRESSION,避免语法错误。

另一种简化思路:合并模式处理

如果不需要单独的EXP模式,可在IN_STRING模式内直接定义所有可能的token类型,简化逻辑:

...
WQ: '"' -> pushMode(IN_STRING) ;
...
mode IN_STRING;
DQUOTE_IN_STRING: '"' -> type(WQ), popMode ;
// 匹配表达式类内容:比较运算符+数字的组合
EXPR: ([<=>]+ DIGIT+)* ([<=>]+ DIGIT+)? ;
// 匹配普通字符串
STRING: ~["]+;
...

这种方式下,ANTLR会优先匹配更长的EXPR序列(符合模式时),否则匹配STRING,同样能区分不同类型的引号内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:52:17