2014-12-17 2 views
0

Я использую antlr 3.1.3 и создаю цель python. Мой лексер и парсер принимают очень большие файлы. Основываясь на управляемых параметрах командной строки или динамического времени выполнения, я хотел бы сначала зафиксировать часть распознанного ввода и прекратить синтаксический анализ. Например, если мой язык состоит из заголовка и тела, а тело может иметь гигабайты токенов, и меня интересует только заголовок, я хотел бы иметь правило, которое останавливает лексер и парсер без привлечения исключения. По соображениям производительности я не хочу читать все тело.exit antlr 3 parser early without raise exception

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

ответ

0

насчет:

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

?

Это использование синтаксического предиката для включения определенных частей языка. Я часто использую это, чтобы переключать языковые части в зависимости от номера версии. Я не уверен на 100%. Возможно, вам придется переместить предикат и следующий код в него в собственное правило.

+0

это работает для простой грамматики, за исключением что это напечатано: «строка 161: 0 правило admin failed predicate: {not self.stopearly}?" У меня было больше удачи, вызвав исключение и поймав его. – moof

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: 
    parser.language() 
except QuitEarlyException as e: 
    print "stopped early" 
+0

Это решение, но в названии конкретно говорится «без поднятия исключения». – Mephy