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