2017-10-18 14 views
1

ANTLR 4를 사용하여 Oracle DB의 일부 Select 문에 대한 간단한 문법을 ​​만들려고합니다. 그리고 작은 문제에 직면했습니다.

문법 & 렉서 COLUMN 선언 rankAnalytic 일부가Lexer 규칙은 필요하지 않은 곳에서 인식됩니다.

column 
: (tableAlias '.')? IDENT ((AS)? colAlias)? 
| expression ((AS)? colAlias)? 
| caseWhenClause ((AS)? colAlias)? 
| rankAggregate ((AS)? colAlias)? 
| rankAnalytic colAlias 
; 

colAlias 
: '"' IDENT '"' 
| IDENT 
; 

rankAnalytic 
: RANK '(' ')' OVER '(' queryPartitionClause orderByClause ')' 
; 

RANK: R A N K; 
fragment A:('a'|'A'); 
fragment N:('n'|'N'); 
fragment R:('r'|'R'); 
fragment K:('k'|'K'); 

가장 중요한 부분 : 나는 다음과 같은 문법을 가지고있다. 나는 Rank 문이 colAlias ​​여야한다고 선언했지만이 colAlias가 "rank"(따옴표 제외)와 같이 호출되는 경우 RANK 렉서 규칙으로 인식되지만 colAlias는 인식하지 않습니다.

그래서 경우 예를 들어, 나는 다음과 같은 텍스트가 :

SELECT fulfillment_bundle_id, SKU, SKU_ACTIVE, PARENT_SKU, SKU_NAME, LAST_MODIFIED_DATE, 
RANK() over (PARTITION BY fulfillment_bundle_id, SKU, PARENT_SKU 
order by ACTIVE DESC NULLS LAST,SKU_NAME) rank 

"순위"별명은 다음과 같은 오류가있는 실수로 밑줄 표시됩니다 :
일치하지 않는 입력 '순위'기대 { ' ", IDENT}
하지만 요점은 내가 렉스 렉서 단어로 인식되는 것이 아니라 Column의 별칭으로 순위를 지정하는 것입니다.
제안을 위해 엽니 다.

답변

1

규칙은 IDENT 규칙 위에 분명히 나타나므로 "랭크"문자열은 렉서에 의해 IDENT 토큰으로 방출되지 않습니다.

colAlias 
    : '"' (IDENT | RANK) '"' 
    | (IDENT | RANK) 
    ; 

영업 이익은 추가 :

간단한 수정은 colAlias 규칙을 변경하는 것입니다

Ok but in case I have not only RANK as a lexer rule but the whole list (>100) of such key words... What am I supposed to do?

colAlias 경우 말 그대로 아무것도 할 수 있습니다를, 다음을 보자 :

colAlias 
    : '"' .+? '"' // must quote if multiple 
    | .    // one token 
    ; 

모자 정의는 술어가 일치하는 자격을 필요, 모호성이 발생할 것 :

colAlias 
    : '"' m+=.+? '"' { check($m) }? // multiple 
    | o=.   { check($o) }? // one 
    ; 

기능적으로, 술어가 하위 규칙에 또 다른 요소입니다.

+0

좋아요. 그렇지만 렉서 규칙으로 만 RANK 할 필요는 없지만 그러한 핵심 단어의 전체 목록 (> 100) ... 내가해야 할 일은 무엇입니까? 위에 표시된 것처럼 모두 나열하십시오. 나는 그런 경우에 목록이 길다는 것을 생각하고 새로운 렉서가 추가 될 때마다 업데이트해야 할 것입니다. –

+0

업데이트 된 답변. – GRosenberg