2012-12-09 5 views
1

가 난 그냥 뭔가 두통을 만났다 문사용 ANTLR 문법 내가 예를 가지고있는 것처럼 나는, 다른 기능으로 문을 분할하려고 ..</p> <p>를 (함수는 같은 시작 항목이 있지만, 중간에 키워드를 가질 수있다)

start 
n turnTo 's'. 
n terminate. 
end 

문 모두 현재 내가 쓰고, 'N'로 시작

statement 
    : 
    (turnTo_statment|terminate_statment)* 
    ; 

turnTo_statment 
    : 
    variable 'turnTo' '\'' value '\'' '.' 
    ; 

terminate_statment 
    : 
    variable 'terminate' '.' 
    ; 

하지만 렉서 실행, 그것은 결정할 수없는 경우 베카있는 하나입니다 substatemts를 모두 사용하는 것은 'n'과 같은 것으로 시작하고, 컴파일러는 규칙을 사용하기 위해 다른 선택을해야합니다. 다음 문자열이 첫 번째 규칙 컴파일러와 일치하지 않으면 자동으로 일치하는 오류가 발생합니다.

'x turnTo y'를 만났을 때 ANTLR을 확인하고 말한 다음 'x terminated'를 만났을 때 turnTo_statment 규칙을 사용하면됩니다. 다음 규칙 terminate_statment을 사용 ..

즉, ANTLR의 모든 기능이 이렇게 ..

statement 
    : 
    ((if statement contain_keywords 'turnTO') -> turnTo_statment 
    | 
    (if statement contain_keywords 'terminate') ->terminate_statment)* 
    ; 

덕분에 ..

답변

3

먼저 구문 분석기 규칙에 '리터럴'을 사용하지 마십시오. ANTLR에서 많은 경험이 없으면 문제가 발생할 수 있습니다. 실제 렉서 규칙을 만듭니다

TURNTO: 'turnTo'; 

지금, 당신은 아마도 ANTLR 위키에있는 튜토리얼을 읽고 다운로드 예를 공부하고 그들을 이해 있는지 확인해야합니다. 문법 언어는 배우기가 쉽지 않기 때문에 좋은 문법을 작성하는 것은 쉽지만, 실제로는 많은 지식이 필요합니다. 그러나 렉서가 파서에 대한 지식이 없다는 것, 즉 입력 스트림을 토큰 화하여 파서에 전달하기 만하면 렉서 패턴을 모호하게 만들 수 없기 때문에 파서 규칙은 잠재적 인 차이를 처리 할 수 ​​있습니다.

ANTLR은 LL (1)로 변환하지 않고 ANTLR이 LL (k)를 처리 할 수 ​​있고 대개 k가 도움없이 작동하는 문법을 처리 할 수 ​​있습니다. 이게 너 문법 전체 야? 그러나 어쨌든 요인을 남기는 것이 가장 좋습니다.

statement: var (TURNTO {etc} | TERMINATE DOT) 
2

문법은 LL (1) 문법 아니다 (때문에, 알다시피, first(turnTo_statment) = first(terminate_statment)).

statement -> var_stmt statement 
var_stmt -> variable turnto_stmt | variable terminate_stmt 
turnto_stmt -> "turnTo" value 
terminate_stmt -> "terminate." 

내가 ANTLR에 대해 잘 모르겠지만,이 충돌의 이러한 종류의 거래의 전통적인 방법이다 : 당신은, 그러나, left-factoring하여 LL (1) 문법으로 변환 할 수 있습니다.