2013-08-21 2 views
0

나는 AST를 생성하고 모든 모호성을 해결하기 위해 그것을 다시 작성한 다음 그것을 걷고 결과를 계산한다. 개서트리 재 작성 문법의 ANTLR3 의미 론적 술어

한 부분 ID가 나타내는 변수의 종류에 따라 또는 ^(DECIMALQUERY ID)^(DATEQUERY ID)^(QUERY ID) 같은 노드의 변환이다. type 값에 기초한다

query 
    : ^(QUERY ID) 
    { 
     var type = GetQueryType($ID.text); 
    } 
    -> { type == QueryType.Decimal }? ^(DECIMALQUERY ID) 
    -> { type == QueryType.Date }?  ^(DATEQUERY ID) 
    -> { type == QueryType.String }? ^(STRINGQUERY ID) 
; 

QUERY 토큰 DECIMALQUERY, DATEQUERY 또는 STRINGQUERY로 변환된다.

문제는 ANTLR이이 문법의 코드 생성을 거부한다는 것입니다. 명령은 다음과 같습니다

java -jar ..\..\binaries\antlr-3.4-complete.jar -message-format vs2005 .\TreeTransform.g 

그리고 오류 :

.\TreeTransform.g(54,2) : error 100 : syntax error: antlr: MismatchedTokenException(52!=84) 
.\TreeTransform.g(53,52) : error 100 : syntax error: assign.types: NoViableAltException([email protected][]) 
org\antlr\grammar\v3\DefineGrammarItemsWalker.g: node from line 53:51 no viable alternative at input ')' 
.\TreeTransform.g(53,52) : error 100 : syntax error: buildnfa: NoViableAltException([email protected][]) 
.\TreeTransform.g(53,52) : error 100 : syntax error: codegen: NoViableAltException([email protected][]) 
.\TreeTransform.g(53,52) : error 100 : syntax error: antlr.print: NoViableAltException([email protected][]) 
.\TreeTransform.g(53,52) : error 100 : syntax error: antlr.print: NoViableAltException([email protected][]) 

하지만 마지막 의미 술어를 제거 할 때, 모든 작품 :

query 
    : ^(QUERY ID) 
    { 
     var type = GetQueryType($ID.text); 
    } 
    -> { type == QueryType.Decimal }? ^(DECIMALQUERY ID) 
    -> { type == QueryType.Date }?  ^(DATEQUERY ID) 
    ->         ^(STRINGQUERY ID) 
; 

그러나 나는 아이디어를 좋아하지 않는 string이 '기본'분기입니다. 세 가지 조건 중 어느 것도 true가 아닌 경우 (즉, 새로운 형식이 열거 형에 추가되었지만 문법에 추가되지 않은 경우), 예외가 발생합니다. 마지막 조건자를 제거하면 문자열로 모두 폴백합니다.

는 그래서, 내 질문은 :

어떻게 명시 적으로 이러한 유형의 기반 스위칭을위한 모든 경우를 지정합니까? 세 가지 대안 중 어느 것도 충족되지 않으면 예외를 강제 적용 할 수있는 방법이 있습니까?

전체 파서와 트리 변압기 문법

현재 위치 :

-> { type == QueryType.Decimal }? ^(DECIMALQUERY[$QUERY] ID) 
-> { type == QueryType.Date }?  ^(DATEQUERY[$QUERY] ID) 
-> { type == QueryType.String }? ^(STRINGQUERY[$QUERY] ID) 
->         ^(INVALIDQUERY[$QUERY] ID) 

그런 경우 어디를보고 할 수 있습니다 :

https://bitbucket.org/ik/public/src/8f91e683e79a084138d6b55beabf8d5e18d965d4/AntlrSemanticPredicatesProblem?at=default

답변

1

제정신 오류 메시지의 최대 지원을 위해, 당신은 다음을 사용한다 INVALIDQUERY은 파서가 실패하지 않고 트리에 나타납니다.

추 신 : [$QUERY] 인수를 추가하면 토큰 행/열 정보가 다시 작성된 트리에 유지됩니다.

+0

가장 깨끗한 것으로 보입니다. 그러나 여전히 변혁의 과정에서 예외를 제기하고 예외를 적용 할 수있는 방법이 있습니까? '-> {throw new InvalidQueryException();}'처럼? –