我们知道Antlr4正在使用同步和返回恢复机制。例如,我有以下简单的语法:
grammar Hello;
r : prefix body ;
prefix: 'hello' ':';
body: INT ID ;
INT: [0-9]+ ;
ID : [a-z]+ ;
WS : [ \t\r\n]+ -> skip ;
我使用以下监听器来获取输入:
public class HelloLoader extends HelloBaseListener {
String input;
public void exitR(HelloParser.RContext ctx) {
input = ctx.getText();
}
}
我的HelloRunner中的主要方法如下所示:
public static void main(String[] args) throws IOException {
CharStream input = CharStreams.fromStream(System.in);
HelloLexer lexer = new HelloLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
HelloParser parser = new HelloParser(tokens);
ParseTree tree = parser.r();
ParseTreeWalker walker = new ParseTreeWalker();
HelloLoader loader = new HelloLoader();
walker.walk(loader, tree);
System.out.println(loader.input);
}
现在,如果我输入正确的输入"你好:1早上",我会按预期得到hello:1morning
。
如果输入不正确怎么办?"你好; 1早上"?我将得到以下输出:
line 1:6 token recognition error at: ';'
line 1:8 missing ':' at '1'
hello<missing ':'>1morning
似乎Antlr4自动识别出错误的令牌&#34;;&#34;并删除它;但是,它不会巧妙地添加&#34;:&#34;在相应的地方,但只是声称<missing ':'>
。
我的问题是:有没有办法解决这个问题,以便当Antlr发现错误时会自动修复它?如何实现这种编码?我们需要其他工具吗?
答案 0 :(得分:0)
通常,解析器的输入来自某个源文件,该文件包含一些(据称)符合某种语法的代码或文本。语法错误的典型使用场景是警告用户,以便纠正源文件。
如评论所述,您可以插入自己的错误恢复系统,但在尝试将单个令牌插入令牌流并恢复之前,请考虑它是非常有限的解决方案。为什么?考虑一个更丰富的语法,对于给定的令牌,许多 - 可能是几十或几百个 - 其他令牌可以合法地遵循它。单令牌替换策略如何工作呢?
hello.g4示例是一个简单语法的缩影,即#34; hello world&#34; ANTLR但大多数时候,对于非平凡的语法,我们用不完美的语法做的最好的事情就是简单地警告用户,以便纠正语法。