ANTLR4 DefaultErrorStrategy无法注入缺少的令牌
我尝试在TestRig中运行以下语法:ANTLR4 DefaultErrorStrategy无法注入缺少的令牌,antlr4,Antlr4,我尝试在TestRig中运行以下语法: grammar COBOLfragment; // hidden tokens WS : [ ]+ -> channel(HIDDEN); NL : '\n' -> channel(HIDDEN); // keywords PERIOD : '.'; DIVISION : 'DIVISION'; SECTION : 'SECTION'; DATA : 'DATA'; WORKING_STORAGE : 'WORKING-STORAGE'
grammar COBOLfragment;
// hidden tokens
WS : [ ]+ -> channel(HIDDEN);
NL : '\n' -> channel(HIDDEN);
// keywords
PERIOD : '.';
DIVISION : 'DIVISION';
SECTION : 'SECTION';
DATA : 'DATA';
WORKING_STORAGE : 'WORKING-STORAGE';
FILE : 'FILE';
FD : 'FD';
EXTERNAL : 'EXTERNAL';
GLOBAL : 'GLOBAL';
BLOCK : 'BLOCK';
CONTAINS : 'CONTAINS';
CHARACTERS : 'CHARACTERS';
// data
INTEGER : [0-9]+;
ID : [A-Z][A-Z0-9]*;
dataDivision :
DATA DIVISION PERIOD
fileSection?
workingStorageSection?
;
fileSection :
FILE SECTION PERIOD
fileDescription*
;
fileDescription :
FD fileName=ID
// (IS? GLOBAL)? // 1. IS GLOBAL clause
// (IS? EXTERNAL)? // 2. IS EXTERNAL clause
blockClause?
PERIOD
;
blockClause :
BLOCK CONTAINS? blockSize=INTEGER CHARACTERS
;
workingStorageSection :
WORKING_STORAGE SECTION PERIOD
;
通过以下输入:
DATA DIVISION.
FILE SECTION.
FD FD01
WORKING-STORAGE SECTION.
很明显,输入的第三行(“FD FD01”)缺少了fileDescription
规则中要求的终止符PERIOD
DefaultErrorStrategy
正确地确认了这一点,并召唤出丢失的令牌:
在stderr上显示正确的报告:行4:0缺失。'WORKING-STORAGE'
但如果已启用注释掉的片段(即,再次将子句“is EXTERNAL”和“is GLOBAL”引入语法),则单标记插入失败:
在stderr上显示误导性报告:第4行:0输入“工作存储”时没有可行的替代方案
如何使完整语法(带IS-EXTERNAL和IS-GLOBAL子句)保留更正缺少句点的能力?
旁注1:如果我启用IS EXTERNAL或IS GLOBAL,但不是两个子句,那么DefaultErrorStrategy
可以很好地工作并注入缺少的标记
旁注2:为启用两个子句的语法生成的代码具有以下额外代码(与仅启用其中一个子句的语法相比):
而
adaptivePredict()
调用是罪魁祸首,因为它在解析器有机会匹配(句点)
(在生成的代码中,而不是粘贴在这里)之前,在输入'WORKING-STORAGE'时抛出了没有可行的替代方法。我已经设法解决了它,为这两个is子句添加了一个新子句:
(此处仅更改了片段)
现在,DefaultErrorStrategy
开始工作,并注入缺少的时段
为什么不isClauses:(是全局的?)是外部的代码>
当然,我先试过了。但是得到了一个警告(警告(154):规则“fileDescription”包含一个可选块,其中至少有一个可选块可以匹配空字符串),并且没有插入缺少的句点
public final FileDescriptionContext fileDescription() ... {
...
try {
...
switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
case 1:
{
setState(31);
_la = _input.LA(1);
if (_la==IS) {
{
setState(30); match(IS);
}
}
setState(33); match(GLOBAL);
}
break;
}
...
}
catch (RecognitionException re) {
...
...
fileDescription :
FD fileName=ID
isClauses?
blockClause?
PERIOD
;
isClauses :
IS? GLOBAL (IS? EXTERNAL)?
| IS? EXTERNAL
;
...