ANTLR4在处理EOF时挂断
我有一个简单的ANTLR4语法: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:
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 ;