ANTLR4在处理EOF时挂断

ANTLR4在处理EOF时挂断,antlr,antlr4,Antlr,Antlr4,我有一个简单的ANTLR4语法: grammar Test; preprocessing_file: oneline+; oneline: IDENTIFIER? new_line; new_line: EOF|CRLF ; WS: [ \t\f]+ -> channel(2); CRLF: '\r'? '\n'; IDENTIFIER: (NONDIGIT | DIGIT )+ ; fragment DIGIT: [0-9]; fragment NONDIGIT:

我有一个简单的ANTLR4语法:

grammar Test;
preprocessing_file: oneline+;

oneline: IDENTIFIER? new_line;

new_line: EOF|CRLF
;

WS: [ \t\f]+ -> channel(2);

CRLF: '\r'? '\n';


IDENTIFIER:  (NONDIGIT | DIGIT )+
; 
  fragment DIGIT: [0-9];
  fragment NONDIGIT: [_a-zA-Z]  ;
我正在测试如何使用换行规则,允许最后一行不被CRLF终止。我用ANTLRv4.1和v4.5.3测试了语法


几行文本的输入文件导致ANTLR4冻结,并在一段时间后导致OutOfMemoryException。看起来ANTLR4进入了一个无限循环。这是ANTLR4的错误吗?我做错什么了吗?另外,如果我在
new\u-line
规则中删除
EOF
,一切正常。

EOF[end of file]不应在new\u-line规则中。换衣服

oneline: IDENTIFIER? new_line
进入


如果需要验证,则在后续阶段验证是否存在新行

只需在主规则中添加一个
EOF
。没有它,主规则将永远不会终止-lexer将继续生成
EOF
令牌,这些令牌将被
new\u line
规则成功消费

preprocessing_file: oneline+? EOF ;
oneline: IDENTIFIER? new_line ;
new_line: EOF|CRLF ;

(1) 为什么规则中不允许EOF?它不是为我们创建的显式匹配文件结尾(2)的语法标识符可以是任何东西,但我的真正语法是非常具体的内容,并规定一个新的_行必须遵循它。因此,新的_线在这里不能是可选的。无论如何,ANLTR4没有理由挂起并在以后抛出内存异常。我不是说这是不允许的,只是没有真正的理由把它放在那里。把根规则放在最后,看看它是否有帮助,如果没有,肯定还有另一个错误。。。我没有在语法中看到任何语法/是整个语法吗?是的,整个语法,我只是排除了“语法xx”;线路。(我刚刚编辑了src以包含该行)。而且,如果在新的_行规则中没有EOF,ANTLR4可以正常工作,但无法匹配没有尾随CRLFThx的最后一行,这就是问题所在。我没有意识到,如果我们继续消费,lexer可能会产生无限多的EOF。但是你建议的解决方案行不通。真正的罪魁祸首是“一线”规则可能会无限期地匹配单个EOF,lexer也会无限期地输出。是否需要使用非贪婪运算符,即oneline+?除了额外的EOF
preprocessing_file: oneline+? EOF ;
oneline: IDENTIFIER? new_line ;
new_line: EOF|CRLF ;