2012-03-25 5 views
2

파이썬 3의 AST 덤프 형식을 구문 분석하고이를 사용하기 쉬운 AST 형식으로 변환 할 수있는 문법을 작성하는 데 문제가 있습니다. 나는 이렇게하기 위해 ANTLR 문법을 작성하기로 결정했으나 키워드 블록을 처리하는 데 문제가 있습니다 (하지만 키워드 블록 만 사용). 나는 같이 키워드 문법을 절연 :가능한 ANTLR 문법 모호성 해결 (일반 개선 팁)

이이 키워드 규칙에 표시된 형식, 키워드 (쉼표로 구분와 0 이상)의 목록을 수용하도록 설계되어
grammar kwds; 
options {output=AST;} 

keywords: 'keywords=['((', '?)keyword)*']' -> keyword* 
    ; 

keyword : 'keyword(arg='STRING', value='str')' 
    ; 
str : 'Str(s='STRING')' -> STRING 
    ; 

STRING 
    : '\'' (ESC_SEQ | ~('\\'|'\''))* '\'' 
    ; 

fragment 
ESC_SEQ 
    : '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\') 
    | UNICODE_ESC 
    | OCTAL_ESC 
    ; 

EMPTYBRACKETS 
    : '[]'; 

fragment 
OCTAL_ESC 
    : '\\' ('0'..'3') ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') ('0'..'7') 
    | '\\' ('0'..'7') 
    ; 

fragment 
UNICODE_ESC 
    : '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
    ; 

fragment 
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ; 

.

위의 문법을 다음 (유효) 입력,

키워드 = [키워드 주면 (ARG = '이름'값을 = str을 (들 = 'UGA')), 키워드 (ARG = 'rank', value = Str (s = '2'))]

이 문법은이를 인식합니다.

그러나 필자가 작성한 "완전한"python 3 AST 형식 문법 (실제로는 공간 절약 목적으로 http://pastebin.com/ETrSVXvf에 있으며 위의 두 규칙은 각각 106 번과 109 번에서 찾을 수 있음)을 사용하면 실제로는

sample3.txt line 1:52 mismatched character 'e' expecting 'w' 
sample3.txt line 1:53 no viable alternative at character 'y' 
sample3.txt line 1:54 no viable alternative at character 'w' 
sample3.txt line 1:55 no viable alternative at character 'o' 
sample3.txt line 1:56 no viable alternative at character 'r' 
sample3.txt line 1:57 no viable alternative at character 'd' 
sample3.txt line 1:58 no viable alternative at character '(' 
sample3.txt line 1:59 missing ENDBR at 'arg=' 

난 단지 생각할 수 : 동일한 문법 규칙은 토큰 스트림은 키워드 규칙에 대해 구문 분석 할 때 다음과 같은 출력을 생성, 위의 예제에서 첫 번째 키워드 일치를 분석 한 후 떨어져 몇 문자를 것 같다 이것에 대한 한 가지 가능성 : 문법의 모호함으로 인해 뭔가 잘못 토큰되고 있습니다. 여러 키워드 문을 검색하는 데 사용 된 패턴이 다른 문법에서 작동하기 때문입니다 진술의 ype. 그러나, 나는 그 모호함이 실제로 문법에 어디에 있는지에 관해 완전히 몰두하고있다.

또한 일반적으로 내 문법을 개선 할 수있는 방법에 대한 일반적인 개선 사항도 알려 주시면 감사하겠습니다. 당신이 규칙을 추가하는 경우

답변

1

: 단순히 0 개 이상의 토큰을 일치하고 유형과 이러한 토큰의 텍스트를 출력

parse 
: (t=. {System.out.printf("type=\%-20s text='\%s'\n", tokenNames[$t.type], $t.text);})* EOF 
; 

을, 당신은 렉서이 예에서 입력 , keyword에 대처 할 수없는 것을 볼 수 있습니다 :

keywords=[keyword(arg='name', value=Str(s='UGA')), keyword(arg='rank', value=Str(s='2'))] 
               ^^^^^^^^^ 

따라서 파서 규칙 중 하나에는 문제가 없지만 어휘 수준에서는 문제가 발생합니다.

파서에서 모든 리터럴 토큰을 제거하고 그에 대한 렉서 규칙을 작성하는 것이 좋습니다. 그런 다음 적절한 토큰이 만들어 졌는지 확인하기 위해 렉서를 테스트 할 수있는 위의 게시판에 하나의 parse 규칙을 추가하십시오. 적절한 토큰이 만들어지면 파서 규칙을 작성하십시오. 렉서는 ', k' "을보고"한 번

내가 여기 문제가 당신이 ', keyword' 토큰이없는 사실입니다 확신, 그것은 물론, 실패 ', kwargs' 토큰을 만들려고합니다. 따라서 이 아닌은 토큰에 쉼표와 공백을 포함 시키되 자신의 토큰이되도록 할 것을 권장합니다.

stmtlist:  ((', '?) stmt)* -> stmt* 
     ; 

가능성이 전혀 일치하지 수 있습니다

또한,이 같은 재 작성 규칙을 가지고 싶지 않아. 이 경우 ANTLR은 AST를 작성하는 동안 예외를 발생시킵니다.

... 

tokens { 
    ... 
    STMTLST; 
    ... 
} 

... 

stmtlist:  ((', '?) stmt)* -> ^(STMTLST stmt*) 
     ; 
+0

아하, 내가 볼 : 항상 재 작성 규칙이 뭔가를 생성 할 수 있습니다. 그것은 렉서가 ',,' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''문자를 소비하는 방법 또한 재 작성 규칙에 대한 팁을 주셔서 감사합니다! – wibarr

+0

@ Webs961, 오신 것을 환영합니다. –