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

如何在ANTLR4中编写规则解析含用户自定义起止标记的字面量块

ANTLR4 自定义起止标记块语法实现方案

实现思路

这类需要配对自定义起止标识符的结构,可通过ANTLR4的词法模式+语义谓词组合实现,核心逻辑是在识别到起始标识符时暂存标记,匹配结束位置时校验是否和暂存的起始标记一致。

1. 词法规则定义

lexer grammar CustomBlockLexer;

// 全局默认模式:匹配非@开头的普通文本
PLAIN_TEXT: ~[@]+ ;
AT: '@' -> pushMode(AFTER_AT) ;

mode AFTER_AT;
// 匹配第二个@,归为AT类型,进入双@标识符匹配模式
SECOND_AT: '@' -> type(AT), pushMode(DOUBLE_AT_IDENT_MODE) ;
// 匹配单@后的起始标识符,暂存到词法状态,进入块内容模式
START_IDENT: [A-Za-z0-9_]+ {
    getInterpreter().setUserState(_input, getCharIndex(), getText());
} -> popMode, pushMode(BLOCK_CONTENT_MODE) ;

mode DOUBLE_AT_IDENT_MODE;
// 匹配双@后的起始标识符,暂存到词法状态,进入块内容模式
DOUBLE_AT_START_IDENT: [A-Za-z0-9_]+ -> type(START_IDENT), {
    getInterpreter().setUserState(_input, getCharIndex(), getText());
} popMode, popMode, pushMode(BLOCK_CONTENT_MODE) ;

mode BLOCK_CONTENT_MODE;
NEWLINE: '\r'? '\n' ;
// 语义谓词校验:仅当匹配内容和暂存的起始标识符一致时,才识别为结束标记
END_IDENT: [A-Za-z0-9_]+ {
    getText().equals(getInterpreter().getUserState(_input, getCharIndex()))
}? -> popMode ;
// 匹配块内普通内容
BLOCK_CONTENT: ~[\r\n]+? ;

2. 语法规则定义

parser grammar CustomBlockParser;
options { tokenVocab = CustomBlockLexer; }

root: (block | PLAIN_TEXT)* EOF ;

block: at_prefix START_IDENT NEWLINE block_content END_IDENT ;

at_prefix: AT | AT AT ;

block_content: (BLOCK_CONTENT | NEWLINE)* ;

规则校验说明

  • 合法场景:单@/双@@开头的标记,结束标识符和起始标识符完全一致时,可正常识别为完整块结构。
  • 非法场景:起止标识符不一致时,结束位置的字符串会被识别为普通BLOCK_CONTENT,解析器会因找不到匹配的END_IDENT抛出语法错误,正好匹配你给出的非法样例校验要求。

内容的提问来源于stack exchange,提问作者叶雨飞

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:15:02