2013-05-31 2 views
0

놀랍습니다. 프로젝트 용 언어 파서와 유사한 SQL을 작성하고 있습니다.Antlr 3 개의 키워드와 식별자가 충돌합니다.

나는 대부분 작동하지만, 실제 요청에 대해 테스트하기 시작했을 때 핸들링이 될 것이므로 생각보다 내부에서 다르게 동작한다는 것을 알았습니다.

다음과 같은 문법의 주요 문제

내가 언어 키워드 ' pct_within'에 대한 PCT_WITHIN 렉서 규칙 을 정의하는 것입니다. 이것은 잘 작동하지만 내가 'attributes.pct_vac'처럼 필드를 일치하려고하면, 나는 'attributes.ac'와 꽤 ANTLR 오류의 텍스트 갖는 필드를 얻을 :

line 1:15 mismatched character u'v' expecting 'c' 

문법을

grammar Select; 

options { 
    language=Python; 
} 

eval returns [value] 
    : field EOF 
    ; 

field returns [value] 
    : fieldsegments {print $field.text} 
    ; 

fieldsegments 
    : fieldsegment (DOT (fieldsegment))* 
    ; 

fieldsegment 
    : ICHAR+ (USCORE ICHAR+)* 
    ; 

WS      : ('\t' | ' ' | '\r' | '\n')+ {self.skip();}; 

ICHAR     : ('a'..'z'|'A'..'Z'); 

PCT_CONTAINS   : 'pct_contains'; 

USCORE     : '_'; 
DOT      : '.'; 

나는이 주제에서 찾을 수있는 모든 것을 읽었습니다. 렉서가 틀린 경우에도 렉서가 그것을 발견 할 때 소비하는 방법. 의미 론적 예측을 사용하여 모호성을 제거하는 방법/미리보기를 사용하는 방법. 그러나 내가 읽은 모든 것이이 문제를 해결하는 데 도움이되지 못했습니다.

정직하게도 어떻게 문제가 될지 모르겠다. 나는 존재하지만 그 파서가 'existsOrNot'와 같은 문자열을 가지고 뱉어 발생하지 않고 을 '의 텍스트 IDENTIFIER 같은 렉서 규칙이 참조 다른 문법 때문에 슈퍼 분명 뭔가 빠진해야 rNot '입니다.

무엇이 잘못되었거나 완전히 잘못 되었습니까?

답변

1

필드 구분 파서 규칙을 렉서 규칙으로 변환하십시오. 지금 그대로 서면

"abc  
_  abc" 

과 같은 입력을 받아 들일 것입니다. 이는 아마도 원하는 것이 아닙니다. 키워드 "pct_contains"는 별도로 정의되었으므로이 규칙과 일치하지 않습니다. 특정 순서의 키워드를 정규 식별자로 사용하려면 허용 된 식별자 규칙에 키워드를 포함시켜야합니다.

+0

답장을 보내 주셔서 감사합니다. 그것은 그것을 고칠 수 있습니다 (천천히 문법의 나머지 부분을 추가하고 테스트). 이 작품을하더라도, 나는 여전히 혼란 스럽다. 왜 내 문법은 렉서가 pct_vac을 보지 않고 '이것은 pct_within 토큰이 아니며 여러 ICHAR 토큰을 방출하겠다'고 말하면서 대신 '자기 자신을 쏜다'라고 말했습니까? –

+1

밑줄을 포함한 식별자와 일치하는 렉서 규칙이 없습니다. 따라서 렉서는 "pct_vac"(namley PCT_CONTAINS)와 일치하는 규칙 만 갖고 있습니다. 이 작업은 실패하므로 오류가 발생합니다. fieldsegment를 렉서 룰로 만들면 이제 "pct_vac"와 일치하는 룰이 자체 규칙으로 정의되어 있으므로이를 수정할 수 있습니다. –

+0

이것은 내 지식에 대한 실질적인 부족함을 드러낸다. 나는 그것이 pct_contains와 일치하지 않을 것이고 대신 ICHAR 토큰, USCORE 토큰, 그리고 더 많은 ICHAR 토큰을 출력한다고 가정했다. –