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

时间:2014-12-17 21:15:23

标签: antlr antlr3

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

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';

2 个答案:

答案 0 :(得分:0)

怎么样:

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

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

答案 1 :(得分:0)

这是一个特定于python的答案。我将此添加到我的解析器中:

@parser::header
    {
    class QuitEarlyException(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
    }

并改变了这个:

body:
    BODY { if stopearly: raise QuitEarlyException('ok') }
    (STRING)*
    ;

现在我的解析器周围有一个“try”块:

try:
    parser.language()
except QuitEarlyException as e:
    print "stopped early"