2013-07-18 5 views
3

내가 형태의 입력 ::ANTLR4 : 일치하지 않는 입력

다음
commit a1b2c3 
Author: Michael <[email protected]> 

commit d3g4 
Author: David <[email protected]> 

내가 쓴 문법입니다 일치하고 싶습니다 :

grammar commit; 

file : commitinfo+; 

commitinfo : commitdesc authordesc; 
commitdesc : 'commit' COMMITHASH NEWLINE; 
authordesc : 'Author:' AUTHORNAME '<' EMAIL '>' NEWLINE; 

COMMITHASH : [a-z0-9]+; 
AUTHORNAME : [a-zA-Z]+; 
EMAIL  : [[email protected]]+; 
NEWLINE : '\r'?'\n'; 
WHITESPACE : [ \t]->skip; 

위 파서의 문제가 있다는 것입니다을, 위의 입력에 대해 완벽하게 일치합니다. 그러나 입력에 변경하는 경우 : AUTHORNAME를 기대 8 일치하지 않는 입력 '마이클'

라인 2 :

commit c1d2 
Author: michael <[email protected]> 

이 같은 오류가 발생합니다.

토큰을 인쇄 할 때 'michael'문자열이 AUTHORNAME 대신 COMMITHASH 토큰과 일치하는 것으로 보입니다.

위의 사례를 수정하는 방법은 무엇입니까?

답변

4

ANTLR4은 작성된 순서에 따라 렉서 규칙을 일치시킵니다.

'michael'은 규칙 AUTHORNAME 따라서 오류가있는 전에 나타나는 규칙 COMMITHASH : [a-z0-9]+ ; 일치됩니다.

난 당신이 직면하고있는 문제를 해결하려면 다음 옵션을 생각할 수 있습니다 :

  • 당신은 ANTLR에 'mode' 기능을 사용할 수는 : ANTLR 4에서는 하나 개의 렉서 모드는 한 번에 활성화하고, 해당 모드 규칙에서 가장 길게 non-fragment lexer rule은 생성 된 토큰을 결정합니다. 문법은 기본 모드 만 포함하므로 모든 렉서 규칙이 활성화되어 일치하는 토큰의 길이가 COMMITHASHAUTHORNAME에 대해 동일하지만 COMMITHASH이 문법에 AUTHORNAME 앞에 나타나는만큼 '마이클'은 COMMITHASH과 일치합니다.

  • 문법에 나타나는 방식을 바꾸어 어휘 규칙을 변경할 수 있습니다. COMMITHASH 규칙에 항상 일치하는 숫자가 있다고 가정합니다. 다음과 같은 방법으로 COMMITHASH 전에 AUTHORNAME을 넣어 :

    grammar commit; 
    ... 
    
    AUTHORNAME : [a-zA-Z]+; 
    COMMITHASH : [a-z0-9]+; 
    ... 
    

참고 : 나는 강력하게 렉서 규칙이 파삭 파삭하게 기록되지 않습니다 느낀다. COMMITHASH 규칙이 [a-z0-9]+;이어야합니다. 'abhdks'과 같은 토큰도 COMMITHASH 규칙과 일치해야합니다. 하지만 그것은 전혀 다른 이슈입니다.

+0

안녕하세요, Rishabh, 감사합니다. 나는 렉시 컬 모드를 사용하여 그것을 해결했다. – Ramg

관련 문제