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

如何在ANTLR4中正常使用字符串内的保留关键字

解决方案

问题根源

ANTLR词法分析器遵循先定义优先匹配的规则:你把IF等关键字规则写在了普通字符/字符串规则前面,所以遇到符合关键字特征的文本会优先识别为关键字Token,而非普通字符或字符串内容。另外你当前的词法规则存在两个明显缺陷:

  1. 仅定义了单引号包裹的字符串字面量规则,没有定义双引号包裹的字符串规则,单独的DOUBLEQUOTES Token会导致双引号内部的内容被按普通规则拆分,自然会识别出关键字
  2. 把LETTER定义为独立Token而非片段,每个字母会被单独拆分为Token,连续字母匹配时会优先命中提前定义的关键字规则

方案1:修复字符串规则(解决引号内关键字被识别的问题)

如果你需要让引号内的所有内容都作为普通字符串、不需要拆分,直接在词法规则中新增完整的双引号字符串规则即可,字符串规则天然不会和字母开头的关键字规则冲突,内部内容会被整体识别:

// 放在词法规则任意位置即可,建议放在顶部
STRING_LITERAL_DOUBLE : '"' ( '\\"' | ~'"' )* '"';

调整后所有被双引号/单引号包裹的内容都会被识别为完整的STRING_LITERAL/STRING_LITERAL_DOUBLE Token,内部不会拆分出任何关键字。


方案2:优雅处理非引号场景下关键字作为普通词使用

你不需要逐个把所有关键字加到word规则里,可以按下面两步调整:

第一步:优化词法规则

把LETTER改为片段规则,新增标识符规则放在所有关键字的后面:

// 把原来的LETTER规则改成fragment,不再作为独立Token输出
fragment LETTER: [A-Za-z\u00e4\u00c4\u00d6\u00f6\u00dc\u00fc\u00df];
// 所有关键字规则的最后面加标识符规则,非关键字的连续字母会被识别为IDENTIFIER
IDENTIFIER: (LETTER | '_')+;

第二步:解析器层统一封装关键字规则

在解析器中定义一次keyword规则枚举所有关键字,之后所有需要用到普通词的位置直接引用即可,不需要重复列所有关键字:

// 只需要定义一次,后续新增关键字只更新此处即可
keyword: IF | ENDIF | ELSE | CASE | ENDCASE | BREAK | SWITCH | SUBSTRING;

word: ( symbolCharacters | IDENTIFIER | keyword )+ ;

可选优化:软关键字实现

如果你的关键字仅在特定语法上下文下生效,其他位置都作为普通词,可以在词法规则中添加动作动态修改Token类型,不需要在解析器层做任何处理,示例:

// 关键字规则加动作,非关键字上下文时自动转为IDENTIFIER类型
IF: I F { if(!isInKeywordContext()) setType(IDENTIFIER); };

你只需要自己实现isInKeywordContext()方法判断当前位置是否需要识别为关键字即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:45:00