2014-11-29 6 views
0

OASIS 그룹이 제공하는 Antlr4에 OData v4 문법을 사용하려고합니다. 다음 링크를 참조하십시오. https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/grammar/ANTLR/#_trunk_spec_grammar_ANTLR_OData v4 문법에 파서 사용하기

이 파일들과 Antlr v4 Maven 플러그인을 기반으로 OData URL을 구문 분석하기위한 클래스를 성공적으로 생성했습니다. 아래에 설명 된대로

내가 파서를 사용하려고 : 방법 odataUri 호출 할 때

String expression = "http://192.168.1.1/odata/Category(1)/Products?$top=2&$orderby=name"; 
ANTLRInputStream in = new ANTLRInputStream(expression); 

ODataParserLexer lexer = new ODataParserLexer(in); 
ODataParserParser parser = new ODataParserParser(
      new CommonTokenStream(lexer)); 

ODataErrorListener errorListener = new ODataErrorListener(); 
parser.addErrorListener(errorListener); 

ODataParseListener listener = new ODataParseListener(); 
parser.addParseListener(listener); 

OdataUriContext ctx = parser.odataUri(); 

, 나는 오류 리스너에보고 된 다음과 같은 오류가 있습니다

line 1:66 mismatched input '<EOF>' expecting Protocol 

이것은 때문에 이상하다 렉서는 구문 분석 할 문자열의 토큰을 얻을 수 있습니다.

"http" 
"://" 
"192.168.1.1" 
"/" 
"odata" 
"/" 
"Category" 
"(" 
"1" 
")" 
"/" 
"Products" 
"?" 
"$top" 
"=" 
"2" 
"&" 
"$orderby" 
"=" 
"name" 

아마도 od odataUri는 파서에서 호출 할 수 없습니다. 그러나 파서 문법 파일을 읽은 후에는 그렇게 보입니다.

odataUri : Protocol ColSlaSla host (COLON port)? 
     serviceRoot 
     (ODataSignal_METADATA | ODataSignal_BATCH | odataRelativeUri)? EOF; 

Protocol : 

규칙 Protocol 찾을 수 없습니다 : -

12/01

에 편집 나는 규칙 이름에 문제가 있음을 발견했습니다. 이름을 으로 업데이트하면 훨씬 더 좋습니다 ...

바트의 조언에 이어 토큰과 관련된 규칙의 이름을 인쇄했습니다. Antlr4 메이븐 플러그인으로 생성 된, 나는 올바른 것을 얻을 수 없다. 고전 세대에서는 다음과 같이 표현했습니다.

"http" 
    index = 93, ODataParserLexer.tokenNames[index] = HTTPORHTTPS 
"://" 
    index = 92, ODataParserLexer.tokenNames[index] = ColSlaSla 
"192.168.1.1" 
    index = 23, ODataParserLexer.tokenNames[index] = Ls32 
"/" 
    index = 60, ODataParserLexer.tokenNames[index] = '/' 
"odata" 
    index = 4, ODataParserLexer.tokenNames[index] = 'odata' 
"/" 
    index = 60, ODataParserLexer.tokenNames[index] = '/' 
"Category" 
    index = 251, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR8 
"(" 
    index = 28, ODataParserLexer.tokenNames[index] = SubDelims 
"1" 
    index = 25, ODataParserLexer.tokenNames[index] = DecOctet 
")" 
    index = 28, ODataParserLexer.tokenNames[index] = SubDelims 
"/" 
    index = 60, ODataParserLexer.tokenNames[index] = '/' 
"Products" 
    index = 251, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR8 
"?" 
    index = 66, ODataParserLexer.tokenNames[index] = '?' 
"$top" 
    index = 128, ODataParserLexer.tokenNames[index] = ODataSignal_TOP 
"=" 
    index = 28, ODataParserLexer.tokenNames[index] = SubDelims 
"2" 
    index = 25, ODataParserLexer.tokenNames[index] = DecOctet 
"&" 
    index = 28, ODataParserLexer.tokenNames[index] = SubDelims 
"$orderby" 
    index = 126, ODataParserLexer.tokenNames[index] = ODataSignal_ORDERBY 
"=" 
    index = 28, ODataParserLexer.tokenNames[index] = SubDelims 
"name" 
    index = 250, ODataParserLexer.tokenNames[index] = ODATA_ID_CHAR4 

토큰 및 관련 규칙이 올바른 것처럼 보입니다.

또한 파서 (parser.setTrace(true))에서 추적을 활성화하고 내 코드를 다시 실행합니다. 난 여전히 당신의 도움을 주셔서 대단히 오류를

enter odataUri, LT(1)=<EOF> 
enter protocol, LT(1)=<EOF> 
line 1:66 mismatched input '<EOF>' expecting HTTPORHTTPS 
------------ 
Error on query : 
null 
=> line 1 : mismatched input '<EOF>' expecting HTTPORHTTPS 
Context : [590] 
exit protocol, LT(1)=<EOF> 
exit odataUri, LT(1)=<EOF> 

감사합니다. Thierry

+0

그 문법에는 나쁜 습관과 심지어는 오류까지있다. 당신이 SVN Repo에서 생성 한 파서로 작업하고 있다고 생각하지 않습니다. 내 생각에''http ''는'Protocol' 토큰으로 토큰 화되지 않습니다. 확실히하기 위해서는 단순히 렉서 토큰의 모든 토큰 타입을 출력하십시오. –

+0

Bart에게 감사드립니다. 멀리 볼 수있는 한, 토큰 # getType 메서드는 정수를 반환합니다. 해당 규칙을 (어떻게 ODataParserLexer # tokenNames 또는 ODataParserLexer # ruleNames를 사용하여) 얻을 수 있습니까? –

+0

바트, 내 질문 내용을 업데이트했습니다 ... –

답변

1

지정된 문법에는 많은 모호한 일치가 있으며 의미 적 조건 자나 렉서 모드를 사용하여 모호한 일치를 제거하기 위해 다시 작성해야했습니다. expamle (나는 문법 시작 규칙을 다시 썼다.) :

odataUri : serviceRoot? EOF ; 

serviceRoot : Protocol host segments relative? # OnSerivceRoot ; 

segments : Segments ; 

host   : (addr | regName) port?; 
addr   : ColSlaSla IPv4address ; 

regName  : HOST ; 

port   : PortDef ; 

relative : (ODataSignal_METADATA | ODataSignal_BATCH) | odataRelativeUri; 

odataRelativeUri : resourcePath (question queryOptions)?; 
question : QUESTION ; 


PortDef  : COLON Digits ; 
Segments : SLASH ((Unreserved | PctEncoded | SubDelims | COLON | AT_SIGN)+ SLASH)* ; 
HOST   : ColSlaSla HOST_DEF ; 
HOST_DEF  : (Unreserved | PctEncoded | SubDelims)+ ; 
QUESTION : '?'; 
Protocol : HttpOrHttpsAnyCase; 
Digits : Digit+ ; 
Digit : [0-9] ; 
Alpha : [a-zA-Z]; 
관련 문제