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

Antlr4报错:prog规则含可匹配空串的闭包分支,如何修复?

解决Antlr4中“rule prog contains a closure with at least one alternative that can match an empty string”报错

报错根源

问题出在compoundstatement规则的最后一个备选分支——你加了一个空选项(| ;),这让compoundstatement可以匹配空字符串。接着statements规则因为包含这个空分支的compoundstatement,也能匹配空内容。最终prog里的(statements)+闭包就存在“匹配空字符串”的可能,触发了Antlr的语法检查错误。

修复步骤

  1. 移除compoundstatement的空备选分支
    删掉compoundstatement里最后的| ;,让这个规则只能匹配三个有效分支中的一个,确保它永远不会匹配空内容。

  2. 验证所有子规则的非空性

    • simplestatement:由DOC(非空Token)+paramlist(带括号的参数列表,必然非空)组成,无法匹配空。
    • 修改后的compoundstatement:
      • TABLE paramlist tabledata TABLE:TABLE是非空Token,paramlist非空,tabledata至少包含一个tablerow(每个tablerow至少有一个元素),整体非空。
      • QUIZ paramlist .*? QUIZ和QUESTION paramlist .*? QUESTION:前后都有明确的Token标记,中间的非贪婪匹配也需要找到结束标记才会停止,不会匹配空。
    • statements只能是上述两种非空规则之一,因此(statements)+的每个循环都匹配非空内容,闭包不会出现空匹配问题。

修改后的完整语法

grammar new_g;

prog: (statements)+ | EOF ;

statements: simplestatement | compoundstatement ;

simplestatement:
  DOC paramlist  ;

compoundstatement:
  TABLE paramlist tabledata TABLE |
  QUIZ paramlist .*? QUIZ |
  QUESTION paramlist .*? QUESTION
  ;

paramlist: '(' param (',' param)* ')' ;

param: VAR '=' STR ;

tabledata: tablerow(':'tablerow )*;

tablerow: (INT|FLOAT|VAR|STR)(',' (INT|FLOAT|VAR|STR))* ;
// tokens
DOC: '%doc';
TABLE: '%table';
//COMMENT:'%c' ;
//GRAPH: '%graph';
QUIZ: '%quiz';
QUESTION: '%question';
INT: [0-9]+ ;
FLOAT: [+-]?([0-9]*[.])?[0-9]+ ;
//GVAR:[a-zA-Z_][a-zA-Z0-9_]* ; 
VAR:  [a-zA-Z_][a-zA-Z0-9_]* ; // abc123 a_123_xyZ
STR: '"'[a-zA-Z0-9., ]*'"';
//COMMENT_STR: '% ' .* ; 
WS: [ \r\n\t]+ -> skip;
//COMMENT_STR: '%c' ([\n] {skip();})? [a-zA-Z0-9., ]* '%c';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 16:24:57