尽早退出antlr 3解析器而不引发异常

尽早退出antlr 3解析器而不引发异常,antlr,antlr3,Antlr,Antlr3,我正在使用Antlr3.1.3并生成一个python目标。我的lexer和解析器接受非常大的文件。基于命令行或动态运行时控制的参数,我希望捕获一部分已识别的输入并尽早停止解析。例如,如果我的语言由一个标题和一个正文组成,正文可能有千兆字节的标记,而我只对标题感兴趣,那么我希望有一个规则,可以在不引发异常的情况下停止lexer和parser。出于性能原因,我不想阅读整个正文 grammar Example; options { language=Python; k=2; } langu

我正在使用Antlr3.1.3并生成一个python目标。我的lexer和解析器接受非常大的文件。基于命令行或动态运行时控制的参数,我希望捕获一部分已识别的输入并尽早停止解析。例如,如果我的语言由一个标题和一个正文组成,正文可能有千兆字节的标记,而我只对标题感兴趣,那么我希望有一个规则,可以在不引发异常的情况下停止lexer和parser。出于性能原因,我不想阅读整个正文

grammar Example;

options {
  language=Python;
  k=2;
}

language:
    header
    body
    EOF
    ;

header:
    HEAD
    (STRING)*
    ;

body:
    BODY { if stopearly: help() }
    (STRING)*
    ;

// string literals
STRING: '"'
    (   
        '"' '"'
    |   NEWLINE
    |   ~('"'|'\n'|'\r')
    )*
    '"'
    ;

// Whitespace -- ignored
WS:
    (   ' '
    |   '\t'
    |   '\f'
    |   NEWLINE
    )+ { $channel=HIDDEN }
    ;

HEAD: 'head';
BODY: 'body';
fragment NEWLINE: '\r' '\n' | '\r' | '\n';
那么:

body:
    BODY {!stopearly}? => (STRING)*
;
?


这就是使用句法谓词来启用某些语言部分。我经常使用它来根据版本号切换语言部分。我不是100%肯定。您可能需要将谓词及其后面的代码移动到自己的规则中。

这是一个特定于python的答案。我在解析器中添加了以下内容:

@parser::header
    {
    class QuitEarlyException(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
    }
try:
    parser.language()
except QuitEarlyException as e:
    print "stopped early"
并改变了这一点:

body:
    BODY { if stopearly: raise QuitEarlyException('ok') }
    (STRING)*
    ;
现在,我的解析器周围有一个try块:

@parser::header
    {
    class QuitEarlyException(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
    }
try:
    parser.language()
except QuitEarlyException as e:
    print "stopped early"

这适用于简单语法,只是打印了以下内容:第161行:规则管理失败谓词:{not self.stoppearly}?我更幸运地提出了一个异常并抓住了它。这是一个解决方案,但标题明确地说没有提出异常。