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的语法检查错误。
修复步骤
移除
compoundstatement的空备选分支
删掉compoundstatement里最后的| ;,让这个规则只能匹配三个有效分支中的一个,确保它永远不会匹配空内容。验证所有子规则的非空性
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
相关产品推荐
相关产品推荐

