2011-09-07 3 views
2

작은 표현식 언어를 구문 분석해야하므로 (예 : 변경 우선 순위가 변경됨) 작업에 대해 ANTLR을 선택 했으므로 좋은 진행률을 보였습니다. ANTLRWorks는 초보자에게 아주 좋습니다.) 나는 ANTLR 웹 사이트에서 일부 받기 시작 참조를 사용하고 난 달성하기 위해 노력하고 무엇을 완벽하게 맞지는 두 개의 블로그 게시물을 발견 :모든 ANTLR 문법은 "입력 할 때 실행 가능한 대안이 없습니다. <EOF>" "

http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx http://www.alittlemadness.com/2006/06/05/antlr-by-example-part-1-the-language

오전 데 문제가 아무리없는 것을 입력 I 난 항상 오류 얻을 넣어 :

라인을 1시 29분 내가 알고 문법이 좋았다 시도하기로 결정에서 렉서/파서를 생성 내 문제 해결의 일환으로 입력 'EOF'그래서

에서 어떤 대안이 없다 처음에 발견 된 ECalc.g 문법 링크. 놀랍게도 그 문법을 사용할 때 같은 오류가 발생했습니다! 나는 속인다. 문법에 대한 유일한 변경 사항은 Java 코드를 생성하고 @members 섹션에서 일부 CSharp 코드를 추출하는 것입니다. 이 문법에서 발생 이유를 알아낼 수 있다면

Token: ‘false’ 
Token: ‘ ’ 
Token: ‘||’ 
Token: ‘ ’ 
Token: ‘not’ 
Token: ‘ ’ 
Token: ‘(’ 
Token: ‘false’ 
Token: ‘ ’ 
Token: ‘and’ 
Token: ‘ ’ 
Token: ‘true’ 
Token: ‘)’ 
line 1:29 no viable alternative at input '<EOF>' 
0 [main] DEBUG ECalcTester - <unexpected: [@0,29:29='<EOF>',<-1>,1:29], resync=> 

하는 것이 좋겠 내가 그림을 할 수 있어야한다 : 여기

public class ECalcTester { 
private final static Logger logger = Logger.getLogger(ECalcTester.class); 

public static void main(String[] args) { 
    BasicConfigurator.configure(); 
    ECalcLexer lex = new ECalcLexer(new ANTLRStringStream("false || not (false and true)")); 

    Token token; 
    while (true) { 
     token = lex.nextToken(); 
     if (token.getType() == Token.EOF) { 
      break; 
     } 

     System.out.println("Token: ‘" + token.getText() + "’"); 
    } 

    CommonTokenStream tokens = new CommonTokenStream(lex); 
    lex.nextToken(); 

    ECalcParser parser = new ECalcParser(tokens); 
    try { 
     logger.debug(parser.expression().getTree()); 
    } catch (org.antlr.runtime.RecognitionException e) { 
     logger.error("Exception ", e); 
    } 

} 

이 출력됩니다 : 여기

내 테스터 클래스 왜 내 문법 (매우 비슷한 개념)에서도 똑같은 일이 일어난다.

아무도 통찰력을 제공 할 수 있습니까?

+1

렉서 토큰 스트림을 재설정해야 할 수 있습니까? 당신이 모든 토큰을 통과하고 파서가 첫 번째로 움직이는 순간에 luketorjussen

+0

* 부끄러움에 머리가 매달 리다. 예, 그렇습니다. 나는 lex.reset()을 한숨 돌릴 필요가있었습니다. 나는 그 방법에 대해 알지 못했던 그런 새다. 비록 그것을 반복해야만하는 스트림이라는 것을 알았지 만 그것을 재설정 할 필요가 있다고 생각 했어야했다. 꽤 일반적인 개념이었다. – Michael

+0

좋은 소식은 이것으로 내가 가지고있는 문제가 해결된다는 것입니다. 그러나 이것은 내가 문법을 가지고있는 문제를 해결하지 않을 것입니다. 나는 일반적인 문제를 발견했지만 완전히 그 표를 놓쳤다 고 생각했다 .... arrgghh. – Michael

답변

5

토큰을 인쇄하면 토큰 스트림이 끝납니다. 당신은 당신의 파서를 호출 할 수 있도록 렉서가 토큰 스트림의 시작으로 돌아갈 것

lex.reset(); 

를 호출하여 토큰 스트림을 다시 설정해야합니다.

관련 문제