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

如何用ANTLR4 Visitor捕获输入中here文档的全部数据?

解决ANTLR4解析Bash Here文档的匹配错误问题

核心问题拆解

line 9:4 mismatched input '<EOF>' expecting HERE_START 错误本质是:解析器进入Here文档的词法模式后,未能正确识别结束标记,导致到达文件末尾时仍处于未完成的解析状态,错误等待新的起始标记。


1. 修复词法规则的结束标记匹配逻辑

Bash Here文档要求结束标记必须是单独一行(无额外空白,除非用<<-允许前导制表符),你的词法规则可能未满足这个约束:

  • 若使用普通<<格式,结束标记规则需匹配整行:
    HERE_END: IDENTIFIER '\r'? '\n' -> popMode;
    
  • 若支持<<-的前导制表符,需允许前导\t:
    HERE_END: '\t'* IDENTIFIER '\r'? '\n' -> popMode;
    
    注意:起始标记的IDENTIFIER需和结束标记完全一致,确保大小写、字符完全匹配。

2. 确认词法模式切换的正确性

必须通过词法模式隔离Here文档内容,避免与其他语法冲突:

// 默认模式
HERE_START: '<<' [ \t]* IDENTIFIER -> pushMode(HERE_MODE);

// Here文档专属模式
mode HERE_MODE;
HERE_CONTENT: ~[\r\n]+; // 捕获单行内的所有内容(不含换行)
HERE_END: IDENTIFIER '\r'? '\n' -> popMode;
WS: [ \t]+ -> skip; // 若需要忽略内容内的空格,可添加此规则

确保进入HERE_MODE后,所有内部内容都被HERE_CONTENT或HERE_END捕获,不会触发默认模式的词法规则。

3. 修正解析器规则的结构

解析器规则需要明确Here文档的完整结构,同时确保顶层规则包含EOF以标记输入结束:

script: statement* EOF;
statement: here_doc | command | assignment; // 其他语句类型
here_doc: HERE_START HERE_CONTENT* HERE_END;

如果顶层规则缺少EOF,解析器可能无法判断输入是否结束,导致状态异常。

4. 验证测试输入的合法性

检查测试输入的结束标记是否符合要求:

结束标记必须与起始标记完全一致,且单独占一行,前后无任何空格、制表符(除非使用<<-格式)。例如起始标记是EOF,结束行不能是 EOF或EOF ,否则词法分析器无法匹配HERE_END。

5. 调试语法树的方法

使用ANTLR4的-gui选项生成可视化语法树,重点检查:

  • 词法标记的分类是否正确(如HERE_CONTENT是否捕获了所有中间内容)
  • 解析器是否在HERE_START后进入here_doc分支,是否因缺少HERE_END导致分支未闭合

内容的提问来源于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 16:05:57