【问题标题】:ANTLR4 Hangs Up When Dealing with EOFANTLR4 在处理 EOF 时挂断
【发布时间】:2016-08-24 17:57:33
【问题描述】:

我有一个简单的 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 终止的换行规则。我用 ANTLR v4.1 和 v4.5.3 测试了语法。

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

【问题讨论】:

    标签: antlr antlr4


    【解决方案1】:

    EOF [文件结尾] 不应在 new_line 规则中。换个方式

    oneline: IDENTIFIER? new_line
    

    进入

    oneline: IDENTIFIER? new_line?
    

    如果需要验证,则在后续阶段验证 new_line 的存在

    【讨论】:

    • (1) 为什么规则中不允许EOF?它不是为我们创建的,以显式匹配此语法中的文件结尾(2) IDENTIFIER 可以是任何东西,但我真正的语法对内容非常具体,并且规定 new_line 必须遵循它。所以 new_line 在这里不能是可选的。无论如何,ANLTR4没有理由挂起并稍后抛出OutOfMemoryException
    • 我并不是说不允许,只是说没有真正的理由把它放在那里。把根规则放在最后,看看是否有帮助,如果没有,一定是另一个错误……我在语法中没有看到任何/是整个语法吗?
    • 是的,整个语法,我只是排除了“语法 xx”;线。 (我刚刚编辑了 src 以包含该行)。而且,如果 new_line 规则中没有 EOF,ANTLR4 可以正常工作,但无法匹配我没有尾随 CRLF 的最后一行
    【解决方案2】:

    只需要在主规则中添加一个EOF。没有它,主规则将永远不会终止 - 词法分析器将继续生成 EOF 标记,这些标记被 new_line 规则成功使用。

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

    【讨论】:

    • 谢谢,这就是问题所在。我没有意识到如果我们继续使用它,词法分析器可能会产生无限多的 EOF。但是您建议的解决方案不起作用。真正的罪魁祸首是“单行”规则可以无限期地匹配单个 EOF,而词法分析器也会无限期地输出。需要使用非贪婪运算符,即 oneline+?除了额外的 EOF
    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 2019-09-21
    • 2017-04-05
    • 2013-08-10
    • 2018-01-22
    • 2022-10-06
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多