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 ...
补充说明
- 规则顺序调整:把
BEGIN_EXPR放在STRING前面,确保ANTLR先尝试匹配比较运算符开头的内容。 STRING规则优化:~["<=>] ~["]*表示第一个字符不能是引号或比较运算符,后续可以是任意非引号字符,避免抢占BEGIN_EXPR的匹配机会。- 修正原代码拼写错误:将
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
相关产品推荐
相关产品推荐

