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

如何用ANTLR4捕获Bash Here文档起止标识间的全部数据

解决ANTLR4识别Bash Here文档内容的问题

核心问题分析

ANTLR4当前会优先匹配IDENTIFIER规则,导致Here文档起止标识间的非标识符内容被当作无关输入,无法归入hereContent。本质是ANTLR4的最长匹配规则逻辑下,IDENTIFIER的优先级高于hereContent,干扰了内容捕获。

解决方案步骤

1. 用词法模式隔离Here文档解析

ANTLR4的词法模式(Lexical Modes)能让词法分析器在进入特定上下文时切换规则集,完全避开外部的IDENTIFIER等规则干扰。在词法文件中添加专用模式:

lexer grammar BashLexer;

// 默认模式
HereDocStart : '<<' IDENTIFIER -> pushMode(HERE_DOC);
IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]*;
// 其他默认词法规则(如运算符、空格等)...

// Here文档专属模式
mode HERE_DOC;
HereDocContent : ~[\r\n]+; // 匹配除换行外的所有内容
HereDocEnd : '\r'? '\n' IDENTIFIER -> popMode; // 结束标识需单独占一行,匹配后退出模式
NewLine : '\r'? '\n' -> skip; // 按需处理换行,若需保留可移除skip

2. 调整语法分析规则关联模式

在解析器文件中定义Here文档的语法规则,关联词法模式生成的token:

parser grammar BashParser;

options { tokenVocab=BashLexer; }

script : statement* EOF;
statement : hereDoc | otherStatement;
hereDoc : HereDocStart HereDocContent* HereDocEnd;
// 其他语句规则(如赋值、命令调用等)...

3. 适配Bash Here文档的特殊场景

  • 支持带引号的结束标识(如<<'EOF',内容不做变量替换):
    修改HereDocStart规则:
    HereDocStart : '<<' ( '\'' IDENTIFIER '\'' | '"' IDENTIFIER '"' | IDENTIFIER ) -> pushMode(HERE_DOC);
    
  • 处理内容中的换行保留需求:
    移除NewLine规则的skip,将换行纳入HereDocContent:
    HereDocContent : .+?; // 非贪婪匹配所有内容,直到遇到结束标识
    

验证方法

用以下测试用例验证解析效果:

cat <<EOF
Hello World!
This is a here doc with special chars: $@ ! *
EOF

检查生成的解析树,确认hereContent完整捕获起止标识间的所有内容,无截断或遗漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:32:37