ANTLRWorks2中的 TestDriver 似乎有点挑剔,它什么时候会接受没有明确EOF
的语法,何时不接受。EOF
。 ANTLR4 Getting Started Guide中的 Hello 语法在任何地方均未使用EOF
,因此我推断如果可能,最好避免使用显式EOF
。
使用{{1}}的最佳做法是什么?你什么时候需要它?
答案 0 :(得分:22)
每当您尝试解析整个输入文件时,都应在输入规则的末尾包含显式EOF
。如果不包含EOF
,则表示您不是要尝试解析整个输入,如果它意味着避免语法错误,则只能解析部分输入。
例如,请考虑以下规则:
file : item*;
此规则意味着“尽可能多地解析item
个元素,然后停止。”换句话说,此规则永远不会尝试从语法错误中恢复,因为它总是假设语法错误是某些语法结构的一部分,超出了file
规则。甚至不会报告语法错误,因为解析器只会停止。
如果我有以下规则:
file : item* EOF;
意思是“文件完全由一系列零或多item
个元素组成。”如果在解析item
元素时出现语法错误,则此规则将尝试从语法错误中恢复(并报告)并继续,因为EOF
是必需的并且具有尚未到达。
对于只尝试解析部分输入的规则,ANTLR 4通常可以工作,但并非总是如此。以下问题描述了一个技术问题,即如果省略EOF
,ANTLR 4并不总是做出正确的决定。
https://github.com/antlr/antlr4/issues/118
不幸的是,此更改对性能的影响实际,因此在解决之前,会出现不符合您预期行为的边缘情况。