2014-12-17 4 views
0

나는 antlr 3.1.3을 사용하고 파이썬 타겟을 생성하고 있습니다. 필자의 렉서와 파서는 매우 큰 파일을 허용합니다. 명령 줄 또는 동적 런타임 제어 매개 변수를 기반으로 인식 된 입력의 일부를 캡처하여 파싱을 일찍 중단하고 싶습니다. 예를 들어, 제 언어가 헤더와 본문으로 구성되어 있고 본문에 기가 바이트의 토큰이있을 수 있으며 머리글에만 관심이있는 경우 예외를 발생시키지 않고 렉서와 파서를 중지하는 규칙을 갖고 싶습니다. 성능상의 이유로 전체 본문을 읽지 않으려 고합니다.예외를 제기하지 않고 일찍 antlr 3 파서를 종료

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 규칙 관리자가 실패했습니다 : {not self.stopearly}?" 나는 예외를 제기하고 그것을 붙잡는 운이 더 있었다. – moof

0

이것은 파이썬 특정 답변입니다. 내 파서이 추가 :

@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