2014-12-15 3 views
0

내가 antlr4 코드 다음 한 구문 분석 :Antlr4 플로트

decnum returns [double value] : 
    NUMBER {$value = Double.parseDouble($NUMBER.text);} 
    ; 

POINT : '.'; 
INTNUMBER : ('0'..'9')+ ; 
NUMBER : INTNUMBER (POINT INTNUMBER)?; 

내가 String s = 1.2System.out.println(parser.decnum().value);을 할 때 제대로 작동합니다.

"0001.2000." 
"0001.2000.asfgheg" 
".0001.2000.37" 
"5.61345345ggdfhfjg" 

을 내가 뭘 잘못 "5"

에서 작동하지 않습니다뿐만 아니라 이들 문자열에서 작동?

또한 antlr4가 구문 분석에 실패해도 표현식을 평가하려고하는 이유는 무엇입니까? 나는 token recognition error을 얻었지만 평가 결과는 어쨌든 인쇄됩니다. 그것을 어떻게 해제 하는가?

답변

3

마지막 항목부터 시작 : 규칙의 일부로 평가를 포함했기 때문에 구문 분석이 성공했는지 여부가 평가됩니다. ANTLR 4를 사용하는 권장 방법은 단순히 구문 분석 트리를 작성한 다음 구문 분석이 완료된 후 청취자 및/또는 방문자를 사용하여 원하는 평가를 수행하는 것입니다. 예를 들어, decnum 규칙은 다음과 같아야합니다

decnum 
    : NUMBER 
    ; 

입력 "5"에 간다. 문법에 입력 문자 "이 포함되어 있지 않으므로이 입력은 위에 나열한 규칙과 일치하지 않습니다. ANTLR 4가이 문자에 도달하고 규칙이 일치하지 않으면, 문자를 건너 뛰고 다음 문자로 계속해서 복구됩니다. 이런 일이 처음 발생할 때, ANTLR 4는 다음 토큰을 찾기 위해 본질적으로 이것을 보게 될 것이다 : 5". ANTLR 4 5" 일치 시작되면

, 그것은 모두 INTNUMBERNUMBER 규칙 입력 5 일치하는지 판정하고, 어떤 룰이 긴 순서 5" 일치하지 않기 때문에,이 가장 긴 매치이다. ANTLR 4는 각 토큰에 하나의 토큰 유형 만 지정할 수 있으며, 이는 구문 분석 규칙이 토큰을보기 전에 수행됩니다. INTNUMBERNUMBER을 모두 5에 할당하는 대신 규칙이 문법에 나타나는 순서에 따라이 사례의 토큰 유형을 결정합니다. 즉 ANTLR 4는 이 아닌 INTNUMBER 토큰 인 5과 일치합니다.NUMBER 토큰입니다. 마지막으로, ANTLR 4는 첫 번째 문자를 생략 한 것과 같은 이유로 마지막 문자 인 "을 건너 뜁니다.

다른 문자열에 대해 유사한 평가 시퀀스가 ​​사용됩니다.예를 들어, "0001.2000.asfgheg"가 일치로 :

  • " : 무시 오류 (NO 경기)
  • . : POINT
  • 0001.2000 : NUMBER
  • . : POINT
  • a : 무시 오류 (NO 경기)
  • s : 무시 됨 e rror (일치하지 않음)
  • f : 무시 오류 (일치하지 않음)
  • g : 무시 오류 (NO 경기)
  • h : 무시 오류 (NO 경기)
  • e : 무시 오류 (NO 경기)
  • g : 무시 오류 (NO 경기)
  • " : 무시 오류 (NO 경기)

파서에 위의 내용은 POINT, NUMBER, POINT으로 나타납니다.

위에서 언급 한 건너 뛴 문자를 구문 분석 트리의 구문 오류로 포함하려면 다음을 렉서의 마지막 규칙으로 추가하면됩니다. 이 규칙은 모든 단일 문자와 일치하지만 다른 규칙은 일치하지 않습니다. 이는 규칙을 포함하지 않을 때 오류 복구 메커니즘이 정확히 일치하는 것입니다. 이 규칙은 오류 문자를 단일 ErrorCharacter 토큰으로 파서에 전달합니다.

ErrorCharacter 
    : . 
    ; 
+0

큰 설명 주셔서 감사합니다! 그러나, 나는 antlr을 빠 르게 만드는 방법을 이해하지 못했다. 정말로 입력이 일치하지 않으면 예외가 필요합니다. 오류 만 무시하려고 시도하면 예외가 발생합니다. 어떻게 구현할 수 있습니까? – Everv0id