2017-03-01 4 views
0

한 패스 (전체 파일)에서 구문 분석 할 때 잘 작동하는 문법이 있습니다.ANTLR4 parsing subrules

이제 구문 분석을 구성 요소로 분해하고 싶습니다. 그리고 파서를 하위 규칙에 따라 실행하십시오. 나는 다음과 같은 규칙을 볼 하위 규칙을 구문 분석하는 등 가정 문제로 실행 : 위의 규칙이 모든 것이 잘 작동를 끝까지 구문 분석 최상위 시작 규칙에서 구문 분석

thing : LABEL? THING THINGDATA thingClause? 
      //{System.out.println("G4 Lexer/parser thing encountered");} 
     ; 
... 
thingClause : ',' ID (',' ID)? 
      ; 

. 하위 규칙 (EOF로 구문 분석되지 않음)으로 구문 분석 될 때 ","문자 또는 EOF 문자를 볼 것으로 예상되므로 구문절이 없을 때 파서가 뒤집습니다.

라인 8 : 0 일치하지 않는 입력 '%'기대 { ','}

내가 EOF에 구문 분석 할 때 최고 수준의 규칙을 찾습니다 때문에 % 올바르게, 또 다른 "일"구성 요소로 분석됩니다 :

toprule : thing+ 
      | endOfThingsTokens 
      ; 

그리고 endOfThingsTokens는 EOF 전에 발생합니다 ... 그래서 이것이 최상위 규칙이 작동하는 이유입니다.

서브 루어를 구문 분석 할 때 ANTLR4 파서가 % 토큰을 허용하거나 무시하고 "OK 우리는 thingClause가 표시되지 않습니다"라고 말한 다음 토큰 스트림을 재설정하여 다음 객체가 다른 것으로 구문 분석 될 수있게하려고합니다. 파서의 인스턴스.

이 특정 경우에 나는 렉서가 파서에 개행 문자를 전달하도록 변경할 수 있습니다. 필자는 현재 렉서 문법을 건너 뜁니다. 현재 필요하지 않은 토큰 스트림에 개행을 허용하려면 많은 변경이 필요합니다.

본질적으로 규칙에 "기록 끝"토큰을 만들기위한 방법이 필요합니다. 그러나 의미 론적 술어 규칙으로 이것을 해결할 방법이 있는지 궁금합니다.

뭔가 같은 :

thing : { if comma before %}? LABEL? THING THINGDATA thingClause? 
      | LABEL? THING THINGDATA 
      ; 
    ... 

    thingClause : ',' ID (',' ID)? 
      ; 

위 술어 의사 코드는 옵션 thingClause을 숨길 것인가? 파서가 특정 "end of thing"토큰 (즉, 개행)을 찾지 않고 하나의 "물건"을 파싱 한 후에 파서가 멈추도록 만족하지 않을 경우.

이 문제를 해결하면 답변을 게시합니다.

답변

1

구문 분석기는 현재 규칙을 만족시킬 수 있는지 판단하기 위해 토큰 스트림에서 미리 검색합니다. 그러면 해당 토큰이 사용됩니다. 미리보기 토큰이 사용되지 않으면 구문 분석기는 이러한 추가 및 미리보기 토큰을 사용하는 또 다른 규칙을 찾습니다.

요소가 일치하지 않으면 구문 분석기에서 사용되지 않은 토큰이됩니다. 따라서 오류가 표시됩니다.

파서의 look-ahead는 데이터에 따라 다릅니다. 규칙의 요소를 평가하면 현재 규칙이 소비 할 수있는 것보다 더 많은 토큰을 파서로 쉽게 읽을 수 있음을 의미합니다.

술어가 도움이 될 수 있지만 결정적으로 문제가되지는 않습니다. 즉, 파서가 프리디 케이드되지 않은 alt와 일치하더라도, 해당 alt에서 소비 할 수있는 것보다 더 많은 토큰을 파서에 읽을 수 있습니다.

이 비 결정론을 피하는 유일한 방법은 하위 규칙 경계의 토큰 스트림에 <EOF> 토큰을 미리 주입하는 것입니다.

+0

감사합니다. 나는 EOF를 사전 주입하기위한 일반적인 방법을 만드는 방법에 대해 생각 해왔다. 나는 TokenReWriter를 살펴 봤지만, 원래의 토큰 스트림을 파싱 한 후에 필자가 본 예제를 호출 한 것처럼 그것을 사용하고 싶지는 않습니다. 그러나 내가 원하는 곳에서 EOF 토큰을 주입하는 커스텀 토큰 스트림을 만드는 데 충분한 밧줄이 필요해 보인다. –

+0

죄송합니다. 귀하를 격려하지 않으 셨습니다. 이론적으로는 가능하지만 끔찍한 방법은 아닙니다. 훨씬 더 나은 선택은 문제를 확인하고 해결하여 간단한/표준 Antlr 구현을 사용하지 못하게 할 수 있습니다. – GRosenberg

+0

@RossYoungblood 당신이이 subrule과 일치하기를 원한다면 물론 끝에 'thingStandalone' 규칙을 만들 수 있습니다. –