英文:
Why does my Antlr give error: rule prog contains a closure with at least one alternative that can match an empty string to my grammar
问题
如何确保 prog
规则的任何子规则都不匹配空字符串?
英文:
I am using Antlr4 4.12 version for parser generator on Intellij IDE
My grammar :
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';
How can I make sure that no subrule for `prog rule matches any empty string
答案1
得分: 1
The |
operator in an ANTLR grammar can be read as an OR
.
Your compoundstatement
is formatted so that it reads more as an "alternative terminator":
compoundstatement:
TABLE paramlist tabledata TABLE |
QUIZ paramlist .*? QUIZ |
QUESTION paramlist .*? QUESTION |
;
If you use the ANTLR plugin for VSCode, it will reformat it as:
compoundstatement
: TABLE paramlist tabledata TABLE
| QUIZ paramlist .*? QUIZ
| QUESTION paramlist .*? QUESTION
|
;
This makes it pretty easy to see that the rule has a final alternative that matches "nothing" (a.k.a an "empty string").
This is the source of your error:
This corrects the warning:
compoundstatement
: TABLE paramlist tabledata TABLE
| QUIZ paramlist .*? QUIZ
| QUESTION paramlist .*? QUESTION
;
NOTE: reading |
as OR
also makes it clear that the prog
rule itself:
prog: (statements)+ | EOF;
is probably not what you intend. It says that it matches one or more statements
OR EOF.
It's a good practice to have any start rules consume all input through EOF, so you probably want:
prog: statements+ EOF;
(Maybe also consider renaming statements
to statement
as the rule only matches a single statement.)
英文:
The |
operator in an ANTLR grammar can be read as an OR
.
Your compoundstatement
is formatted so that it reads more as an "alternative terminator"
compoundstatement:
TABLE paramlist tabledata TABLE |
QUIZ paramlist .*? QUIZ |
QUESTION paramlist .*? QUESTION |
;
If you use the ANTLR plugin for VSCode, it will reformat it as:
compoundstatement
: TABLE paramlist tabledata TABLE
| QUIZ paramlist .*? QUIZ
| QUESTION paramlist .*? QUESTION
|
;
This makes it pretty easy to see that the rule has a final alternative that matches "nothing" (a.k.a an "empty string").
This is the source of your error:
This corrects the warning:
compoundstatement
: TABLE paramlist tabledata TABLE
| QUIZ paramlist .*? QUIZ
| QUESTION paramlist .*? QUESTION
;
NOTE: reading |
as OR
also makes it clear that the prog
rule itself:
prog: (statements)+ | EOF;
is probably not what you intend. It says that is matches one of more statements
OR EOF.
It's a good practice to have any start rules consume all input through the OEF, so you probably want:
prog: statements+ EOF;
(Maybe also consider renaming statements
to statement
as the rule only matches a single statement.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论